diff --git a/DEPS b/DEPS index d4da0337..94d93a2f 100644 --- a/DEPS +++ b/DEPS
@@ -107,7 +107,7 @@ # 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': 'a63cf8e80aa5eaade9bfb4c30662cec9157a4372', + 'skia_revision': '9a370396f131ff621f85c2fd3e443ab31296bc17', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -119,7 +119,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': '836674c28b1ec3ac1e28a4435594b5258cdd3a69', + 'angle_revision': '6aab06e0e5d43907861063b3a652603cdc7f986e', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling build tools # and whatever else without interference from each other. @@ -215,7 +215,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. - 'spv_tools_revision': '101c113f649bc27371370a176043e495001f732f', + 'spv_tools_revision': '3adb7977dae0faae6ab37a0726d37e0d40432f29', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -646,7 +646,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '44bef83f2be0f01d410f436c519da2987cca5747', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'ae57ced21615842cd56bff92403fe2074ed28492', 'condition': 'checkout_linux', }, @@ -666,7 +666,7 @@ }, 'src/third_party/custom_tabs_client/src': { - 'url': Var('chromium_git') + '/custom-tabs-client.git' + '@' + '4c092f007199e64798a0c6d48c4a847758392952', + 'url': Var('chromium_git') + '/custom-tabs-client.git' + '@' + '23a570c65c45ad19725b53359c2556156b9a4363', 'condition': 'checkout_android', }, @@ -1003,7 +1003,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '96e14159c92b4b47817ae224193553e6771ead0b', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '2da0d123402a3b93b5f08fdf2fa9ce3d690cdf75', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78', @@ -1155,7 +1155,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '5b6cbd789b9b91b4e46dde883c9f2ecb31eddade', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '38332cdcb1079486370bea8b5407cb3e52026598', + Var('webrtc_git') + '/src.git' + '@' + '0e4dfcbcf4fd7c8ba3ed7a98aeede4d469ace7f6', 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d', @@ -1186,7 +1186,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@0d23e71a1714b6b2b03c2261d36ff72130010eb6', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@bbe98fbac5e1e9a456593c85e13338f828c6fa15', 'condition': 'checkout_src_internal', },
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldOverrideUrlLoadingTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldOverrideUrlLoadingTest.java index e8630053..6902655 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldOverrideUrlLoadingTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldOverrideUrlLoadingTest.java
@@ -302,8 +302,11 @@ CommonResources.makeHtmlPageWithSimpleLinkTo(anchorLinkUrl + "#anchor")); if (useLoadData) { + final String html = + CommonResources.makeHtmlPageWithSimpleLinkTo("#anchor").replace("#", "%23"); + // Loading the html via a data URI requires us to encode '#' symbols as '%23'. mActivityTestRule.loadDataSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), - CommonResources.makeHtmlPageWithSimpleLinkTo("%23anchor"), "text/html", false); + html, "text/html", false); } else { mActivityTestRule.loadUrlSync( mAwContents, mContentsClient.getOnPageFinishedHelper(), anchorLinkUrl);
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsRenderTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsRenderTest.java index 936720a..fff2de80 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsRenderTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsRenderTest.java
@@ -67,9 +67,11 @@ setBackgroundColorOnUiThread(Color.YELLOW); GraphicsTestUtils.pollForBackgroundColor(mAwContents, Color.YELLOW); + final String html = "<html><head><style>body {background-color:#227788}</style></head>" + + "<body></body></html>"; + // Loading the html via a data URI requires us to encode '#' symbols as '%23'. mActivityTestRule.loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), - "data:text/html,<html><head><style>body {background-color:%23227788}</style></head>" - + "<body></body></html>"); + "data:text/html," + html.replace("#", "%23")); final int teal = 0xFF227788; GraphicsTestUtils.pollForBackgroundColor(mAwContents, teal); @@ -99,9 +101,11 @@ @SmallTest @Feature({"AndroidWebView"}) public void testForceDrawWhenInvisible() throws Throwable { + final String html = "<html><head><style>body {background-color:#227788}</style></head>" + + "<body>Hello world!</body></html>"; + // Loading the html via a data URI requires us to encode '#' symbols as '%23'. mActivityTestRule.loadUrlSync(mAwContents, mContentsClient.getOnPageFinishedHelper(), - "data:text/html,<html><head><style>body {background-color:%23227788}</style></head>" - + "<body>Hello world!</body></html>"); + "data:text/html," + html.replace("#", "%23")); Bitmap visibleBitmap = null; Bitmap invisibleBitmap = null;
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java index 63239a0..a8bdf1ac 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java
@@ -3019,10 +3019,12 @@ final String page = "<!doctype html>" + "<script>" + "window.onload = function() {" - + " document.title = CSS.supports('color', '%23AABBCCDD');" + + " document.title = CSS.supports('color', '#AABBCCDD');" + "};" + "</script>"; - mActivityTestRule.loadDataSync(awContents, onPageFinishedHelper, page, "text/html", false); + // Loading the html via a data URI requires us to encode '#' symbols as '%23'. + mActivityTestRule.loadDataSync( + awContents, onPageFinishedHelper, page.replace("#", "%23"), "text/html", false); String actualTitle = mActivityTestRule.getTitleOnUiThread(awContents); Assert.assertEquals(expectedTitle, actualTitle); }
diff --git a/android_webview/lib/aw_main_delegate.cc b/android_webview/lib/aw_main_delegate.cc index e722cc18..65c016e 100644 --- a/android_webview/lib/aw_main_delegate.cc +++ b/android_webview/lib/aw_main_delegate.cc
@@ -101,8 +101,9 @@ // WebView does not yet support screen orientation locking. cl->AppendSwitch(switches::kDisableScreenOrientationLock); - // WebView does not currently support Web Speech API (crbug.com/487255) - cl->AppendSwitch(switches::kDisableSpeechAPI); + // WebView does not currently support Web Speech Synthesis API, + // but it does support Web Speech Recognition API (crbug.com/487255). + cl->AppendSwitch(switches::kDisableSpeechSynthesisAPI); // WebView does not currently support the Permissions API (crbug.com/490120) cl->AppendSwitch(switches::kDisablePermissionsAPI);
diff --git a/android_webview/tools/system_webview_shell/test/data/webexposed/not-webview-exposed.txt b/android_webview/tools/system_webview_shell/test/data/webexposed/not-webview-exposed.txt index 1e4419a..853e086a 100644 --- a/android_webview/tools/system_webview_shell/test/data/webexposed/not-webview-exposed.txt +++ b/android_webview/tools/system_webview_shell/test/data/webexposed/not-webview-exposed.txt
@@ -1,12 +1,8 @@ -# speech api not enabled in webview, crbug.com/487255 +# speech synthesis api not enabled in webview +# but speech recognition is enabled, crbug.com/487255 interface SpeechSynthesisErrorEvent : SpeechSynthesisEvent interface SpeechSynthesisEvent : Event interface SpeechSynthesisUtterance : EventTarget -interface webkitSpeechGrammar -interface webkitSpeechGrammarList -interface webkitSpeechRecognition : EventTarget -interface webkitSpeechRecognitionError : Event -interface webkitSpeechRecognitionEvent : Event # permissions api not enabled in webview, crbug.com/490120 interface PermissionStatus : EventTarget
diff --git a/base/BUILD.gn b/base/BUILD.gn index 1d2115cd..d5f06b1 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -3330,3 +3330,13 @@ "//base", ] } + +fuzzer_test("pickle_fuzzer") { + sources = [ + "pickle_fuzzer.cc", + ] + deps = [ + "//base", + "//base/test:test_support", + ] +}
diff --git a/base/compiler_specific.h b/base/compiler_specific.h index 924d1e4f..0d6bccc8 100644 --- a/base/compiler_specific.h +++ b/base/compiler_specific.h
@@ -217,4 +217,13 @@ #define FALLTHROUGH #endif +#if defined(COMPILER_GCC) +#define PRETTY_FUNCTION __PRETTY_FUNCTION__ +#elif defined(COMPILER_MSVC) +#define PRETTY_FUNCTION __FUNCSIG__ +#else +// See https://en.cppreference.com/w/c/language/function_definition#func +#define PRETTY_FUNCTION __func__ +#endif + #endif // BASE_COMPILER_SPECIFIC_H_
diff --git a/base/pickle_fuzzer.cc b/base/pickle_fuzzer.cc new file mode 100644 index 0000000..26c5dbf --- /dev/null +++ b/base/pickle_fuzzer.cc
@@ -0,0 +1,123 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/macros.h" +#include "base/pickle.h" +#include "base/test/fuzzed_data_provider.h" + +namespace { +constexpr int kIterations = 16; +constexpr int kReadControlBytes = 32; +constexpr int kReadDataTypes = 17; +constexpr int kMaxReadLength = 1024; +constexpr int kMaxSkipBytes = 1024; +} // namespace + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + if (size < kReadControlBytes) { + return 0; + } + // Use the first kReadControlBytes bytes of the fuzzer input to control how + // the pickled data is read. + base::FuzzedDataProvider data_provider(data, kReadControlBytes); + data += kReadControlBytes; + size -= kReadControlBytes; + + base::Pickle pickle(reinterpret_cast<const char*>(data), size); + base::PickleIterator iter(pickle); + for (int i = 0; i < kIterations; i++) { + uint8_t read_type = data_provider.ConsumeUint8(); + switch (read_type % kReadDataTypes) { + case 0: { + bool result = 0; + ignore_result(iter.ReadBool(&result)); + break; + } + case 1: { + int result = 0; + ignore_result(iter.ReadInt(&result)); + break; + } + case 2: { + long result = 0; + ignore_result(iter.ReadLong(&result)); + break; + } + case 3: { + uint16_t result = 0; + ignore_result(iter.ReadUInt16(&result)); + break; + } + case 4: { + uint32_t result = 0; + ignore_result(iter.ReadUInt32(&result)); + break; + } + case 5: { + int64_t result = 0; + ignore_result(iter.ReadInt64(&result)); + break; + } + case 6: { + uint64_t result = 0; + ignore_result(iter.ReadUInt64(&result)); + break; + } + case 7: { + float result = 0; + ignore_result(iter.ReadFloat(&result)); + break; + } + case 8: { + double result = 0; + ignore_result(iter.ReadDouble(&result)); + break; + } + case 9: { + std::string result; + ignore_result(iter.ReadString(&result)); + break; + } + case 10: { + base::StringPiece result; + ignore_result(iter.ReadStringPiece(&result)); + break; + } + case 11: { + base::string16 result; + ignore_result(iter.ReadString16(&result)); + break; + } + case 12: { + base::StringPiece16 result; + ignore_result(iter.ReadStringPiece16(&result)); + break; + } + case 13: { + const char* data_result = nullptr; + int length_result = 0; + ignore_result(iter.ReadData(&data_result, &length_result)); + break; + } + case 14: { + const char* data_result = nullptr; + int read_length = data_provider.ConsumeInt32InRange(0, kMaxReadLength); + ignore_result(iter.ReadBytes(&data_result, read_length)); + break; + } + case 15: { + int result = 0; + ignore_result(iter.ReadLength(&result)); + break; + } + case 16: { + ignore_result(iter.SkipBytes( + data_provider.ConsumeInt32InRange(0, kMaxSkipBytes))); + break; + } + } + } + + return 0; +}
diff --git a/base/process/launch.h b/base/process/launch.h index 31c6ba6..2ce25464 100644 --- a/base/process/launch.h +++ b/base/process/launch.h
@@ -216,8 +216,8 @@ std::vector<FilePath> paths_to_clone; // Specifies handles which will be installed as files or directories in the - // child process' namespace. Paths installed by |paths_to_clone| will be - // overridden by these entries. + // child process' namespace. Paths installed by |paths_to_clone| or + // FDIO_SPAWN_CLONE_NAMESPACE flag will be overridden by these entries. std::vector<PathToTransfer> paths_to_transfer; #endif // defined(OS_FUCHSIA)
diff --git a/base/process/launch_fuchsia.cc b/base/process/launch_fuchsia.cc index 3fe392d..12cc877 100644 --- a/base/process/launch_fuchsia.cc +++ b/base/process/launch_fuchsia.cc
@@ -159,7 +159,10 @@ // Add actions to clone handles for any specified paths into the new process' // namespace. if (!options.paths_to_clone.empty() || !options.paths_to_transfer.empty()) { - DCHECK((options.spawn_flags & FDIO_SPAWN_CLONE_NAMESPACE) == 0); + // |paths_to_clone| doesn't make sense with FDIO_SPAWN_CLONE_NAMESPACE. + DCHECK((options.spawn_flags & FDIO_SPAWN_CLONE_NAMESPACE) == 0 || + options.paths_to_clone.empty()); + transferred_handles.reserve(transferred_handles.size() + options.paths_to_clone.size() + options.paths_to_transfer.size());
diff --git a/base/task/sequence_manager/sequence_manager_impl_unittest.cc b/base/task/sequence_manager/sequence_manager_impl_unittest.cc index 6e24cbd..75e2df9 100644 --- a/base/task/sequence_manager/sequence_manager_impl_unittest.cc +++ b/base/task/sequence_manager/sequence_manager_impl_unittest.cc
@@ -4044,6 +4044,33 @@ EXPECT_EQ(0u, manager_->GetPendingTaskCountForTesting()); } +TEST_P(SequenceManagerTest, PostDelayedTaskFromOtherThread) { + scoped_refptr<TestTaskQueue> main_tq = CreateTaskQueue(); + scoped_refptr<TaskRunner> task_runner = + main_tq->CreateTaskRunner(kTaskTypeNone); + manager_->SetAddQueueTimeToTasks(true); + + Thread thread("test thread"); + thread.StartAndWaitForTesting(); + + WaitableEvent task_posted(WaitableEvent::ResetPolicy::MANUAL, + WaitableEvent::InitialState::NOT_SIGNALED); + thread.task_runner()->PostTask( + FROM_HERE, BindOnce( + [](scoped_refptr<TaskRunner> task_runner, + WaitableEvent* task_posted) { + task_runner->PostDelayedTask( + FROM_HERE, BindOnce(&NopTask), + base::TimeDelta::FromMilliseconds(10)); + task_posted->Signal(); + }, + std::move(task_runner), &task_posted)); + task_posted.Wait(); + test_task_runner_->FastForwardUntilNoTasksRemain(); + RunLoop().RunUntilIdle(); + thread.Stop(); +} + } // namespace sequence_manager_impl_unittest } // namespace internal } // namespace sequence_manager
diff --git a/base/task/sequence_manager/task_queue_impl.cc b/base/task/sequence_manager/task_queue_impl.cc index fc8ccbc..cfcdafc 100644 --- a/base/task/sequence_manager/task_queue_impl.cc +++ b/base/task/sequence_manager/task_queue_impl.cc
@@ -261,16 +261,19 @@ // be common. This pathway is less optimal than perhaps it could be // because it causes two main thread tasks to be run. Should this // assumption prove to be false in future, we may need to revisit this. - AutoLock lock(any_thread_lock_); EnqueueOrder sequence_number = sequence_manager_->GetNextSequenceNumber(); - TimeTicks time_domain_now = any_thread().time_domain->Now(); + TimeTicks time_domain_now; + { + AutoLock lock(any_thread_lock_); + time_domain_now = any_thread().time_domain->Now(); + } TimeTicks time_domain_delayed_run_time = time_domain_now + task.delay; if (sequence_manager_->GetAddQueueTimeToTasks()) { task.queue_time = time_domain_now; } - PushOntoDelayedIncomingQueueLocked( + PushOntoDelayedIncomingQueue( Task(std::move(task), time_domain_delayed_run_time, sequence_number, EnqueueOrder(), resolution)); } @@ -290,7 +293,7 @@ TraceQueueSize(); } -void TaskQueueImpl::PushOntoDelayedIncomingQueueLocked(Task pending_task) { +void TaskQueueImpl::PushOntoDelayedIncomingQueue(Task pending_task) { sequence_manager_->WillQueueTask(&pending_task); // TODO(altimin): Add a copy method to Task to capture metadata here.
diff --git a/base/task/sequence_manager/task_queue_impl.h b/base/task/sequence_manager/task_queue_impl.h index c90d471..0886773 100644 --- a/base/task/sequence_manager/task_queue_impl.h +++ b/base/task/sequence_manager/task_queue_impl.h
@@ -339,7 +339,7 @@ // Push the task onto the |delayed_incoming_queue|. Slow path from other // threads. - void PushOntoDelayedIncomingQueueLocked(Task pending_task); + void PushOntoDelayedIncomingQueue(Task pending_task); void ScheduleDelayedWorkTask(Task pending_task);
diff --git a/base/test/launcher/test_launcher.cc b/base/test/launcher/test_launcher.cc index 166ea6d..c97a43a 100644 --- a/base/test/launcher/test_launcher.cc +++ b/base/test/launcher/test_launcher.cc
@@ -325,15 +325,9 @@ #elif defined(OS_FUCHSIA) DCHECK(!new_options.job_handle); - // Set the clone policy, deliberately omitting FDIO_SPAWN_CLONE_NAMESPACE so - // that we can install a different /data. - new_options.spawn_flags = FDIO_SPAWN_CLONE_STDIO | FDIO_SPAWN_CLONE_JOB; - new_options.paths_to_clone.push_back(base::FilePath("/config/ssl")); - new_options.paths_to_clone.push_back(base::FilePath("/dev/null")); - new_options.paths_to_clone.push_back(base::FilePath("/dev/zero")); - new_options.paths_to_clone.push_back(base::FilePath("/pkg")); - new_options.paths_to_clone.push_back(base::FilePath("/svc")); - new_options.paths_to_clone.push_back(base::FilePath("/tmp")); + // Set the clone policy. + new_options.spawn_flags = FDIO_SPAWN_CLONE_STDIO | FDIO_SPAWN_CLONE_JOB | + FDIO_SPAWN_CLONE_NAMESPACE; zx::job job_handle; zx_status_t result = zx::job::create(*GetDefaultJob(), 0, &job_handle);
diff --git a/base/trace_event/memory_infra_background_whitelist.cc b/base/trace_event/memory_infra_background_whitelist.cc index 5c818b68..a829e65 100644 --- a/base/trace_event/memory_infra_background_whitelist.cc +++ b/base/trace_event/memory_infra_background_whitelist.cc
@@ -267,6 +267,7 @@ "v8/main/contexts/native_context", "v8/main/heap/code_space", "v8/main/heap/code_stats", + "v8/main/heap/code_large_object_space", "v8/main/heap/large_object_space", "v8/main/heap/map_space", "v8/main/heap/new_large_object_space", @@ -279,6 +280,7 @@ "v8/utility/contexts/detached_context", "v8/utility/contexts/native_context", "v8/utility/heap/code_space", + "v8/utility/heap/code_large_object_space", "v8/utility/heap/large_object_space", "v8/utility/heap/map_space", "v8/utility/heap/new_large_object_space", @@ -291,6 +293,7 @@ "v8/workers/contexts/detached_context/isolate_0x?", "v8/workers/contexts/native_context/isolate_0x?", "v8/workers/heap/code_space/isolate_0x?", + "v8/workers/heap/code_large_object_space/isolate_0x?", "v8/workers/heap/large_object_space/isolate_0x?", "v8/workers/heap/map_space/isolate_0x?", "v8/workers/heap/new_large_object_space/isolate_0x?",
diff --git a/build/config/android/BUILD.gn b/build/config/android/BUILD.gn index a94c842..7761687f1 100644 --- a/build/config/android/BUILD.gn +++ b/build/config/android/BUILD.gn
@@ -198,12 +198,6 @@ ldflags = [ "-Wl,--pack-dyn-relocs=android" ] } -# Pack relocations with Android-specific relocations and RELR relocations that -# are only supported by the crazy linker and Android P+. -config("lld_pack_relocations_with_relr") { - ldflags = [ "-Wl,--pack-dyn-relocs=android+relr,--use-android-relr-tags" ] -} - # Used for instrumented build to generate the orderfile. config("default_orderfile_instrumentation") { if (use_order_profiling) {
diff --git a/build/sanitizers/OWNERS b/build/sanitizers/OWNERS index 3059b0e..e9a248c 100644 --- a/build/sanitizers/OWNERS +++ b/build/sanitizers/OWNERS
@@ -1,4 +1,10 @@ -glider@chromium.org +ochang@chromium.org eugenis@chromium.org +glider@chromium.org +inferno@chromium.org +mbarbella@chromium.org +metzman@chromium.org +mmoroz@chromium.org +rnk@chromium.org per-file tsan_suppressions.cc=* per-file lsan_suppressions.cc=*
diff --git a/build/vs_toolchain.py b/build/vs_toolchain.py index 0368497..e613b88e 100755 --- a/build/vs_toolchain.py +++ b/build/vs_toolchain.py
@@ -27,10 +27,12 @@ def SetEnvironmentAndGetRuntimeDllDirs(): """Sets up os.environ to use the depot_tools VS toolchain with gyp, and - returns the location of the VS runtime DLLs so they can be copied into + returns the location of the VC runtime DLLs so they can be copied into the output directory after gyp generation. - Return value is [x64path, x86path] or None + Return value is [x64path, x86path, 'Arm64Unused'] or None. arm64path is + generated separately because there are multiple folders for the arm64 VC + runtime. """ vs_runtime_dll_dirs = None depot_tools_win_toolchain = \ @@ -86,7 +88,9 @@ # don't build on ARM64 machines. x64_path = 'System32' if bitness == '64bit' else 'Sysnative' x64_path = os.path.join(os.path.expandvars('%windir%'), x64_path) - vs_runtime_dll_dirs = [x64_path, os.path.expandvars('%windir%/SysWOW64'), + vs_runtime_dll_dirs = [x64_path, + os.path.join(os.path.expandvars('%windir%'), + 'SysWOW64'), 'Arm64Unused'] return vs_runtime_dll_dirs @@ -184,6 +188,16 @@ def _CopyUCRTRuntime(target_dir, source_dir, target_cpu, dll_pattern, suffix): """Copy both the msvcp and vccorlib runtime DLLs, only if the target doesn't exist, but the target directory does exist.""" + if target_cpu == 'arm64': + # Windows ARM64 VCRuntime is located at {toolchain_root}/VC/Redist/MSVC/ + # {x.y.z}/[debug_nonredist/]arm64/Microsoft.VC141.CRT/. + vc_redist_root = FindVCRedistRoot() + if suffix.startswith('.'): + source_dir = os.path.join(vc_redist_root, + 'arm64', 'Microsoft.VC141.CRT') + else: + source_dir = os.path.join(vc_redist_root, 'debug_nonredist', + 'arm64', 'Microsoft.VC141.DebugCRT') for file_part in ('msvcp', 'vccorlib', 'vcruntime'): dll = dll_pattern % file_part target = os.path.join(target_dir, dll) @@ -211,6 +225,20 @@ _CopyRuntimeImpl(ucrt_dst_file, ucrt_src_file, False) # We must copy ucrtbase.dll for x64/x86, and ucrtbased.dll for all CPU types. if target_cpu != 'arm64' or not suffix.startswith('.'): + if not suffix.startswith('.'): + # ucrtbased.dll is located at {win_sdk_dir}/bin/{a.b.c.d}/{target_cpu}/ + # ucrt/. + sdk_redist_root = os.path.join(win_sdk_dir, 'bin') + sdk_bin_sub_dirs = os.listdir(sdk_redist_root) + # Select the most recent SDK if there are multiple versions installed. + sdk_bin_sub_dirs.sort(reverse=True) + for directory in sdk_bin_sub_dirs: + sdk_redist_root_version = os.path.join(sdk_redist_root, directory) + if not os.path.isdir(sdk_redist_root_version): + continue + if re.match('10\.\d+\.\d+\.\d+', directory): + source_dir = os.path.join(sdk_redist_root_version, target_cpu, 'ucrt') + break _CopyRuntimeImpl(os.path.join(target_dir, 'ucrtbase' + suffix), os.path.join(source_dir, 'ucrtbase' + suffix)) @@ -238,6 +266,29 @@ raise Exception('Unable to find the VC tools directory.') +def FindVCRedistRoot(): + """In VS2017, Redist binaries are located in + {toolchain_root}/VC/Redist/MSVC/{x.y.z}/{target_cpu}/, the {version_number} + part is likely to change in case of minor update of the toolchain so we don't + hardcode this value here (except for the major number). + + This returns the '{toolchain_root}/VC/Redist/MSVC/{x.y.z}/' path. + + This function should only be called when using VS2017. + """ + assert GetVisualStudioVersion() == '2017' + SetEnvironmentAndGetRuntimeDllDirs() + assert ('GYP_MSVS_OVERRIDE_PATH' in os.environ) + vc_redist_msvc_root = os.path.join(os.environ['GYP_MSVS_OVERRIDE_PATH'], + 'VC', 'Redist', 'MSVC') + for directory in os.listdir(vc_redist_msvc_root): + if not os.path.isdir(os.path.join(vc_redist_msvc_root, directory)): + continue + if re.match('14\.\d+\.\d+', directory): + return os.path.join(vc_redist_msvc_root, directory) + raise Exception('Unable to find the VC redist directory') + + def _CopyPGORuntime(target_dir, target_cpu): """Copy the runtime dependencies required during a PGO build. """ @@ -286,7 +337,7 @@ """Copy the VS runtime DLLs into the requested directory as needed. configuration is one of 'Debug' or 'Release'. - target_cpu is one of 'x86' or 'x64'. + target_cpu is one of 'x86', 'x64' or 'arm64'. The debug configuration gets both the debug and release DLLs; the release config only the latter. @@ -316,7 +367,7 @@ def _CopyDebugger(target_dir, target_cpu): """Copy dbghelp.dll and dbgcore.dll into the requested directory as needed. - target_cpu is one of 'x86' or 'x64'. + target_cpu is one of 'x86', 'x64' or 'arm64'. dbghelp.dll is used when Chrome needs to symbolize stacks. Copying this file from the SDK directory avoids using the system copy of dbghelp.dll which then
diff --git a/cc/raster/zero_copy_raster_buffer_provider.cc b/cc/raster/zero_copy_raster_buffer_provider.cc index c8121751..b61b669 100644 --- a/cc/raster/zero_copy_raster_buffer_provider.cc +++ b/cc/raster/zero_copy_raster_buffer_provider.cc
@@ -180,7 +180,7 @@ const gpu::Capabilities& caps = compositor_context_provider_->ContextCapabilities(); backing->texture_target = gpu::GetBufferTextureTarget( - gfx::BufferUsage::SCANOUT, BufferFormat(resource.format()), caps); + kBufferUsage, BufferFormat(resource.format()), caps); backing->overlay_candidate = true; // This RasterBufferProvider will modify the resource outside of the // GL command stream. So resources should not become available for reuse
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc index 58a3092..0019177 100644 --- a/cc/test/layer_tree_test.cc +++ b/cc/test/layer_tree_test.cc
@@ -434,7 +434,9 @@ void RecordEndOfFrameMetrics(base::TimeTicks) override {} - void UpdateLayerTreeHost() override { test_hooks_->UpdateLayerTreeHost(); } + void UpdateLayerTreeHost(bool record_main_frame_metrics) override { + test_hooks_->UpdateLayerTreeHost(); + } void ApplyViewportChanges(const ApplyViewportChangesArgs& args) override { test_hooks_->ApplyViewportChanges(args);
diff --git a/cc/test/stub_layer_tree_host_client.h b/cc/test/stub_layer_tree_host_client.h index bb4078f73..27317aa5 100644 --- a/cc/test/stub_layer_tree_host_client.h +++ b/cc/test/stub_layer_tree_host_client.h
@@ -20,7 +20,7 @@ void RecordEndOfFrameMetrics(base::TimeTicks) override {} void BeginMainFrameNotExpectedSoon() override {} void BeginMainFrameNotExpectedUntil(base::TimeTicks time) override {} - void UpdateLayerTreeHost() override {} + void UpdateLayerTreeHost(bool record_main_frame_metrics) override {} void ApplyViewportChanges(const ApplyViewportChangesArgs&) override {} void RecordWheelAndTouchScrollingCount(bool has_scrolled_by_wheel, bool has_scrolled_by_touch) override {}
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc index 6af26d03..e6a8128 100644 --- a/cc/trees/layer_tree_host.cc +++ b/cc/trees/layer_tree_host.cc
@@ -277,8 +277,8 @@ return debug_state_; } -void LayerTreeHost::RequestMainFrameUpdate() { - client_->UpdateLayerTreeHost(); +void LayerTreeHost::RequestMainFrameUpdate(bool record_main_frame_metrics) { + client_->UpdateLayerTreeHost(record_main_frame_metrics); } // This function commits the LayerTreeHost to an impl tree. When modifying @@ -650,7 +650,7 @@ DCHECK(IsSingleThreaded()); // This function is only valid when not using the scheduler. DCHECK(!settings_.single_thread_proxy_scheduler); - RequestMainFrameUpdate(); + RequestMainFrameUpdate(false /* record_main_frame_metrics */); UpdateLayers(); }
diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h index 8d73791..c403263 100644 --- a/cc/trees/layer_tree_host.h +++ b/cc/trees/layer_tree_host.h
@@ -527,7 +527,7 @@ void BeginMainFrameNotExpectedSoon(); void BeginMainFrameNotExpectedUntil(base::TimeTicks time); void AnimateLayers(base::TimeTicks monotonic_frame_begin_time); - void RequestMainFrameUpdate(); + void RequestMainFrameUpdate(bool record_main_frame_metrics); void FinishCommitOnImplThread(LayerTreeHostImpl* host_impl); void WillCommit(); void CommitComplete();
diff --git a/cc/trees/layer_tree_host_client.h b/cc/trees/layer_tree_host_client.h index d216ff5..2973940a 100644 --- a/cc/trees/layer_tree_host_client.h +++ b/cc/trees/layer_tree_host_client.h
@@ -89,8 +89,11 @@ // (Blink's notions of) style, layout, paint invalidation and compositing // state. (The "compositing state" will result in a mutated layer tree on the // LayerTreeHost via additional interface indirections which lead back to - // mutations on the LayerTreeHost.) - virtual void UpdateLayerTreeHost() = 0; + // mutations on the LayerTreeHost.) The |record_main_frame_metrics| flag + // determines whether Blink will compute metrics related to main frame update + // time. If true, the caller must ensure that RecordEndOfFrameMetrics is + // called when this method returns and the total main frame time is known. + virtual void UpdateLayerTreeHost(bool record_main_frame_metrics) = 0; // Notifies the client of viewport-related changes that occured in the // LayerTreeHost since the last commit. This typically includes things
diff --git a/cc/trees/proxy_main.cc b/cc/trees/proxy_main.cc index 2a254b1..3d7a37f 100644 --- a/cc/trees/proxy_main.cc +++ b/cc/trees/proxy_main.cc
@@ -220,7 +220,8 @@ // See LayerTreeHostClient::MainFrameUpdate for more documentation on // what this does. - layer_tree_host_->RequestMainFrameUpdate(); + layer_tree_host_->RequestMainFrameUpdate( + true /* record_main_frame_metrics */); // TODO(schenney) This will be changed to defer_commits_ when we introduce // the separation between deferring of main frame updates and deferring of
diff --git a/cc/trees/single_thread_proxy.cc b/cc/trees/single_thread_proxy.cc index 010db63..a8c17f5 100644 --- a/cc/trees/single_thread_proxy.cc +++ b/cc/trees/single_thread_proxy.cc
@@ -786,7 +786,6 @@ void SingleThreadProxy::DoBeginMainFrame( const viz::BeginFrameArgs& begin_frame_args) { - base::TimeTicks begin_main_frame_start_time = base::TimeTicks::Now(); // The impl-side scroll deltas may be manipulated directly via the // InputHandler on the UI thread and the scale deltas may change when they are // clamped on the impl thread. @@ -797,8 +796,8 @@ layer_tree_host_->WillBeginMainFrame(); layer_tree_host_->BeginMainFrame(begin_frame_args); layer_tree_host_->AnimateLayers(begin_frame_args.frame_time); - layer_tree_host_->RequestMainFrameUpdate(); - layer_tree_host_->RecordEndOfFrameMetrics(begin_main_frame_start_time); + layer_tree_host_->RequestMainFrameUpdate( + false /* record_main_frame_metrics */); } void SingleThreadProxy::DoPainting() {
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index e1389a07..c89806d 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -980,16 +980,12 @@ # ELF relocations to reduce native library size. # use_gnu_hash_style: If true, the final library will include only GNU hash # tables, rather than both SysV and GNU types (the default). -# enable_relr_relocations: Optional flag. If true, and if |enable_compressed_relocations| -# is true, then reduce the size of the native library by enabling RELR relocations. -# Note that these are only supported by the Chromium linker, and Android P+. template("chrome_common_shared_library") { shared_library(target_name) { forward_variables_from(invoker, "*", [ "enable_compressed_relocations", - "enable_relr_relocations", "export_java_symbols", "use_gnu_hash_style", ]) @@ -1023,12 +1019,7 @@ # Compress relocations if needed. if (defined(invoker.enable_compressed_relocations) && invoker.enable_compressed_relocations) { - if (defined(invoker.enable_relr_relocations) && - invoker.enable_relr_relocations) { - configs += [ "//build/config/android:lld_pack_relocations_with_relr" ] - } else { - configs += [ "//build/config/android:lld_pack_relocations" ] - } + configs += [ "//build/config/android:lld_pack_relocations" ] } if (invoker.use_gnu_hash_style && target_cpu != "mipsel" && @@ -1061,7 +1052,6 @@ } enable_compressed_relocations = chromium_linker_supported && use_lld - enable_relr_relocations = enable_compressed_relocations use_gnu_hash_style = chromium_linker_supported } }
diff --git a/chrome/android/java/AndroidManifest.xml b/chrome/android/java/AndroidManifest.xml index 01c213bc..5ef2aebb 100644 --- a/chrome/android/java/AndroidManifest.xml +++ b/chrome/android/java/AndroidManifest.xml
@@ -841,6 +841,17 @@ android:exported="false"> </service> + <activity + android:name="org.chromium.chrome.browser.browserservices.ManageTrustedWebActivityDataActivity" + android:theme="@style/FullscreenTransparentActivityTheme" + android:exported="true"> + <intent-filter> + <action android:name="android.support.customtabs.action.ACTION_MANAGE_TRUSTED_WEB_ACTIVITY_DATA" /> + <category android:name="android.intent.category.DEFAULT" /> + <data android:scheme="https"/> + </intent-filter> + </activity> + <!-- Service for decoding images in a sandboxed process. --> <service android:description="@string/decoder_description"
diff --git a/chrome/android/java/res/xml/tracing_preferences.xml b/chrome/android/java/res/xml/tracing_preferences.xml index 321eaad1..14bb735 100644 --- a/chrome/android/java/res/xml/tracing_preferences.xml +++ b/chrome/android/java/res/xml/tracing_preferences.xml
@@ -3,22 +3,19 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> -<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" android:orderingFromXml="true"> <Preference android:fragment="org.chromium.chrome.browser.preferences.developer.TracingCategoriesPreferences" android:key="default_categories" - android:title="@string/prefs_tracing_default_categories_title" - android:order="0"/> + android:title="@string/prefs_tracing_default_categories_title"/> <Preference android:fragment="org.chromium.chrome.browser.preferences.developer.TracingCategoriesPreferences" android:key="non_default_categories" - android:title="@string/prefs_tracing_non_default_categories_title" - android:order="1"/> + android:title="@string/prefs_tracing_non_default_categories_title"/> <org.chromium.chrome.browser.preferences.ChromeBaseListPreference android:key="mode" android:title="@string/prefs_tracing_mode_title" - android:persistent="false" - android:order="2"/> + android:persistent="false"/> <org.chromium.chrome.browser.preferences.ButtonPreference android:key="start_recording"/> <org.chromium.chrome.browser.preferences.TextMessagePreference
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/AppHooksModule.java b/chrome/android/java/src/org/chromium/chrome/browser/AppHooksModule.java index 66ee57d..d12e9e06 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/AppHooksModule.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/AppHooksModule.java
@@ -7,6 +7,7 @@ import org.chromium.chrome.browser.customtabs.CustomTabsConnection; import org.chromium.chrome.browser.dependency_injection.ModuleFactoryOverrides; import org.chromium.chrome.browser.externalauth.ExternalAuthUtils; +import org.chromium.chrome.browser.multiwindow.MultiWindowUtils; import dagger.Module; import dagger.Provides; @@ -29,4 +30,9 @@ public ExternalAuthUtils provideExternalAuthUtils() { return ExternalAuthUtils.getInstance(); } + + @Provides + public MultiWindowUtils provideMultiWindowUtils() { + return MultiWindowUtils.getInstance(); + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java index c746757..1f495f4b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
@@ -165,6 +165,7 @@ public static final String CCT_BACKGROUND_TAB = "CCTBackgroundTab"; public static final String CCT_MODULE = "CCTModule"; public static final String CCT_MODULE_CACHE = "CCTModuleCache"; + public static final String CCT_MODULE_CUSTOM_HEADER = "CCTModuleCustomHeader"; public static final String CCT_MODULE_POST_MESSAGE = "CCTModulePostMessage"; public static final String CCT_EXTERNAL_LINK_HANDLING = "CCTExternalLinkHandling"; public static final String CCT_PARALLEL_REQUEST = "CCTParallelRequest";
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/IntentHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/IntentHelper.java index ea56b6e0..a279f9a5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/IntentHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/IntentHelper.java
@@ -17,6 +17,7 @@ import org.chromium.components.signin.AccountManagerFacade; import java.io.File; +import java.util.List; /** * Helper for issuing intents to the android framework. @@ -40,10 +41,10 @@ static void sendEmail( String email, String subject, String body, String chooserTitle, String fileToAttach) { if (TextUtils.isEmpty(email)) { - Account[] accounts = AccountManagerFacade.get().tryGetGoogleAccounts(); - if (accounts != null && accounts.length == 1 - && Patterns.EMAIL_ADDRESS.matcher(accounts[0].name).matches()) { - email = accounts[0].name; + List<Account> accounts = AccountManagerFacade.get().tryGetGoogleAccounts(); + if (accounts != null && accounts.size() == 1 + && Patterns.EMAIL_ADDRESS.matcher(accounts.get(0).name).matches()) { + email = accounts.get(0).name; } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java index 6da07a3..ee799f1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java
@@ -283,6 +283,7 @@ if (mCurrentDetails.isEmpty() && newDetails.isEmpty()) { // No update on UI needed. nativeOnShowDetails(mUiControllerAndroid, /* canContinue= */ true); + return; } Details mergedDetails = Details.merge(mCurrentDetails, newDetails); @@ -375,9 +376,9 @@ /** Choose an account to authenticate as for making RPCs to the backend. */ private void chooseAccountAsync(Bundle extras) { AccountManagerFacade.get().tryGetGoogleAccounts(accounts -> { - if (accounts.length == 1) { + if (accounts.size() == 1) { // If there's only one account, there aren't any doubts. - onAccountChosen(accounts[0]); + onAccountChosen(accounts.get(0)); return; } Account signedIn = @@ -413,8 +414,9 @@ } } - private static Account findAccountByName(Account[] accounts, String name) { - for (Account account : accounts) { + private static Account findAccountByName(List<Account> accounts, String name) { + for (int i = 0; i < accounts.size(); i++) { + Account account = accounts.get(i); if (account.name.equals(name)) { return account; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ManageTrustedWebActivityDataActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ManageTrustedWebActivityDataActivity.java new file mode 100644 index 0000000..3995ea05 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ManageTrustedWebActivityDataActivity.java
@@ -0,0 +1,80 @@ +// 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. + +package org.chromium.chrome.browser.browserservices; + +import android.os.Bundle; +import android.support.customtabs.CustomTabsService; +import android.support.customtabs.CustomTabsSessionToken; +import android.support.customtabs.TrustedWebUtils; +import android.support.v7.app.AppCompatActivity; + +import org.chromium.base.Log; +import org.chromium.base.library_loader.LibraryLoader; +import org.chromium.chrome.browser.ChromeApplication; +import org.chromium.chrome.browser.customtabs.CustomTabsConnection; +import org.chromium.chrome.browser.preferences.PreferencesLauncher; + +/** + * Launched by {@link android.support.customtabs.TrustedWebUtils#launchBrowserSiteSettings}. + * Verifies that url provided in intent has valid Digital Asset Link with the calling application, + * and if successful, launches site-settings activity for that url. + */ +public class ManageTrustedWebActivityDataActivity extends AppCompatActivity { + + private static final String TAG = "TwaDataActivity"; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if (LibraryLoader.getInstance().isInitialized()) { + verifyOriginAndLaunchSettings(); + } else { + logNativeNotLoaded(); + } + finish(); + } + + private void verifyOriginAndLaunchSettings() { + Origin origin = new Origin(getIntent().getData()); + if (isVerifiedOrigin(origin)) { + startActivity(PreferencesLauncher.createIntentForSingleWebsitePreferences(this, + origin.toString())); + } else { + logVerificationFailed(); + } + } + + private boolean isVerifiedOrigin(Origin origin) { + CustomTabsSessionToken session = + CustomTabsSessionToken.getSessionTokenFromIntent(getIntent()); + if (session == null) { + return false; + } + + CustomTabsConnection connection = + ChromeApplication.getComponent().resolveCustomTabsConnection(); + String clientPackageName = connection.getClientPackageNameForSession(session); + if (clientPackageName == null) { + return false; + } + + // We expect that origin has been verified on the client side, and here we synchronously + // check if a result of a successful verification has been cached. + return OriginVerifier.isValidOrigin(clientPackageName, origin, + CustomTabsService.RELATION_HANDLE_ALL_URLS); + } + + private void logNativeNotLoaded() { + Log.e(TAG, "Chrome's native libraries not initialized. Please call CustomTabsClient#warmup" + + " before TrustedWebUtils#launchBrowserSiteSettings."); + } + + private void logVerificationFailed() { + Log.e(TAG, "Failed to verify " + getIntent().getData() + " while launching site settings." + + " Please use CustomTabsSession#validateRelationship to verify this origin" + + " before launching an intent with " + + TrustedWebUtils.ACTION_MANAGE_TRUSTED_WEB_ACTIVITY_DATA); + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/view/PersistentNotificationView.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/view/PersistentNotificationView.java index aea9e89..706d6aa6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/view/PersistentNotificationView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/trustedwebactivityui/view/PersistentNotificationView.java
@@ -38,7 +38,6 @@ import org.chromium.chrome.browser.notifications.NotificationBuilderFactory; import org.chromium.chrome.browser.notifications.channels.ChannelDefinitions; import org.chromium.chrome.browser.preferences.PreferencesLauncher; -import org.chromium.chrome.browser.preferences.website.SingleWebsitePreferences; import javax.inject.Inject; import javax.inject.Named; @@ -164,9 +163,8 @@ } private PendingIntent makeManageDataIntent() { - Intent settingsIntent = PreferencesLauncher.createIntentForSettingsPage(mAppContext, - SingleWebsitePreferences.class.getName(), - SingleWebsitePreferences.createFragmentArgsForSite(mOrigin.toString())); + Intent settingsIntent = PreferencesLauncher.createIntentForSingleWebsitePreferences( + mAppContext, mOrigin.toString()); return PendingIntent.getActivity(mAppContext, 0, settingsIntent, FLAG_UPDATE_CURRENT); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/childaccounts/ChildAccountService.java b/chrome/android/java/src/org/chromium/chrome/browser/childaccounts/ChildAccountService.java index 4c041687..7194d6b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/childaccounts/ChildAccountService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/childaccounts/ChildAccountService.java
@@ -41,11 +41,11 @@ ThreadUtils.assertOnUiThread(); final AccountManagerFacade accountManager = AccountManagerFacade.get(); accountManager.tryGetGoogleAccounts(accounts -> { - if (accounts.length != 1) { + if (accounts.size() != 1) { // Child accounts can't share a device. callback.onResult(ChildAccountStatus.NOT_CHILD); } else { - accountManager.checkChildAccountStatus(accounts[0], callback); + accountManager.checkChildAccountStatus(accounts.get(0), callback); } }); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java index 0faa83d..fecc6257 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java
@@ -110,7 +110,9 @@ import org.chromium.chrome.browser.webapps.WebappCustomTabTimeSpentLogger; import org.chromium.components.dom_distiller.core.DomDistillerUrlUtils; import org.chromium.content_public.browser.LoadUrlParams; +import org.chromium.content_public.browser.NavigationController; import org.chromium.content_public.browser.NavigationEntry; +import org.chromium.content_public.browser.NavigationHistory; import org.chromium.content_public.browser.WebContents; import org.chromium.ui.base.PageTransition; @@ -204,6 +206,15 @@ private ActivityTabTaskDescriptionHelper mTaskDescriptionHelper; + // Default visibility of the Toolbar prior to any header customization. + // The value is either View.VISIBLE, View.INVISIBLE, or View.GONE. + private int mDefaultToolbarVisibility; + // Default visibility of the Toolbar shadow prior to any header customization. + // The value is either View.VISIBLE, View.INVISIBLE, or View.GONE. + private int mDefaultToolbarShadowVisibility; + // Whether the progress bar is enabled prior to any header customization. + private boolean mDefaultIsProgressBarEnabled; + /** * Return true when the activity has been launched in a separate task. The default behavior is * to reuse the same task and put the activity on top of the previous one (i.e hiding it). A @@ -370,6 +381,32 @@ } } + /** + * @return The index of the previous navigation history entry managed by a dynamic module + * or -1 if there is no such entry. + */ + private boolean goToModuleManagedNavigationIndex() { + if (mModuleActivityDelegate == null && mModuleCallback == null) return false; + NavigationController navigationController = getNavigationController(); + if (navigationController == null) return false; + + NavigationHistory history = navigationController.getNavigationHistory(); + for (int i = history.getCurrentEntryIndex() - 1; i >= 0; i--) { + if (isModuleManagedUrl(history.getEntryAtIndex(i).getUrl())) { + navigationController.goToNavigationIndex(i); + return true; + } + } + + return false; + } + + @Nullable + private NavigationController getNavigationController() { + WebContents webContents = getActivityTab().getWebContents(); + return webContents == null ? null : webContents.getNavigationController(); + } + @VisibleForTesting void maybeInitialiseDynamicModulePostMessageHandler(PostMessageBackend backend) { // Only initialise the handler if the feature is enabled. @@ -423,8 +460,7 @@ public void setTopBarContentView(View view) { mTopBarDelegate.setTopBarContentView(view); - mTopBarDelegate.showTopBarIfNecessary( - isModuleManagedUrl(mIntentDataProvider.getUrlToLoad())); + maybeUpdateCctHeaderVisibility(mIntentDataProvider.getUrlToLoad()); } /** @@ -502,6 +538,9 @@ getFullscreenManager()); mBottomBarDelegate.showBottomBarIfNecessary(); mTopBarDelegate = new CustomTabTopBarDelegate(this); + mDefaultToolbarVisibility = getToolbarManager().getToolbarVisibility(); + mDefaultToolbarShadowVisibility = getToolbarManager().getToolbarShadowVisibility(); + mDefaultIsProgressBarEnabled = getToolbarManager().isProgressBarEnabled(); } @Override @@ -527,13 +566,7 @@ } private CustomTabDelegateFactory createCustomTabDelegateFactory() { - // Don't show an app install banner for the user of a Trusted Web Activity - they've already - // got an app installed! - // TODO(peconn): Look into allowing the banner again if the user leaves the Trusted origin. - boolean allowAppBanners = !mIntentDataProvider.isTrustedWebActivity(); - return new CustomTabDelegateFactory(mIntentDataProvider.shouldEnableUrlBarHiding(), - mIntentDataProvider.isOpenedByChrome(), allowAppBanners, - getComponent().resolveControlsVisibilityDelegate()); + return getComponent().resolveTabDelegateFactory(); } @Override @@ -596,6 +629,11 @@ if (mIntentDataProvider.shouldEnableEmbeddedMediaExperience()) { RecordUserAction.record("CustomTabs.CloseButtonClicked.DownloadsUI"); } + if (goToModuleManagedNavigationIndex()) { + RecordUserAction.record( + "CustomTabs.CloseButtonClicked.GoToModuleManagedUrl"); + return; + } recordClientConnectionStatus(); finishAndClose(false); } @@ -860,7 +898,7 @@ public void onUrlUpdated(Tab tab) { // Update the color on every new URL. updateColor(tab); - mTopBarDelegate.showTopBarIfNecessary(isModuleManagedUrl(tab.getUrl())); + maybeUpdateCctHeaderVisibility(tab.getUrl()); } /** @@ -1485,7 +1523,7 @@ protected void initializeToolbar() { super.initializeToolbar(); if (mIntentDataProvider.isMediaViewer()) { - getToolbarManager().disableShadow(); + getToolbarManager().setToolbarShadowVisibility(View.GONE); // The media viewer has no default menu items, so if there are also no custom items, we // should hide the menu button altogether. @@ -1611,7 +1649,27 @@ } private boolean isModuleManagedUrl(String url) { + if (!ChromeFeatureList.isEnabled(ChromeFeatureList.CCT_MODULE)) { + return false; + } Pattern urlsPattern = mIntentDataProvider.getExtraModuleManagedUrlsPattern(); return !TextUtils.isEmpty(url) && urlsPattern != null && urlsPattern.matcher(url).matches(); } + + private void maybeUpdateCctHeaderVisibility(String url) { + // TODO(crbug.com/882404) Show CCT top bar if module fails to load. + boolean isModuleManagedUrl = isModuleManagedUrl(url); + mTopBarDelegate.showTopBarIfNecessary(isModuleManagedUrl); + + if (ChromeFeatureList.isEnabled(ChromeFeatureList.CCT_MODULE) + && ChromeFeatureList.isEnabled(ChromeFeatureList.CCT_MODULE_CUSTOM_HEADER) + && mIntentDataProvider.shouldHideCctHeaderOnModuleManagedUrls()) { + getToolbarManager().setToolbarVisibility( + isModuleManagedUrl ? View.GONE : mDefaultToolbarVisibility); + getToolbarManager().setToolbarShadowVisibility( + isModuleManagedUrl ? View.GONE : mDefaultToolbarShadowVisibility); + getToolbarManager().setProgressBarEnabled( + isModuleManagedUrl ? false : mDefaultIsProgressBarEnabled); + } + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabDelegateFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabDelegateFactory.java index fc4dbdc..49d30d3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabDelegateFactory.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabDelegateFactory.java
@@ -16,6 +16,7 @@ import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.contextmenu.ChromeContextMenuPopulator; import org.chromium.chrome.browser.contextmenu.ContextMenuPopulator; +import org.chromium.chrome.browser.dependency_injection.ActivityScope; import org.chromium.chrome.browser.externalauth.ExternalAuthUtils; import org.chromium.chrome.browser.externalnav.ExternalNavigationDelegateImpl; import org.chromium.chrome.browser.externalnav.ExternalNavigationHandler; @@ -38,10 +39,13 @@ import org.chromium.content_public.common.ResourceRequestBody; import org.chromium.ui.mojom.WindowOpenDisposition; +import javax.inject.Inject; + /** * A {@link TabDelegateFactory} class to be used in all {@link Tab} owned * by a {@link CustomTabActivity}. */ +@ActivityScope public class CustomTabDelegateFactory extends TabDelegateFactory { /** * A custom external navigation delegate that forbids the intent picker from showing up. @@ -49,14 +53,17 @@ static class CustomTabNavigationDelegate extends ExternalNavigationDelegateImpl { private static final String TAG = "customtabs"; private final String mClientPackageName; + private final ExternalAuthUtils mExternalAuthUtils; private boolean mHasActivityStarted; /** * Constructs a new instance of {@link CustomTabNavigationDelegate}. */ - public CustomTabNavigationDelegate(Tab tab, String clientPackageName) { + CustomTabNavigationDelegate(Tab tab, String clientPackageName, + ExternalAuthUtils authUtils) { super(tab); mClientPackageName = clientPackageName; + mExternalAuthUtils = authUtils; } @Override @@ -130,7 +137,7 @@ @Override public boolean isIntentForTrustedCallingApp(Intent intent) { if (TextUtils.isEmpty(mClientPackageName)) return false; - if (!ExternalAuthUtils.getInstance().isGoogleSigned(mClientPackageName)) return false; + if (!mExternalAuthUtils.isGoogleSigned(mClientPackageName)) return false; return isPackageSpecializedHandler(mClientPackageName, intent); } @@ -145,11 +152,13 @@ } private static class CustomTabWebContentsDelegate extends TabWebContentsDelegateAndroid { + private final MultiWindowUtils mMultiWindowUtils; /** * See {@link TabWebContentsDelegateAndroid}. */ - public CustomTabWebContentsDelegate(Tab tab) { + public CustomTabWebContentsDelegate(Tab tab, MultiWindowUtils multiWindowUtils) { super(tab); + mMultiWindowUtils = multiWindowUtils; } @Override @@ -177,7 +186,7 @@ loadUrlParams.setIsRendererInitiated(isRendererInitiated); Class<? extends ChromeTabbedActivity> tabbedClass = - MultiWindowUtils.getInstance().getTabbedActivityForIntent( + mMultiWindowUtils.getTabbedActivityForIntent( null, ContextUtils.getApplicationContext()); AsyncTabCreationParams tabParams = new AsyncTabCreationParams(loadUrlParams, new ComponentName(ContextUtils.getApplicationContext(), tabbedClass)); @@ -194,6 +203,8 @@ private final boolean mIsOpenedByChrome; private final boolean mShouldAllowAppBanners; private final BrowserControlsVisibilityDelegate mBrowserStateVisibilityDelegate; + private final ExternalAuthUtils mExternalAuthUtils; + private final MultiWindowUtils mMultiWindowUtils; private ExternalNavigationDelegateImpl mNavigationDelegate; private ExternalNavigationHandler mNavigationHandler; @@ -205,12 +216,29 @@ * @param visibilityDelegate The delegate that handles browser control visibility associated * with browser actions (as opposed to tab state). */ - public CustomTabDelegateFactory(boolean shouldHideBrowserControls, boolean isOpenedByChrome, - boolean shouldAllowAppBanners, BrowserControlsVisibilityDelegate visibilityDelegate) { + private CustomTabDelegateFactory(boolean shouldHideBrowserControls, boolean isOpenedByChrome, + boolean shouldAllowAppBanners, BrowserControlsVisibilityDelegate visibilityDelegate, + ExternalAuthUtils authUtils, MultiWindowUtils multiWindowUtils) { mShouldHideBrowserControls = shouldHideBrowserControls; mIsOpenedByChrome = isOpenedByChrome; mShouldAllowAppBanners = shouldAllowAppBanners; mBrowserStateVisibilityDelegate = visibilityDelegate; + mExternalAuthUtils = authUtils; + mMultiWindowUtils = multiWindowUtils; + } + + @Inject + public CustomTabDelegateFactory(CustomTabIntentDataProvider intentDataProvider, + CustomTabBrowserControlsVisibilityDelegate visibilityDelegate, + ExternalAuthUtils authUtils, MultiWindowUtils multiWindowUtils) { + // Don't show an app install banner for the user of a Trusted Web Activity - they've already + // got an app installed! + this(intentDataProvider.shouldEnableUrlBarHiding(), + intentDataProvider.isOpenedByChrome(), + !intentDataProvider.isTrustedWebActivity(), + visibilityDelegate, + authUtils, + multiWindowUtils); } /** @@ -218,7 +246,7 @@ * be replaced when the hidden Tab becomes shown. */ static CustomTabDelegateFactory createDummy() { - return new CustomTabDelegateFactory(false, false, false, null); + return new CustomTabDelegateFactory(false, false, false, null, null, null); } @Override @@ -238,7 +266,7 @@ @Override public TabWebContentsDelegateAndroid createWebContentsDelegate(Tab tab) { - return new CustomTabWebContentsDelegate(tab); + return new CustomTabWebContentsDelegate(tab, mMultiWindowUtils); } @Override @@ -246,7 +274,8 @@ if (mIsOpenedByChrome) { mNavigationDelegate = new ExternalNavigationDelegateImpl(tab); } else { - mNavigationDelegate = new CustomTabNavigationDelegate(tab, tab.getAppAssociatedWith()); + mNavigationDelegate = new CustomTabNavigationDelegate(tab, tab.getAppAssociatedWith(), + mExternalAuthUtils); } mNavigationHandler = new ExternalNavigationHandler(mNavigationDelegate); return new InterceptNavigationDelegateImpl(mNavigationHandler, tab);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java index 29a9db42..0f36a1071 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java
@@ -134,13 +134,19 @@ "org.chromium.chrome.browser.customtabs.EXTRA_MODULE_MANAGED_URLS_REGEX"; /** The APK package to load the module from. */ + @VisibleForTesting /* package */ static final String EXTRA_MODULE_PACKAGE_NAME = "org.chromium.chrome.browser.customtabs.EXTRA_MODULE_PACKAGE_NAME"; /** The class name of the module entry point. */ + @VisibleForTesting /* package */ static final String EXTRA_MODULE_CLASS_NAME = "org.chromium.chrome.browser.customtabs.EXTRA_MODULE_CLASS_NAME"; + /** Extra that indicates whether to hide the CCT header on module managed URLs. */ + /* package */ static final String EXTRA_HIDE_CCT_HEADER_ON_MODULE_MANAGED_URLS = + "org.chromium.chrome.browser.customtabs.EXTRA_HIDE_CCT_HEADER_ON_MODULE_MANAGED_URLS"; + private static final int MAX_CUSTOM_MENU_ITEMS = 5; private static final int MAX_CUSTOM_TOOLBAR_ITEMS = 2; @@ -164,6 +170,9 @@ private final boolean mIsTrustedWebActivity; @Nullable private final ComponentName mModuleComponentName; + @Nullable + private final Pattern mModuleManagedUrlsPattern; + private final boolean mHideCctHeaderOnModuleManagedUrls; private final boolean mIsIncognito; @Nullable private String mUrlToLoad; @@ -182,8 +191,6 @@ private PendingIntent mRemoteViewsPendingIntent; // OnFinished listener for PendingIntents. Used for testing only. private PendingIntent.OnFinished mOnFinished; - @Nullable - private Pattern mModuleManagedUrlsPattern; /** Whether this CustomTabActivity was explicitly started by another Chrome Activity. */ private final boolean mIsOpenedByChrome; @@ -293,15 +300,17 @@ String moduleClassName = IntentUtils.safeGetStringExtra(intent, EXTRA_MODULE_CLASS_NAME); if (modulePackageName != null && moduleClassName != null) { mModuleComponentName = new ComponentName(modulePackageName, moduleClassName); + String moduleManagedUrlsRegex = + IntentUtils.safeGetStringExtra(intent, EXTRA_MODULE_MANAGED_URLS_REGEX); + mModuleManagedUrlsPattern = (moduleManagedUrlsRegex != null) + ? Pattern.compile(moduleManagedUrlsRegex) + : null; + mHideCctHeaderOnModuleManagedUrls = IntentUtils.safeGetBooleanExtra( + intent, EXTRA_HIDE_CCT_HEADER_ON_MODULE_MANAGED_URLS, false); } else { mModuleComponentName = null; - } - String moduleManagedUrlsRegex = - IntentUtils.safeGetStringExtra(intent, EXTRA_MODULE_MANAGED_URLS_REGEX); - if (moduleManagedUrlsRegex != null) { - mModuleManagedUrlsPattern = Pattern.compile(moduleManagedUrlsRegex); - } else { mModuleManagedUrlsPattern = null; + mHideCctHeaderOnModuleManagedUrls = false; } } @@ -793,4 +802,11 @@ public Intent getIntent() { return mIntent; } + + /** + * @return Whether to hide CCT header on module managed URLs. + */ + boolean shouldHideCctHeaderOnModuleManagedUrls() { + return mHideCctHeaderOnModuleManagedUrls; + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java index 5d03f665..af2f416 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java
@@ -762,7 +762,12 @@ CustomTabsSessionToken sessionToken, int relation, Origin origin, Bundle extras) { // Essential parts of the verification will depend on native code and will be run sync on UI // thread. Make sure the client has called warmup() beforehand. - if (!mWarmupHasBeenCalled.get()) return false; + if (!mWarmupHasBeenCalled.get()) { + Log.d(TAG, "Verification failed due to warmup not having been previously called."); + mClientManager.getCallbackForSession(sessionToken).onRelationshipValidationResult( + relation, Uri.parse(origin.toString()), false, null); + return false; + } return mClientManager.validateRelationship(sessionToken, relation, origin, extras); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dependency_injection/CustomTabActivityComponent.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dependency_injection/CustomTabActivityComponent.java index 860fdb38..90e9dd2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dependency_injection/CustomTabActivityComponent.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dependency_injection/CustomTabActivityComponent.java
@@ -6,7 +6,7 @@ import org.chromium.chrome.browser.browserservices.trustedwebactivityui.TrustedWebActivityCoordinator; import org.chromium.chrome.browser.contextual_suggestions.ContextualSuggestionsModule; -import org.chromium.chrome.browser.customtabs.CustomTabBrowserControlsVisibilityDelegate; +import org.chromium.chrome.browser.customtabs.CustomTabDelegateFactory; import org.chromium.chrome.browser.dependency_injection.ActivityScope; import org.chromium.chrome.browser.dependency_injection.ChromeActivityCommonsModule; import org.chromium.chrome.browser.dependency_injection.ChromeActivityComponent; @@ -22,5 +22,5 @@ @ActivityScope public interface CustomTabActivityComponent extends ChromeActivityComponent { TrustedWebActivityCoordinator resolveTrustedWebActivityCoordinator(); - CustomTabBrowserControlsVisibilityDelegate resolveControlsVisibilityDelegate(); + CustomTabDelegateFactory resolveTabDelegateFactory(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeAppComponent.java b/chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeAppComponent.java index c1a7deb..33d49105f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeAppComponent.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeAppComponent.java
@@ -7,6 +7,7 @@ import org.chromium.chrome.browser.AppHooksModule; import org.chromium.chrome.browser.contextual_suggestions.ContextualSuggestionsModule; import org.chromium.chrome.browser.contextual_suggestions.EnabledStateMonitor; +import org.chromium.chrome.browser.customtabs.CustomTabsConnection; import org.chromium.chrome.browser.customtabs.dependency_injection.CustomTabActivityComponent; import org.chromium.chrome.browser.customtabs.dependency_injection.CustomTabActivityModule; import org.chromium.chrome.browser.externalauth.ExternalAuthUtils; @@ -28,6 +29,8 @@ ContextualSuggestionsModule contextualSuggestionsModule, CustomTabActivityModule customTabActivityModule); + CustomTabsConnection resolveCustomTabsConnection(); + // Temporary getters for DI migration process. All of these getters // should eventually be replaced with constructor injection. EnabledStateMonitor resolveContextualSuggestionsEnabledStateMonitor();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java index af7feb746..19255fc 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java
@@ -60,7 +60,7 @@ // The following are initialized via initializeSharedState(). private boolean mIsAndroidEduDevice; private @ChildAccountStatus.Status int mChildAccountStatus; - private Account[] mGoogleAccounts; + private List<Account> mGoogleAccounts; private boolean mForceEduSignIn; /** @@ -113,7 +113,7 @@ } @VisibleForTesting - protected Account[] getGoogleAccounts() { + protected List<Account> getGoogleAccounts() { return AccountManagerFacade.get().tryGetGoogleAccounts(); } @@ -163,7 +163,7 @@ mGoogleAccounts = getGoogleAccounts(); // EDU devices should always have exactly 1 google account, which will be automatically // signed-in. All FRE screens are skipped in this case. - mForceEduSignIn = mIsAndroidEduDevice && mGoogleAccounts.length == 1 && !isSignedIn(); + mForceEduSignIn = mIsAndroidEduDevice && mGoogleAccounts.size() == 1 && !isSignedIn(); } void processFreEnvironmentPreNative() { @@ -195,7 +195,7 @@ /** * Called onNativeInitialized() a given flow as completed. - * @param data Resulting FRE properties bundle. + * @param freProperties Resulting FRE properties bundle. */ public void onNativeInitialized(Bundle freProperties) { // We show the sign-in page if sync is allowed, and not signed in, and this is not @@ -203,13 +203,13 @@ // - no "skip the first use hints" is set, or // - "skip the first use hints" is set, but there is at least one account. boolean offerSignInOk = isSyncAllowed() && !isSignedIn() && !mForceEduSignIn - && (!shouldSkipFirstUseHints() || mGoogleAccounts.length > 0); + && (!shouldSkipFirstUseHints() || !mGoogleAccounts.isEmpty()); freProperties.putBoolean(FirstRunActivity.SHOW_SIGNIN_PAGE, offerSignInOk); if (mForceEduSignIn || ChildAccountStatus.isChild(mChildAccountStatus)) { // If the device is an Android EDU device or has a child account, there should be // exactly account on the device. Force sign-in in to that account. freProperties.putString( - AccountFirstRunFragment.FORCE_SIGNIN_ACCOUNT_TO, mGoogleAccounts[0].name); + AccountFirstRunFragment.FORCE_SIGNIN_ACCOUNT_TO, mGoogleAccounts.get(0).name); } freProperties.putBoolean(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ForcedSigninProcessor.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ForcedSigninProcessor.java index 7a90ce4..13999e6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ForcedSigninProcessor.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/ForcedSigninProcessor.java
@@ -4,10 +4,8 @@ package org.chromium.chrome.browser.firstrun; -import android.accounts.Account; import android.content.Context; -import org.chromium.base.Callback; import org.chromium.base.Log; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.externalauth.ExternalAuthUtils; @@ -77,29 +75,26 @@ Log.d(TAG, "Sign in disallowed"); return; } - AccountManagerFacade.get().tryGetGoogleAccounts(new Callback<Account[]>() { - @Override - public void onResult(Account[] accounts) { - if (accounts.length != 1) { - Log.d(TAG, "Incorrect number of accounts (%d)", accounts.length); - return; - } - signinManager.signIn(accounts[0], null, new SigninManager.SignInCallback() { - @Override - public void onSignInComplete() { - if (onComplete != null) { - onComplete.run(); - } - } - - @Override - public void onSignInAborted() { - if (onComplete != null) { - onComplete.run(); - } - } - }); + AccountManagerFacade.get().tryGetGoogleAccounts(accounts -> { + if (accounts.size() != 1) { + Log.d(TAG, "Incorrect number of accounts (%d)", accounts.size()); + return; } + signinManager.signIn(accounts.get(0), null, new SigninManager.SignInCallback() { + @Override + public void onSignInComplete() { + if (onComplete != null) { + onComplete.run(); + } + } + + @Override + public void onSignInAborted() { + if (onComplete != null) { + onComplete.run(); + } + } + }); }); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omaha/RequestGenerator.java b/chrome/android/java/src/org/chromium/chrome/browser/omaha/RequestGenerator.java index 16ad618..9f6b9a8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omaha/RequestGenerator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omaha/RequestGenerator.java
@@ -201,7 +201,7 @@ () -> ProcessInitializationHandler.getInstance().initializePreNative()); int numAccounts = 0; try { - numAccounts = AccountManagerFacade.get().getGoogleAccounts().length; + numAccounts = AccountManagerFacade.get().getGoogleAccounts().size(); } catch (Exception e) { Log.e(TAG, "Can't get number of accounts.", e); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/PreferencesLauncher.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/PreferencesLauncher.java index 84b4c8f..aede605 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/PreferencesLauncher.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/PreferencesLauncher.java
@@ -15,6 +15,7 @@ import org.chromium.chrome.browser.AppHooks; import org.chromium.chrome.browser.preferences.autofill.AutofillPaymentMethodsFragment; import org.chromium.chrome.browser.preferences.autofill.AutofillProfilesFragment; +import org.chromium.chrome.browser.preferences.website.SingleWebsitePreferences; import org.chromium.chrome.browser.util.IntentUtils; import org.chromium.content_public.browser.WebContents; import org.chromium.ui.base.WindowAndroid; @@ -89,6 +90,15 @@ return intent; } + /** + * Creates an intent to launch single website preferences for the specified {@param url}. + */ + public static Intent createIntentForSingleWebsitePreferences(Context context, String url) { + return createIntentForSettingsPage( + context, SingleWebsitePreferences.class.getName(), + SingleWebsitePreferences.createFragmentArgsForSite(url)); + } + @CalledByNative private static void showAutofillProfileSettings(WebContents webContents) { showSettingSubpage(webContents, AutofillProfilesFragment.class);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncedAccountPreference.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncedAccountPreference.java index 2a4cc46..d7d0004 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncedAccountPreference.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncedAccountPreference.java
@@ -15,6 +15,8 @@ import org.chromium.components.signin.ChromeSigninController; import org.chromium.components.sync.AndroidSyncSettings; +import java.util.List; + /** * A preference that displays the account currently being synced and allows the user to choose a new * account to use for syncing. The values used are the account names. @@ -47,15 +49,15 @@ // signed in account } - Account[] accounts = AccountManagerFacade.get().tryGetGoogleAccounts(); - String[] accountNames = new String[accounts.length]; - String[] accountValues = new String[accounts.length]; + List<Account> accounts = AccountManagerFacade.get().tryGetGoogleAccounts(); + String[] accountNames = new String[accounts.size()]; + String[] accountValues = new String[accounts.size()]; String signedInAccountName = ChromeSigninController.get().getSignedInAccountName(); String signedInSettingsKey = ""; - for (int i = 0; i < accounts.length; ++i) { - Account account = accounts[i]; + for (int i = 0; i < accounts.size(); ++i) { + Account account = accounts.get(i); accountNames[i] = account.name; accountValues[i] = account.name; boolean isPrimaryAccount = TextUtils.equals(account.name, signedInAccountName);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountManagementFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountManagementFragment.java index 97d3c182..1a3d1a6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountManagementFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountManagementFragment.java
@@ -49,6 +49,8 @@ import org.chromium.components.signin.AccountManagerFacade; import org.chromium.components.signin.ChromeSigninController; +import java.util.List; + /** * The settings screen with information and settings related to the user's accounts. * @@ -358,8 +360,9 @@ accountsCategory.removeAll(); - Account[] accounts = AccountManagerFacade.get().tryGetGoogleAccounts(); - for (final Account account : accounts) { + List<Account> accounts = AccountManagerFacade.get().tryGetGoogleAccounts(); + for (int i = 0; i < accounts.size(); i++) { + Account account = accounts.get(i); Preference pref = new Preference(getActivity()); pref.setLayoutResource(R.layout.account_management_account_row); pref.setTitle(account.name);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountTrackerService.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountTrackerService.java index 1345ff7..83357a2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountTrackerService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountTrackerService.java
@@ -136,10 +136,11 @@ @Override public String[][] doInBackground() { Log.d(TAG, "Getting id/email mapping"); - String[][] accountIdNameMap = new String[2][accounts.length]; - for (int i = 0; i < accounts.length; ++i) { - accountIdNameMap[0][i] = accountIdProvider.getAccountId(accounts[i].name); - accountIdNameMap[1][i] = accounts[i].name; + String[][] accountIdNameMap = new String[2][accounts.size()]; + for (int i = 0; i < accounts.size(); ++i) { + accountIdNameMap[0][i] = + accountIdProvider.getAccountId(accounts.get(i).name); + accountIdNameMap[1][i] = accounts.get(i).name; } return accountIdNameMap; } @@ -222,9 +223,9 @@ return; } - String[] accountNames = new String[accounts.length]; - for (int i = 0; i < accounts.length; ++i) { - accountNames[i] = accounts[i].name; + String[] accountNames = new String[accounts.size()]; + for (int i = 0; i < accounts.size(); ++i) { + accountNames[i] = accounts.get(i).name; } if (nativeAreAccountsSeeded(accountNames)) { mSystemAccountsSeedingStatus = SystemAccountsSeedingStatus.SEEDING_DONE;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninHelper.java index 0594fe1..7131988 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninHelper.java
@@ -233,8 +233,9 @@ } private static boolean accountExists(Account account) { - Account[] accounts = AccountManagerFacade.get().tryGetGoogleAccounts(); - for (Account a : accounts) { + List<Account> accounts = AccountManagerFacade.get().tryGetGoogleAccounts(); + for (int i = 0; i < accounts.size(); i++) { + Account a = accounts.get(i); if (a.equals(account)) { return true; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPromoUtil.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPromoUtil.java index 6a14395..7e04ad0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPromoUtil.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninPromoUtil.java
@@ -21,6 +21,7 @@ import org.chromium.ui.base.WindowAndroid; import java.util.Collections; +import java.util.List; import java.util.Set; /** @@ -119,9 +120,9 @@ ProfileDataCache profileDataCache, PersonalizedSigninPromoView view, SigninPromoController.OnDismissListener listener) { DisplayableProfileData profileData = null; - Account[] accounts = AccountManagerFacade.get().tryGetGoogleAccounts(); - if (accounts.length > 0) { - String defaultAccountName = accounts[0].name; + List<Account> accounts = AccountManagerFacade.get().tryGetGoogleAccounts(); + if (accounts.size() > 0) { + String defaultAccountName = accounts.get(0).name; profileDataCache.update(Collections.singletonList(defaultAccountName)); profileData = profileDataCache.getProfileDataOrDefault(defaultAccountName); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncCustomizationFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncCustomizationFragment.java index e9d61d18..5aa4c9a4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncCustomizationFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncCustomizationFragment.java
@@ -57,6 +57,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.HashSet; +import java.util.List; import java.util.Set; /** @@ -302,8 +303,8 @@ // We remove the the SyncedAccountPreference if there's only 1 account on the device, so // it's possible for accountList to be null if (accountList != null) { - Account[] accounts = AccountManagerFacade.get().tryGetGoogleAccounts(); - if (accounts.length <= 1) { + List<Account> accounts = AccountManagerFacade.get().tryGetGoogleAccounts(); + if (accounts.size() <= 1) { getPreferenceScreen().removePreference(accountList); } else { accountList.setEnabled(mSyncSwitchPreference.isChecked());
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java index 226f721..6273339e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
@@ -113,7 +113,6 @@ import org.chromium.content_public.browser.NavigationEntry; import org.chromium.content_public.browser.WebContents; import org.chromium.ui.AsyncViewProvider; -import org.chromium.ui.UiUtils; import org.chromium.ui.base.DeviceFormFactor; import org.chromium.ui.base.PageTransition; import org.chromium.ui.widget.ViewRectProvider; @@ -217,6 +216,7 @@ private boolean mNativeLibraryReady; private boolean mTabRestoreCompleted; + private boolean mProgressBarEnabled; private AppMenuButtonHelper mAppMenuButtonHelper; @@ -1473,11 +1473,37 @@ } /** - * Prevents the shadow from being rendered. + * Gets the visibility of the Toolbar shadow. + * @return One of View.VISIBLE, View.INVISIBLE, or View.GONE. */ - public void disableShadow() { + public int getToolbarShadowVisibility() { View toolbarShadow = mControlContainer.findViewById(R.id.toolbar_shadow); - if (toolbarShadow != null) UiUtils.removeViewFromParent(toolbarShadow); + return (toolbarShadow != null) ? toolbarShadow.getVisibility() : View.GONE; + } + + /** + * Sets the visibility of the Toolbar shadow. + */ + public void setToolbarShadowVisibility(int visibility) { + View toolbarShadow = mControlContainer.findViewById(R.id.toolbar_shadow); + if (toolbarShadow != null) toolbarShadow.setVisibility(visibility); + } + + /** + * Gets the visibility of the Toolbar. + * @return One of View.VISIBLE, View.INVISIBLE, or View.GONE. + */ + public int getToolbarVisibility() { + View toolbar = mControlContainer.findViewById(R.id.toolbar); + return (toolbar != null) ? toolbar.getVisibility() : View.GONE; + } + + /** + * Sets the visibility of the Toolbar. + */ + public void setToolbarVisibility(int visibility) { + View toolbar = mControlContainer.findViewById(R.id.toolbar); + if (toolbar != null) toolbar.setVisibility(visibility); } /** @@ -1754,9 +1780,17 @@ } /** + * @return Whether the progress bar is enabled. + */ + public boolean isProgressBarEnabled() { + return mProgressBarEnabled; + } + + /** * @param enabled Whether the progress bar is enabled. */ public void setProgressBarEnabled(boolean enabled) { + mProgressBarEnabled = enabled; mToolbar.setProgressBarEnabled(enabled); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tracing/TracingController.java b/chrome/android/java/src/org/chromium/chrome/browser/tracing/TracingController.java index 0af88f1b..4072693 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tracing/TracingController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tracing/TracingController.java
@@ -5,12 +5,16 @@ package org.chromium.chrome.browser.tracing; import android.content.Context; +import android.content.Intent; +import android.net.Uri; import android.support.annotation.IntDef; import android.text.TextUtils; +import org.chromium.base.ContentUriUtils; import org.chromium.base.ContextUtils; import org.chromium.base.Log; import org.chromium.base.ObserverList; +import org.chromium.base.ThreadUtils; import org.chromium.base.VisibleForTesting; import org.chromium.base.task.AsyncTask; import org.chromium.chrome.R; @@ -65,6 +69,11 @@ private static final String TEMP_FILE_DIR = "/traces"; private static final String TEMP_FILE_PREFIX = "chrome-trace-"; private static final String TEMP_FILE_EXT = ".json.gz"; + private static final String TRACE_MIMETYPE = "application/gzip"; + + // Delete shared trace files after 1 hour. + private static final long DELETE_AFTER_SHARE_TIMEOUT_MILLIS = 60 * 60 * 1000; + private static final long UPDATE_BUFFER_USAGE_INTERVAL_MILLIS = 1000; private static TracingController sInstance; @@ -76,7 +85,10 @@ private Set<String> mKnownCategories; private File mTracingTempFile; - private TracingController() {} + private TracingController() { + // Check for old chrome-trace temp files and delete them. + new DeleteOldTempFilesTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } /** * @return the singleton instance of TracingController, creating and initializing it if needed. @@ -209,6 +221,20 @@ } setState(State.RECORDING); + updateBufferUsage(); + } + + private void updateBufferUsage() { + if (mState != State.RECORDING) return; + + mNativeController.getTraceBufferUsage(pair -> { + if (mState != State.RECORDING) return; + + TracingNotificationManager.updateTracingActiveNotification(pair.first); + + ThreadUtils.postOnUiThreadDelayed( + () -> { updateBufferUsage(); }, UPDATE_BUFFER_USAGE_INTERVAL_MILLIS); + }); } /** @@ -229,8 +255,6 @@ }); } - // TODO(eseckler): Add a way to download and/or share the trace. - /** * Discards a recorded trace and cleans up the temporary trace file. * Should only be called when in STOPPED state. @@ -241,6 +265,36 @@ setState(State.IDLE); } + /** + * Share a recorded trace via an Android share intent. + */ + public void shareTrace() { + assert mState == State.STOPPED; + + Intent shareIntent = new Intent(Intent.ACTION_SEND); + + Uri fileUri = ContentUriUtils.getContentUriFromFile(mTracingTempFile); + + shareIntent.setType(TRACE_MIMETYPE); + shareIntent.putExtra(Intent.EXTRA_STREAM, fileUri); + shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + + Context context = ContextUtils.getApplicationContext(); + context.startActivity(Intent.createChooser( + shareIntent, context.getResources().getString(R.string.tracing_share))); + + // Delete the file after an hour. This won't work if the app quits in the meantime, so we + // also check for old files when TraceController is created. + File tracingTempFile = mTracingTempFile; + ThreadUtils.postOnUiThreadDelayed(() -> { + new DeleteTempFileTask(tracingTempFile) + .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + }, DELETE_AFTER_SHARE_TIMEOUT_MILLIS); + + mTracingTempFile = null; + setState(State.IDLE); + } + private void setState(@State int state) { Log.d(TAG, "State changing to %d", state); mState = state; @@ -275,6 +329,24 @@ } } + private class DeleteOldTempFilesTask extends AsyncTask<Void> { + @Override + protected Void doInBackground() { + File cacheDir = + new File(ContextUtils.getApplicationContext().getCacheDir() + TEMP_FILE_DIR); + File[] files = cacheDir.listFiles(); + if (files != null) { + long maxTime = System.currentTimeMillis() - DELETE_AFTER_SHARE_TIMEOUT_MILLIS; + for (File f : files) { + if (f.lastModified() <= maxTime) { + f.delete(); + } + } + } + return null; + } + } + private void showErrorToast() { Context context = ContextUtils.getApplicationContext(); Toast.makeText(context, context.getString(R.string.tracing_error_toast), Toast.LENGTH_SHORT)
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tracing/TracingNotificationManager.java b/chrome/android/java/src/org/chromium/chrome/browser/tracing/TracingNotificationManager.java index 58951d34..1103b8b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tracing/TracingNotificationManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tracing/TracingNotificationManager.java
@@ -28,6 +28,7 @@ private static final int TRACING_NOTIFICATION_ID = 100; private static NotificationManagerProxy sNotificationManagerOverride; + private static ChromeNotificationBuilder sTracingActiveNotificationBuilder; // TODO(eseckler): Consider recording UMAs, see e.g. IncognitoNotificationManager. @@ -85,12 +86,11 @@ public static void showTracingActiveNotification() { Context context = ContextUtils.getApplicationContext(); String title = context.getResources().getString(R.string.tracing_active_notification_title); - // TODO(eseckler): Update the buffer usage in the notification periodically. int bufferUsagePercentage = 0; String message = context.getResources().getString( R.string.tracing_active_notification_message, bufferUsagePercentage); - ChromeNotificationBuilder builder = + sTracingActiveNotificationBuilder = createNotificationBuilder() .setContentTitle(title) .setContentText(message) @@ -99,7 +99,25 @@ ContextUtils.getApplicationContext().getResources().getString( R.string.tracing_stop), TracingNotificationService.getStopRecordingIntent(context)); - showNotification(builder.build()); + showNotification(sTracingActiveNotificationBuilder.build()); + } + + /** + * Update the tracing notification that is shown while a trace is being recorded with the + * current buffer utilization. Should only be called while the "tracing active" notification is + * shown. + * + * @param bufferUsagePercentage buffer utilization as float between 0 and 1. + */ + public static void updateTracingActiveNotification(float bufferUsagePercentage) { + assert (sTracingActiveNotificationBuilder != null); + Context context = ContextUtils.getApplicationContext(); + String message = + context.getResources().getString(R.string.tracing_active_notification_message, + Math.round(bufferUsagePercentage * 100)); + + sTracingActiveNotificationBuilder.setContentText(message); + showNotification(sTracingActiveNotificationBuilder.build()); } /** @@ -129,12 +147,15 @@ String message = context.getResources().getString(R.string.tracing_complete_notification_message); - // TODO(eseckler): Show download / share trace buttons in this notification. ChromeNotificationBuilder builder = createNotificationBuilder() .setContentTitle(title) .setContentText(message) .setOngoing(false) + .addAction(R.drawable.ic_share_white_24dp, + ContextUtils.getApplicationContext().getResources().getString( + R.string.tracing_share), + TracingNotificationService.getShareTraceIntent(context)) .setDeleteIntent(TracingNotificationService.getDiscardTraceIntent(context)); showNotification(builder.build()); } @@ -146,6 +167,7 @@ NotificationManagerProxy manager = getNotificationManager(ContextUtils.getApplicationContext()); manager.cancel(TRACING_NOTIFICATION_TAG, TRACING_NOTIFICATION_ID); + sTracingActiveNotificationBuilder = null; } private static ChromeNotificationBuilder createNotificationBuilder() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tracing/TracingNotificationService.java b/chrome/android/java/src/org/chromium/chrome/browser/tracing/TracingNotificationService.java index 92a662a..6f8c293b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tracing/TracingNotificationService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tracing/TracingNotificationService.java
@@ -18,10 +18,13 @@ private static final String TAG = "tracing_notification"; private static final String ACTION_STOP_RECORDING = - "com.google.android.apps.chrome.tracing.STOP_RECORDING"; + "org.chromium.chrome.browser.tracing.STOP_RECORDING"; private static final String ACTION_DISCARD_TRACE = - "com.google.android.apps.chrome.tracing.DISCARD_TRACE"; + "org.chromium.chrome.browser.tracing.DISCARD_TRACE"; + + private static final String ACTION_SHARE_TRACE = + "org.chromium.chrome.browser.tracing.SHARE_TRACE"; /** * Get the intent to send to stop a trace recording. @@ -48,6 +51,18 @@ } /** + * Get the intent to share a recorded trace. + * + * @param context the application's context. + * @return the intent. + */ + public static PendingIntent getShareTraceIntent(Context context) { + Intent intent = new Intent(context, TracingNotificationService.class); + intent.setAction(ACTION_SHARE_TRACE); + return PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); + } + + /** * Construct the service. Called by Android. */ public TracingNotificationService() { @@ -59,8 +74,10 @@ if (ACTION_STOP_RECORDING.equals(intent.getAction())) { ThreadUtils.runOnUiThreadBlocking( () -> { TracingController.getInstance().stopRecording(); }); - } else { - assert ACTION_DISCARD_TRACE.equals(intent.getAction()); + } else if (ACTION_SHARE_TRACE.equals(intent.getAction())) { + ThreadUtils.runOnUiThreadBlocking( + () -> { TracingController.getInstance().shareTrace(); }); + } else if (ACTION_DISCARD_TRACE.equals(intent.getAction())) { ThreadUtils.runOnUiThreadBlocking( () -> { TracingController.getInstance().discardTrace(); }); }
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd index c61fc9c9..574c684 100644 --- a/chrome/android/java/strings/android_chrome_strings.grd +++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -1459,6 +1459,9 @@ <message name="IDS_TRACING_STOP" translateable="false" desc="Caption of a button that stops recording a trace."> Stop recording </message> + <message name="IDS_TRACING_SHARE" translateable="false" desc="Caption of a button that shares a recorded trace."> + Share trace + </message> <message name="IDS_TRACING_ERROR_TOAST" translateable="false" desc="Message of a toast shown when there was an error during tracing."> Error occurred while recording Chrome trace, see log for details. </message>
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index 6094143..546e317 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -187,6 +187,7 @@ "java/src/org/chromium/chrome/browser/browserservices/ClientAppBroadcastReceiver.java", "java/src/org/chromium/chrome/browser/browserservices/ClientAppDataRegister.java", "java/src/org/chromium/chrome/browser/browserservices/DomainDataCleaner.java", + "java/src/org/chromium/chrome/browser/browserservices/ManageTrustedWebActivityDataActivity.java", "java/src/org/chromium/chrome/browser/browserservices/Origin.java", "java/src/org/chromium/chrome/browser/browserservices/OriginVerifier.java", "java/src/org/chromium/chrome/browser/browserservices/PostMessageHandler.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java index cbd6bd50e..e519db2 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java
@@ -42,6 +42,7 @@ import android.support.test.InstrumentationRegistry; import android.support.test.filters.MediumTest; import android.support.test.filters.SmallTest; +import android.support.test.uiautomator.UiDevice; import android.support.v7.content.res.AppCompatResources; import android.text.TextUtils; import android.view.Menu; @@ -77,6 +78,7 @@ import org.chromium.base.test.util.Restriction; import org.chromium.base.test.util.RetryOnFailure; import org.chromium.chrome.R; +import org.chromium.chrome.browser.AppHooksModule; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.ChromeSwitches; @@ -88,6 +90,7 @@ import org.chromium.chrome.browser.browserservices.BrowserSessionContentUtils; import org.chromium.chrome.browser.browserservices.Origin; import org.chromium.chrome.browser.browserservices.OriginVerifier; +import org.chromium.chrome.browser.dependency_injection.ModuleFactoryOverrides; import org.chromium.chrome.browser.document.ChromeLauncherActivity; import org.chromium.chrome.browser.firstrun.FirstRunStatus; import org.chromium.chrome.browser.history.BrowsingHistoryBridge; @@ -117,6 +120,7 @@ import org.chromium.chrome.test.util.browser.contextmenu.ContextMenuUtils; import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.content_public.browser.WebContentsObserver; +import org.chromium.content_public.browser.test.util.ClickUtils; import org.chromium.content_public.browser.test.util.Criteria; import org.chromium.content_public.browser.test.util.CriteriaHelper; import org.chromium.content_public.browser.test.util.DOMUtils; @@ -124,12 +128,14 @@ import org.chromium.content_public.browser.test.util.WebContentsUtils; import org.chromium.net.test.EmbeddedTestServer; import org.chromium.net.test.util.TestWebServer; +import org.chromium.ui.base.PageTransition; import org.chromium.ui.mojom.WindowOpenDisposition; import org.chromium.ui.test.util.UiRestriction; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.concurrent.ExecutionException; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; @@ -220,6 +226,9 @@ PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX); LibraryLoader.getInstance().ensureInitialized(LibraryProcessType.PROCESS_BROWSER); mWebServer = TestWebServer.start(); + + ModuleFactoryOverrides.setOverride(AppHooksModule.Factory.class, + CustomTabsDynamicModuleTestUtils.AppHooksModuleForTest::new); } @After @@ -236,6 +245,8 @@ if (handler != null) handler.hideAppMenu(); }); mWebServer.shutdown(); + + ModuleFactoryOverrides.clearOverrides(); } private CustomTabActivity getActivity() { @@ -1110,6 +1121,123 @@ } } + private void runAndWaitForActivityStopped(Runnable runnable) + throws TimeoutException, InterruptedException { + CallbackHelper cctHiddenCallback = new CallbackHelper(); + ActivityStateListener listener = (activity, newState) -> { + if (activity == mCustomTabActivityTestRule.getActivity() + && (newState == ActivityState.STOPPED || newState == ActivityState.DESTROYED)) { + cctHiddenCallback.notifyCalled(); + } + }; + ApplicationStatus.registerStateListenerForAllActivities(listener); + + runnable.run(); + cctHiddenCallback.waitForCallback("Hide cct", 0); + ApplicationStatus.unregisterActivityStateListener(listener); + } + + /** + This test executes the following workflow assuming dynamic module has been loaded succesfully: + - moduleManagedUrl1 -> nav1.1 -> nav1.2 -> modulemanagedUrl2 -> nav2.1 -> nav2.2 + - User hits the "close button", therefore goes back to modulemanagedUrl2 + - User hits the Android back button, going returning to nav1.2 + - User hits the "close button" again, going return to moduleManagedUrl1 + - User hits the Android back button thereby closes CCT. + */ + @Test + @SmallTest + @EnableFeatures(ChromeFeatureList.CCT_MODULE) + public void testCloseButtonBehaviourWithDynamicModule() + throws InterruptedException, ExecutionException, TimeoutException { + String moduleManagedUrl1 = mTestServer.getURL( + "/chrome/test/data/android/about.html"); + String moduleManagedUrl2 = mTestServer.getURL( + "/chrome/test/data/android/simple.html"); + + Intent intent = CustomTabsDynamicModuleTestUtils.makeDynamicModuleIntent(moduleManagedUrl1, + "^(" + moduleManagedUrl1 + "|" + moduleManagedUrl2 + ")$"); + + // Open CCT with moduleManagedUrl1 and navigate + // moduleManagedUrl1 -> nav1.1 - nav1.2 -> modulemanagedUrl2 -> nav2.1 -> nav2.2 + mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent); + CustomTabActivity cctActivity = mCustomTabActivityTestRule.getActivity(); + + mCustomTabActivityTestRule.loadUrlInTab(mTestPage, PageTransition.LINK, + cctActivity.getActivityTab()); + mCustomTabActivityTestRule.loadUrlInTab(mTestPage2, PageTransition.LINK, + cctActivity.getActivityTab()); + mCustomTabActivityTestRule.loadUrlInTab(moduleManagedUrl2, PageTransition.TYPED, + cctActivity.getActivityTab()); + mCustomTabActivityTestRule.loadUrlInTab(mTestPage, PageTransition.LINK, + cctActivity.getActivityTab()); + mCustomTabActivityTestRule.loadUrlInTab(mTestPage2, PageTransition.LINK, + cctActivity.getActivityTab()); + + // click the close button and wait while tab page loaded + ClickUtils.clickButton(cctActivity.findViewById(R.id.close_button)); + ChromeTabUtils.waitForTabPageLoaded(cctActivity.getActivityTab(), (String) null); + + // close button returns back to moduleManagedUrl2 + Assert.assertEquals(moduleManagedUrl2, cctActivity.getActivityTab().getUrl()); + + // press the back button and wait while tab page loaded + UiDevice mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); + mDevice.pressBack(); + ChromeTabUtils.waitForTabPageLoaded(cctActivity.getActivityTab(), (String) null); + + // the back button returns to nav1.2 + Assert.assertEquals(mTestPage2, cctActivity.getActivityTab().getUrl()); + + // click the close button and wait while tab page loaded + ClickUtils.clickButton(cctActivity.findViewById(R.id.close_button)); + ChromeTabUtils.waitForTabPageLoaded(cctActivity.getActivityTab(), (String) null); + + // close button returns back to moduleManagedUrl1 + Assert.assertEquals(moduleManagedUrl1, cctActivity.getActivityTab().getUrl()); + + // press back button and while cct is hidden + runAndWaitForActivityStopped(mDevice::pressBack); + } + + /** + This test executes the following workflow assuming dynamic module has not been loaded: + - moduleManagedUrl1 -> nav1.1 - nav1.2 -> modulemanagedUrl2 -> nav2.1 -> nav2.2 + - User hits the close button, thereby closes CCT + */ + @Test + @SmallTest + public void testCloseButtonBehaviourWithoutDynamicModule() + throws InterruptedException, ExecutionException, TimeoutException { + String moduleManagedUrl1 = mTestServer.getURL( + "/chrome/test/data/android/about.html"); + String moduleManagedUrl2 = mTestServer.getURL( + "/chrome/test/data/android/simple.html"); + + // Open CCT with moduleManagedUrl1 and navigate + // moduleManagedUrl1 -> nav1.1 - nav1.2 -> modulemanagedUrl2 -> nav2.1 -> nav2.2 + + Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent( + InstrumentationRegistry.getTargetContext(), moduleManagedUrl1); + mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent); + CustomTabActivity cctActivity = mCustomTabActivityTestRule.getActivity(); + + mCustomTabActivityTestRule.loadUrlInTab(mTestPage, PageTransition.LINK, + cctActivity.getActivityTab()); + mCustomTabActivityTestRule.loadUrlInTab(mTestPage2, PageTransition.LINK, + cctActivity.getActivityTab()); + mCustomTabActivityTestRule.loadUrlInTab(moduleManagedUrl2, PageTransition.LINK, + cctActivity.getActivityTab()); + mCustomTabActivityTestRule.loadUrlInTab(mTestPage, PageTransition.LINK, + cctActivity.getActivityTab()); + mCustomTabActivityTestRule.loadUrlInTab(mTestPage2, PageTransition.LINK, + cctActivity.getActivityTab()); + + // click close button and wait while cct is hidden + runAndWaitForActivityStopped(() -> + ClickUtils.clickButton(cctActivity.findViewById(R.id.close_button))); + } + @Test @SmallTest @RetryOnFailure @@ -1146,8 +1274,8 @@ @Test @SmallTest - @RetryOnFailure - public void testSetTopBarContentView_moduleManagedUrl_topBarVisible() throws Exception { + @EnableFeatures(ChromeFeatureList.CCT_MODULE) + public void testSetTopBarContentView_moduleNotProvided_topBarInvisible() throws Exception { Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent( InstrumentationRegistry.getTargetContext(), "https://www.google.com/search?q=london"); @@ -1162,12 +1290,146 @@ ViewGroup topBar = cctActivity.findViewById(R.id.topbar); Assert.assertNotNull(topBar); Assert.assertThat(anyView.getParent(), equalTo(topBar)); + Assert.assertEquals(View.GONE, anyView.getVisibility()); + }); + } + + @Test + @SmallTest + @DisableFeatures(ChromeFeatureList.CCT_MODULE) + public void testSetTopBarContentView_featureDisabled_topBarInvisible() throws Exception { + Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent( + InstrumentationRegistry.getTargetContext(), + "https://www.google.com/search?q=london"); + intent.putExtra(CustomTabIntentDataProvider.EXTRA_MODULE_PACKAGE_NAME, + "com.google.android.googlequicksearchbox"); + intent.putExtra(CustomTabIntentDataProvider.EXTRA_MODULE_CLASS_NAME, + "com.google.android.googlequicksearchbox.SearchActivity"); + intent.putExtra(CustomTabIntentDataProvider.EXTRA_MODULE_MANAGED_URLS_REGEX, + "^https://www.google.com/search.*"); + mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent); + + ThreadUtils.runOnUiThread(() -> { + CustomTabActivity cctActivity = mCustomTabActivityTestRule.getActivity(); + View anyView = new View(cctActivity); + cctActivity.setTopBarContentView(anyView); + ViewGroup topBar = cctActivity.findViewById(R.id.topbar); + Assert.assertNotNull(topBar); + Assert.assertThat(anyView.getParent(), equalTo(topBar)); + Assert.assertEquals(View.GONE, anyView.getVisibility()); + }); + } + + @Test + @SmallTest + @EnableFeatures(ChromeFeatureList.CCT_MODULE) + public void testSetTopBarContentView_withModuleAndManagedUrls_topBarVisible() throws Exception { + Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent( + InstrumentationRegistry.getTargetContext(), + "https://www.google.com/search?q=london"); + intent.putExtra(CustomTabIntentDataProvider.EXTRA_MODULE_PACKAGE_NAME, + "com.google.android.googlequicksearchbox"); + intent.putExtra(CustomTabIntentDataProvider.EXTRA_MODULE_CLASS_NAME, + "com.google.android.googlequicksearchbox.SearchActivity"); + intent.putExtra(CustomTabIntentDataProvider.EXTRA_MODULE_MANAGED_URLS_REGEX, + "^https://www.google.com/search.*"); + mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent); + + ThreadUtils.runOnUiThread(() -> { + CustomTabActivity cctActivity = mCustomTabActivityTestRule.getActivity(); + View anyView = new View(cctActivity); + cctActivity.setTopBarContentView(anyView); + ViewGroup topBar = cctActivity.findViewById(R.id.topbar); + Assert.assertNotNull(topBar); + Assert.assertThat(anyView.getParent(), equalTo(topBar)); Assert.assertEquals(View.VISIBLE, anyView.getVisibility()); }); } @Test @SmallTest + @EnableFeatures({ChromeFeatureList.CCT_MODULE, ChromeFeatureList.CCT_MODULE_CUSTOM_HEADER}) + public void testSetTopBarContentView_moduleNotProvided_cctHeaderVisible() throws Exception { + Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent( + InstrumentationRegistry.getTargetContext(), + "https://www.google.com/search?q=london"); + intent.putExtra(CustomTabIntentDataProvider.EXTRA_MODULE_MANAGED_URLS_REGEX, + "^https://www.google.com/search.*"); + intent.putExtra( + CustomTabIntentDataProvider.EXTRA_HIDE_CCT_HEADER_ON_MODULE_MANAGED_URLS, true); + mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent); + + ThreadUtils.runOnUiThread(() -> { + CustomTabActivity cctActivity = mCustomTabActivityTestRule.getActivity(); + cctActivity.setTopBarContentView(new View(cctActivity)); + View toolbarView = cctActivity.findViewById(R.id.toolbar); + Assert.assertTrue( + "A custom tab toolbar is never shown", toolbarView instanceof CustomTabToolbar); + CustomTabToolbar toolbar = (CustomTabToolbar) toolbarView; + Assert.assertEquals(View.VISIBLE, toolbar.getVisibility()); + }); + } + + @Test + @SmallTest + @DisableFeatures(ChromeFeatureList.CCT_MODULE_CUSTOM_HEADER) + public void testSetTopBarContentView_featureDisabled_cctHeaderVisible() throws Exception { + Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent( + InstrumentationRegistry.getTargetContext(), + "https://www.google.com/search?q=london"); + intent.putExtra(CustomTabIntentDataProvider.EXTRA_MODULE_PACKAGE_NAME, + "com.google.android.googlequicksearchbox"); + intent.putExtra(CustomTabIntentDataProvider.EXTRA_MODULE_CLASS_NAME, + "com.google.android.googlequicksearchbox.SearchActivity"); + intent.putExtra(CustomTabIntentDataProvider.EXTRA_MODULE_MANAGED_URLS_REGEX, + "^https://www.google.com/search.*"); + intent.putExtra( + CustomTabIntentDataProvider.EXTRA_HIDE_CCT_HEADER_ON_MODULE_MANAGED_URLS, true); + mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent); + + ThreadUtils.runOnUiThread(() -> { + CustomTabActivity cctActivity = mCustomTabActivityTestRule.getActivity(); + cctActivity.setTopBarContentView(new View(cctActivity)); + View toolbarView = cctActivity.findViewById(R.id.toolbar); + Assert.assertTrue( + "A custom tab toolbar is never shown", toolbarView instanceof CustomTabToolbar); + CustomTabToolbar toolbar = (CustomTabToolbar) toolbarView; + Assert.assertEquals(View.VISIBLE, toolbar.getVisibility()); + }); + } + + @Test + @SmallTest + @EnableFeatures({ChromeFeatureList.CCT_MODULE, ChromeFeatureList.CCT_MODULE_CUSTOM_HEADER}) + public void testSetTopBarContentView_withModuleAndExtras_cctHeaderHidden() throws Exception { + Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent( + InstrumentationRegistry.getTargetContext(), + "https://www.google.com/search?q=london"); + intent.putExtra(CustomTabIntentDataProvider.EXTRA_MODULE_PACKAGE_NAME, + "com.google.android.googlequicksearchbox"); + intent.putExtra(CustomTabIntentDataProvider.EXTRA_MODULE_CLASS_NAME, + "com.google.android.googlequicksearchbox.SearchActivity"); + intent.putExtra(CustomTabIntentDataProvider.EXTRA_MODULE_MANAGED_URLS_REGEX, + "^https://www.google.com/search.*"); + intent.putExtra( + CustomTabIntentDataProvider.EXTRA_HIDE_CCT_HEADER_ON_MODULE_MANAGED_URLS, true); + mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent); + + ThreadUtils.runOnUiThread(() -> { + CustomTabActivity cctActivity = mCustomTabActivityTestRule.getActivity(); + cctActivity.setTopBarContentView(new View(cctActivity)); + ViewGroup toolbarContainerView = cctActivity.findViewById(R.id.toolbar_container); + for (int index = 0; index < toolbarContainerView.getChildCount(); index++) { + View childView = toolbarContainerView.getChildAt(index); + if (childView.getId() != R.id.topbar) { + Assert.assertEquals(View.GONE, childView.getVisibility()); + } + } + }); + } + + @Test + @SmallTest @Feature({"UiCatalogue"}) public void testRemoteViews() throws Exception { Intent intent = createMinimalCustomTabIntent();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/video/FullscreenVideoTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/video/FullscreenVideoTest.java index 65e2651..d4e707b 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/video/FullscreenVideoTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/video/FullscreenVideoTest.java
@@ -102,6 +102,7 @@ */ @Test @MediumTest + @FlakyTest(message = "crbug.com/906840") public void testFullscreenDimensions() throws InterruptedException, TimeoutException { String url = mTestServerRule.getServer().getURL("/content/test/data/media/video-player.html");
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencerTest.java index df2927d..36bc8fc 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencerTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencerTest.java
@@ -26,6 +26,9 @@ import org.chromium.base.test.util.Feature; import org.chromium.components.signin.ChildAccountStatus; +import java.util.Collections; +import java.util.List; + /** * Tests FirstRunFlowSequencer which contains the core logic of what should be shown during the * first run. @@ -49,7 +52,7 @@ public boolean isFirstRunFlowComplete; public boolean isSignedIn; public boolean isSyncAllowed; - public Account[] googleAccounts; + public List<Account> googleAccounts; public boolean hasAnyUserSeenToS; public boolean shouldSkipFirstUseHints; public boolean isFirstRunEulaAccepted; @@ -83,7 +86,7 @@ } @Override - public Account[] getGoogleAccounts() { + public List<Account> getGoogleAccounts() { return googleAccounts; } @@ -140,12 +143,11 @@ @Test @Feature({"FirstRun"}) public void testFirstRunComplete() { - Account[] accounts = new Account[1]; - accounts[0] = new Account(DEFAULT_ACCOUNT, GOOGLE_ACCOUNT_TYPE); mSequencer.isFirstRunFlowComplete = true; mSequencer.isSignedIn = false; mSequencer.isSyncAllowed = true; - mSequencer.googleAccounts = accounts; + mSequencer.googleAccounts = + Collections.singletonList(new Account(DEFAULT_ACCOUNT, GOOGLE_ACCOUNT_TYPE)); mSequencer.hasAnyUserSeenToS = true; mSequencer.shouldSkipFirstUseHints = false; mSequencer.isFirstRunEulaAccepted = true; @@ -164,7 +166,7 @@ mSequencer.isFirstRunFlowComplete = false; mSequencer.isSignedIn = false; mSequencer.isSyncAllowed = true; - mSequencer.googleAccounts = new Account[0]; + mSequencer.googleAccounts = Collections.emptyList(); mSequencer.hasAnyUserSeenToS = false; mSequencer.shouldSkipFirstUseHints = false; mSequencer.shouldShowDataReductionPage = false; @@ -189,12 +191,11 @@ @Test @Feature({"FirstRun"}) public void testStandardFlowOneChildAccount() { - Account[] accounts = new Account[1]; - accounts[0] = new Account(DEFAULT_ACCOUNT, GOOGLE_ACCOUNT_TYPE); mSequencer.isFirstRunFlowComplete = false; mSequencer.isSignedIn = false; mSequencer.isSyncAllowed = true; - mSequencer.googleAccounts = accounts; + mSequencer.googleAccounts = + Collections.singletonList(new Account(DEFAULT_ACCOUNT, GOOGLE_ACCOUNT_TYPE)); mSequencer.hasAnyUserSeenToS = false; mSequencer.shouldSkipFirstUseHints = false; mSequencer.shouldShowDataReductionPage = false; @@ -224,7 +225,7 @@ mSequencer.isFirstRunFlowComplete = false; mSequencer.isSignedIn = false; mSequencer.isSyncAllowed = true; - mSequencer.googleAccounts = new Account[0]; + mSequencer.googleAccounts = Collections.emptyList(); mSequencer.hasAnyUserSeenToS = false; mSequencer.shouldSkipFirstUseHints = false; mSequencer.shouldShowDataReductionPage = true; @@ -253,7 +254,7 @@ mSequencer.isFirstRunFlowComplete = false; mSequencer.isSignedIn = false; mSequencer.isSyncAllowed = true; - mSequencer.googleAccounts = new Account[0]; + mSequencer.googleAccounts = Collections.emptyList(); mSequencer.hasAnyUserSeenToS = false; mSequencer.shouldSkipFirstUseHints = false; mSequencer.shouldShowDataReductionPage = true;
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 6ad90bc..babe228 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -2942,10 +2942,6 @@ FEATURE_VALUE_TYPE( offline_pages::kOfflinePagesSvelteConcurrentLoadingFeature)}, #endif // !defined(OS_ANDROID) - {"cross-process-guests", - flag_descriptions::kCrossProcessGuestViewIsolationName, - flag_descriptions::kCrossProcessGuestViewIsolationDescription, kOsDesktop, - FEATURE_VALUE_TYPE(features::kGuestViewCrossProcessFrames)}, #if defined(OS_ANDROID) {"video-fullscreen-orientation-lock", flag_descriptions::kVideoFullscreenOrientationLockName, @@ -4102,6 +4098,9 @@ FEATURE_WITH_PARAMS_VALUE_TYPE(chrome::android::kCCTModuleCache, kCCTModuleCacheVariations, "CCTModule")}, + {"cct-module-custom-header", flag_descriptions::kCCTModuleCustomHeaderName, + flag_descriptions::kCCTModuleCustomHeaderDescription, kOsAndroid, + FEATURE_VALUE_TYPE(chrome::android::kCCTModuleCustomHeader)}, {"cct-module-post-message", flag_descriptions::kCCTModulePostMessageName, flag_descriptions::kCCTModulePostMessageDescription, kOsAndroid, FEATURE_VALUE_TYPE(chrome::android::kCCTModulePostMessage)}, @@ -4438,6 +4437,9 @@ flag_descriptions::kAshEnablePipRoundedCornersDescription, kOsCrOS, FEATURE_VALUE_TYPE(ash::features::kPipRoundedCorners)}, #endif // defined(OS_CHROMEOS) + {"google-password-manager", flag_descriptions::kGooglePasswordManagerName, + flag_descriptions::kGooglePasswordManagerDescription, kOsAll, + FEATURE_VALUE_TYPE(password_manager::features::kGooglePasswordManager)}, }; class FlagsStateSingleton {
diff --git a/chrome/browser/android/autofill_assistant/ui_controller_android.cc b/chrome/browser/android/autofill_assistant/ui_controller_android.cc index 89716ac..95e4c05c 100644 --- a/chrome/browser/android/autofill_assistant/ui_controller_android.cc +++ b/chrome/browser/android/autofill_assistant/ui_controller_android.cc
@@ -226,11 +226,21 @@ payment_info->card = std::make_unique<autofill::CreditCard>(); autofill::PersonalDataManagerAndroid::PopulateNativeCreditCardFromJava( jcard, env, payment_info->card.get()); + + auto guid = payment_info->card->billing_address_id(); + if (!guid.empty()) { + autofill::AutofillProfile* profile = + GetPersonalDataManager()->GetProfileByGUID(guid); + if (profile != nullptr) + payment_info->billing_address = + std::make_unique<autofill::AutofillProfile>(*profile); + } } if (jaddress != nullptr) { - payment_info->address = std::make_unique<autofill::AutofillProfile>(); + payment_info->shipping_address = + std::make_unique<autofill::AutofillProfile>(); autofill::PersonalDataManagerAndroid::PopulateNativeProfileFromJava( - jaddress, env, payment_info->address.get()); + jaddress, env, payment_info->shipping_address.get()); } if (jpayer_name != nullptr) { base::android::ConvertJavaStringToUTF8(env, jpayer_name,
diff --git a/chrome/browser/android/chrome_feature_list.cc b/chrome/browser/android/chrome_feature_list.cc index 6b4e3bd..d1f71d8d 100644 --- a/chrome/browser/android/chrome_feature_list.cc +++ b/chrome/browser/android/chrome_feature_list.cc
@@ -86,6 +86,7 @@ &kCCTExternalLinkHandling, &kCCTModule, &kCCTModuleCache, + &kCCTModuleCustomHeader, &kCCTModulePostMessage, &kCCTParallelRequest, &kCCTPostMessageAPI, @@ -230,6 +231,9 @@ const base::Feature kCCTModuleCache{"CCTModuleCache", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kCCTModuleCustomHeader{"CCTModuleCustomHeader", + base::FEATURE_DISABLED_BY_DEFAULT}; + const base::Feature kCCTModulePostMessage{"CCTModulePostMessage", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/chrome/browser/android/chrome_feature_list.h b/chrome/browser/android/chrome_feature_list.h index beee5e1..d7340c2 100644 --- a/chrome/browser/android/chrome_feature_list.h +++ b/chrome/browser/android/chrome_feature_list.h
@@ -25,6 +25,7 @@ extern const base::Feature kCCTExternalLinkHandling; extern const base::Feature kCCTModule; extern const base::Feature kCCTModuleCache; +extern const base::Feature kCCTModuleCustomHeader; extern const base::Feature kCCTModulePostMessage; extern const base::Feature kCCTParallelRequest; extern const base::Feature kCCTPostMessageAPI;
diff --git a/chrome/browser/chromeos/login/signin/oauth2_browsertest.cc b/chrome/browser/chromeos/login/signin/oauth2_browsertest.cc index f118e12..47fb7e4 100644 --- a/chrome/browser/chromeos/login/signin/oauth2_browsertest.cc +++ b/chrome/browser/chromeos/login/signin/oauth2_browsertest.cc
@@ -28,7 +28,7 @@ #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/signin/account_tracker_service_factory.h" #include "chrome/browser/signin/identity_manager_factory.h" -#include "chrome/browser/signin/signin_error_controller_factory.h" +#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_tabstrip.h" #include "chrome/browser/ui/javascript_dialogs/javascript_dialog_tab_helper.h" @@ -43,8 +43,6 @@ #include "components/browser_sync/browser_sync_switches.h" #include "components/prefs/pref_service.h" #include "components/signin/core/browser/account_tracker_service.h" -#include "components/signin/core/browser/fake_auth_status_provider.h" -#include "components/signin/core/browser/signin_error_controller.h" #include "components/user_manager/user.h" #include "components/user_manager/user_manager.h" #include "content/public/browser/browser_task_traits.h" @@ -54,6 +52,7 @@ #include "extensions/browser/process_manager.h" #include "extensions/test/extension_test_message_listener.h" #include "extensions/test/result_catcher.h" +#include "google_apis/gaia/oauth2_token_service_delegate.h" #include "net/cookies/canonical_cookie.h" #include "net/cookies/cookie_store.h" #include "net/test/embedded_test_server/http_request.h" @@ -688,9 +687,8 @@ /*is_under_advanced_protectionis_true=*/false); } -// Tests that an auth error reported by SigninErrorController marks invalid auth -// token status despite OAuth2LoginManager thinks merge session is done -// successfully +// Tests that an auth error marks invalid auth token status despite +// OAuth2LoginManager thinks merge session is done successfully IN_PROC_BROWSER_TEST_F(OAuth2Test, SetInvalidTokenStatus) { RequestDeferrer list_accounts_request_deferer; AddRequestDeferer("/ListAccounts", &list_accounts_request_deferer); @@ -724,12 +722,8 @@ ASSERT_NE(OAuth2LoginManager::SESSION_RESTORE_DONE, login_manager->state()); // Generate an auth error. - SigninErrorController* const error_controller = - SigninErrorControllerFactory::GetForProfile(profile()); - FakeAuthStatusProvider auth_provider(error_controller); - auth_provider.SetAuthError( - kTestEmail, GoogleServiceAuthError( - GoogleServiceAuthError::State::INVALID_GAIA_CREDENTIALS)); + ProfileOAuth2TokenServiceFactory::GetForProfile(profile())->UpdateCredentials( + kTestEmail, OAuth2TokenServiceDelegate::kInvalidRefreshToken); // Let go /ListAccounts request. list_accounts_request_deferer.UnblockRequest();
diff --git a/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc b/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc index 200db3f..d8670c5 100644 --- a/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc +++ b/chrome/browser/chromeos/policy/device_policy_decoder_chromeos.cc
@@ -1076,6 +1076,25 @@ nullptr); } } + + if (policy.has_plugin_vm_allowed()) { + const em::PluginVmAllowedProto& container(policy.plugin_vm_allowed()); + if (container.has_plugin_vm_allowed()) { + policies->Set( + key::kPluginVmAllowed, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, + POLICY_SOURCE_CLOUD, + std::make_unique<base::Value>(container.plugin_vm_allowed()), + nullptr); + } + } + + if (policy.has_plugin_vm_image()) { + const em::PluginVmImageProto& container(policy.plugin_vm_image()); + if (container.has_plugin_vm_image()) { + SetJsonDevicePolicy(key::kPluginVmImage, container.plugin_vm_image(), + policies); + } + } } } // namespace
diff --git a/chrome/browser/chromeos/policy/variations_service_policy_browsertest.cc b/chrome/browser/chromeos/policy/variations_service_policy_browsertest.cc index 0a58ba9d..c306c130 100644 --- a/chrome/browser/chromeos/policy/variations_service_policy_browsertest.cc +++ b/chrome/browser/chromeos/policy/variations_service_policy_browsertest.cc
@@ -47,7 +47,6 @@ // Device policy has updated the cros settings. const GURL url = g_browser_process->variations_service()->GetVariationsServerURL( - g_browser_process->local_state(), std::string(), variations::VariationsService::HttpOptions::USE_HTTPS); EXPECT_TRUE(base::StartsWith(url.spec(), default_variations_url, base::CompareCase::SENSITIVE));
diff --git a/chrome/browser/extensions/api/identity/identity_api.cc b/chrome/browser/extensions/api/identity/identity_api.cc index 4d06926..6329e42 100644 --- a/chrome/browser/extensions/api/identity/identity_api.cc +++ b/chrome/browser/extensions/api/identity/identity_api.cc
@@ -28,10 +28,9 @@ #include "chrome/browser/signin/account_consistency_mode_manager.h" #include "chrome/browser/signin/account_tracker_service_factory.h" #include "chrome/browser/signin/chrome_signin_client_factory.h" -#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" +#include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/common/extensions/api/identity.h" #include "chrome/common/url_constants.h" -#include "components/signin/core/browser/profile_oauth2_token_service.h" #include "extensions/browser/extension_function_dispatcher.h" #include "extensions/common/extension.h" #include "extensions/common/extension_l10n_util.h" @@ -104,7 +103,7 @@ IdentityAPI::IdentityAPI(content::BrowserContext* context) : profile_(Profile::FromBrowserContext(context)) { AccountTrackerServiceFactory::GetForProfile(profile_)->AddObserver(this); - ProfileOAuth2TokenServiceFactory::GetForProfile(profile_)->AddObserver(this); + IdentityManagerFactory::GetForProfile(profile_)->AddObserver(this); } IdentityAPI::~IdentityAPI() {} @@ -147,8 +146,7 @@ void IdentityAPI::Shutdown() { on_shutdown_callback_list_.Notify(); AccountTrackerServiceFactory::GetForProfile(profile_)->RemoveObserver(this); - ProfileOAuth2TokenServiceFactory::GetForProfile(profile_)->RemoveObserver( - this); + IdentityManagerFactory::GetForProfile(profile_)->RemoveObserver(this); } static base::LazyInstance<BrowserContextKeyedAPIFactory<IdentityAPI>>:: @@ -172,11 +170,9 @@ #endif } -void IdentityAPI::OnRefreshTokenAvailable(const std::string& account_id) { - const AccountInfo& account_info = - AccountTrackerServiceFactory::GetForProfile(profile_)->GetAccountInfo( - account_id); - +void IdentityAPI::OnRefreshTokenUpdatedForAccount( + const AccountInfo& account_info, + bool is_valid) { // Refresh tokens are sometimes made available in contexts where // AccountTrackerService is not tracking the account in question (one example // is SupervisedUserService::InitSync()). Bail out in these cases. @@ -214,7 +210,7 @@ DependsOn(ExtensionsBrowserClient::Get()->GetExtensionSystemFactory()); DependsOn(ChromeSigninClientFactory::GetInstance()); - DependsOn(ProfileOAuth2TokenServiceFactory::GetInstance()); + DependsOn(IdentityManagerFactory::GetInstance()); } } // namespace extensions
diff --git a/chrome/browser/extensions/api/identity/identity_api.h b/chrome/browser/extensions/api/identity/identity_api.h index 964c7b01..5cde6ca 100644 --- a/chrome/browser/extensions/api/identity/identity_api.h +++ b/chrome/browser/extensions/api/identity/identity_api.h
@@ -35,6 +35,7 @@ #include "extensions/browser/event_router.h" #include "google_apis/gaia/oauth2_mint_token_flow.h" #include "google_apis/gaia/oauth2_token_service.h" +#include "services/identity/public/cpp/identity_manager.h" namespace content { class BrowserContext; @@ -82,7 +83,7 @@ class IdentityAPI : public BrowserContextKeyedAPI, public AccountTrackerService::Observer, - public OAuth2TokenService::Observer { + public identity::IdentityManager::Observer { public: typedef std::map<ExtensionTokenKey, IdentityTokenCacheValue> CachedTokens; @@ -131,8 +132,9 @@ static const char* service_name() { return "IdentityAPI"; } static const bool kServiceIsNULLWhileTesting = true; - // OAuth2TokenService::Observer: - void OnRefreshTokenAvailable(const std::string& account_id) override; + // identity::IdentityManager::Observer: + void OnRefreshTokenUpdatedForAccount(const AccountInfo& account_info, + bool is_valid) override; // AccountTrackerService::Observer: // NOTE: This class listens for signout events via this callback (which itself
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index df5e213..24ff508 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -347,6 +347,11 @@ "expiry_milestone": 76 }, { + "name": "cct-module-custom-header", + "owners": [ "mvanouwerkerk" ], + "expiry_milestone": 76 + }, + { "name": "cct-module-post-message", "owners": [ "mvanouwerkerk" ], "expiry_milestone": 76 @@ -442,11 +447,6 @@ "expiry_milestone": 76 }, { - "name": "cross-process-guests", - // "owners": [ "your-team" ], - "expiry_milestone": 76 - }, - { "name": "crostini-usb-support", // "owners": [ "your-team" ], "expiry_milestone": 76 @@ -1133,7 +1133,7 @@ }, { "name": "enable-experimental-productivity-features", - // "owners": [ "your-team" ], + "owners": [ "feature-control@chromium.org" ], "expiry_milestone": 76 }, { @@ -2229,6 +2229,11 @@ "expiry_milestone": 76 }, { + "name": "google-password-manager", + "owners": ["ioanap", "jdoerrie"], + "expiry_milestone": 76 + }, + { "name": "grant-notifications-to-dse", // "owners": [ "your-team" ], "expiry_milestone": 76
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 1a75517e..a33078b 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -252,12 +252,6 @@ const char kCreditCardAssistDescription[] = "Enable assisted credit card filling on certain sites."; -const char kCrossProcessGuestViewIsolationName[] = - "Cross process frames for guests"; -const char kCrossProcessGuestViewIsolationDescription[] = - "Highly experimental where guests such as <webview> are implemented on " - "the out-of-process iframe infrastructure."; - const char kDataSaverServerPreviewsName[] = "Data Saver Server Previews"; const char kDataSaverServerPreviewsDescription[] = "Allow the Data Reduction Proxy to serve previews."; @@ -1056,6 +1050,10 @@ "Use GPU to rasterize web content. Requires impl-side painting."; const char kForceGpuRasterization[] = "Force-enabled for all layers"; +const char kGooglePasswordManagerName[] = "Google Password Manager UI"; +const char kGooglePasswordManagerDescription[] = + "Enables access to the Google Password Manager UI from Chrome."; + const char kGoogleProfileInfoName[] = "Google profile name and icon"; const char kGoogleProfileInfoDescription[] = "Enables using Google information to populate the profile name and icon in " @@ -2239,6 +2237,12 @@ "Enables a cache for dynamically loaded modules in Chrome Custom Tabs. " "Under mild memory pressure the cache may be retained for some time"; +const char kCCTModuleCustomHeaderName[] = + "Chrome Custom Tabs Module Custom Header"; +const char kCCTModuleCustomHeaderDescription[] = + "Enables header customization by dynamically loaded modules in " + "Chrome Custom Tabs."; + const char kCCTModulePostMessageName[] = "Chrome Custom Tabs Module postMessage API"; const char kCCTModulePostMessageDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 50b87180..7cb7562 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -182,9 +182,6 @@ extern const char kCreditCardAssistName[]; extern const char kCreditCardAssistDescription[]; -extern const char kCrossProcessGuestViewIsolationName[]; -extern const char kCrossProcessGuestViewIsolationDescription[]; - extern const char kDataSaverServerPreviewsName[]; extern const char kDataSaverServerPreviewsDescription[]; @@ -640,6 +637,9 @@ extern const char kGpuRasterizationDescription[]; extern const char kForceGpuRasterization[]; +extern const char kGooglePasswordManagerName[]; +extern const char kGooglePasswordManagerDescription[]; + extern const char kGoogleProfileInfoName[]; extern const char kGoogleProfileInfoDescription[]; @@ -1343,6 +1343,9 @@ extern const char kCCTModuleCacheName[]; extern const char kCCTModuleCacheDescription[]; +extern const char kCCTModuleCustomHeaderName[]; +extern const char kCCTModuleCustomHeaderDescription[]; + extern const char kCCTModulePostMessageName[]; extern const char kCCTModulePostMessageDescription[];
diff --git a/chrome/browser/history/android/android_provider_backend.cc b/chrome/browser/history/android/android_provider_backend.cc index cc91883..8189e09f 100644 --- a/chrome/browser/history/android/android_provider_backend.cc +++ b/chrome/browser/history/android/android_provider_backend.cc
@@ -121,7 +121,9 @@ void RunNotifyURLsModified(HistoryBackendNotifier* notifier, std::unique_ptr<URLRows> rows) { - notifier->NotifyURLsModified(*rows); + // All modifications from the android UI are caused by user action and not by + // expiration. + notifier->NotifyURLsModified(*rows, /*is_from_expiration=*/false); } void RunNotifyURLsDeleted(HistoryBackendNotifier* notifier,
diff --git a/chrome/browser/history/android/android_provider_backend_unittest.cc b/chrome/browser/history/android/android_provider_backend_unittest.cc index b37f6f05..548a752 100644 --- a/chrome/browser/history/android/android_provider_backend_unittest.cc +++ b/chrome/browser/history/android/android_provider_backend_unittest.cc
@@ -134,7 +134,9 @@ const history::URLRow& row, const history::RedirectList& redirects, base::Time visit_time) override {} - void NotifyURLsModified(const history::URLRows& rows) override { + void NotifyURLsModified(const history::URLRows& rows, + bool is_from_expiration) override { + EXPECT_FALSE(is_from_expiration); modified_details_.reset(new history::URLRows(rows)); } void NotifyURLsDeleted(DeletionInfo deletion_info) override {
diff --git a/chrome/browser/metrics/process_memory_metrics_emitter.cc b/chrome/browser/metrics/process_memory_metrics_emitter.cc index 0f04b32..1564662 100644 --- a/chrome/browser/metrics/process_memory_metrics_emitter.cc +++ b/chrome/browser/metrics/process_memory_metrics_emitter.cc
@@ -174,6 +174,15 @@ {"v8/main/heap", "V8.Main.Heap.AllocatedObjects", kLargeMetric, kAllocatedObjectsSize, EmitTo::kUkmAndUmaAsSize, &Memory_Experimental::SetV8_Main_Heap_AllocatedObjects}, + {"v8/main/heap/code_large_object_space", + "V8.Main.Heap.CodeLargeObjectSpace", kLargeMetric, kEffectiveSize, + EmitTo::kUkmAndUmaAsSize, + &Memory_Experimental::SetV8_Main_Heap_CodeLargeObjectSpace}, + {"v8/main/heap/code_large_object_space", + "V8.Main.Heap.CodeLargeObjectSpace.AllocatedObjects", kLargeMetric, + kAllocatedObjectsSize, EmitTo::kUkmAndUmaAsSize, + &Memory_Experimental:: + SetV8_Main_Heap_CodeLargeObjectSpace_AllocatedObjects}, {"v8/main/heap/code_space", "V8.Main.Heap.CodeSpace", kLargeMetric, kEffectiveSize, EmitTo::kUkmAndUmaAsSize, &Memory_Experimental::SetV8_Main_Heap_CodeSpace},
diff --git a/chrome/browser/metrics/process_memory_metrics_emitter_unittest.cc b/chrome/browser/metrics/process_memory_metrics_emitter_unittest.cc index b48bdbbc..cf15b0d 100644 --- a/chrome/browser/metrics/process_memory_metrics_emitter_unittest.cc +++ b/chrome/browser/metrics/process_memory_metrics_emitter_unittest.cc
@@ -197,6 +197,15 @@ metrics_mb_or_count["V8.Main.Heap.AllocatedObjects"] * 1024 * 1024); SetAllocatorDumpMetric( + pmd, "v8/main/heap/code_large_object_space", "effective_size", + metrics_mb_or_count["V8.Main.Heap.CodeLargeObjectSpace"] * 1024 * 1024); + SetAllocatorDumpMetric( + pmd, "v8/main/heap/code_large_object_space", "allocated_objects_size", + metrics_mb_or_count + ["V8.Main.Heap.CodeLargeObjectSpace.AllocatedObjects"] * + 1024 * 1024); + + SetAllocatorDumpMetric( pmd, "v8/main/heap/code_space", "effective_size", metrics_mb_or_count["V8.Main.Heap.CodeSpace"] * 1024 * 1024); SetAllocatorDumpMetric(
diff --git a/chrome/browser/password_manager/password_accessory_controller_impl.cc b/chrome/browser/password_manager/password_accessory_controller_impl.cc index 7f30c0fd..0722f7932 100644 --- a/chrome/browser/password_manager/password_accessory_controller_impl.cc +++ b/chrome/browser/password_manager/password_accessory_controller_impl.cc
@@ -156,8 +156,6 @@ const base::Optional< autofill::password_generation::PasswordGenerationUIData>& ui_data, const base::WeakPtr<password_manager::PasswordManagerDriver>& driver) { - DCHECK(mf_controller_); - target_frame_driver_ = driver; if (available) { DCHECK(ui_data.has_value()); @@ -172,14 +170,12 @@ generation_element_data_.reset(); } - mf_controller_->OnAutomaticGenerationStatusChanged(available); + GetManualFillingController()->OnAutomaticGenerationStatusChanged(available); } void PasswordAccessoryControllerImpl::OnFilledIntoFocusedField( autofill::FillingStatus status) { - DCHECK(mf_controller_); - - mf_controller_->OnFilledIntoFocusedField(status); + GetManualFillingController()->OnFilledIntoFocusedField(status); } void PasswordAccessoryControllerImpl::OnOptionSelected( @@ -200,10 +196,8 @@ const url::Origin& origin, bool is_fillable, bool is_password_field) { - DCHECK(mf_controller_); - current_origin_ = is_fillable ? origin : url::Origin(); - mf_controller_->RefreshSuggestionsForField( + GetManualFillingController()->RefreshSuggestionsForField( is_fillable, CreateAccessorySheetData( origin, is_fillable ? origin_suggestions_[origin] @@ -219,15 +213,11 @@ } void PasswordAccessoryControllerImpl::ShowWhenKeyboardIsVisible() { - DCHECK(mf_controller_); - - mf_controller_->ShowWhenKeyboardIsVisible(); + GetManualFillingController()->ShowWhenKeyboardIsVisible(); } void PasswordAccessoryControllerImpl::Hide() { - DCHECK(mf_controller_); - - mf_controller_->Hide(); + GetManualFillingController()->Hide(); } void PasswordAccessoryControllerImpl::GetFavicon( @@ -327,7 +317,6 @@ favicon_service_(FaviconServiceFactory::GetForProfile( Profile::FromBrowserContext(web_contents->GetBrowserContext()), ServiceAccessType::EXPLICIT_ACCESS)) { - mf_controller_ = ManualFillingController::GetOrCreate(web_contents); } // Additional creation functions in unit tests only: @@ -399,3 +388,11 @@ } icon_request->pending_requests.clear(); } + +base::WeakPtr<ManualFillingController> +PasswordAccessoryControllerImpl::GetManualFillingController() { + if (!mf_controller_) + mf_controller_ = ManualFillingController::GetOrCreate(web_contents_); + DCHECK(mf_controller_); + return mf_controller_; +}
diff --git a/chrome/browser/password_manager/password_accessory_controller_impl.h b/chrome/browser/password_manager/password_accessory_controller_impl.h index c74616d..be50522 100644 --- a/chrome/browser/password_manager/password_accessory_controller_impl.h +++ b/chrome/browser/password_manager/password_accessory_controller_impl.h
@@ -123,6 +123,10 @@ url::Origin origin, const favicon_base::FaviconRawBitmapResult& bitmap_results); + // Lazy-initializes and returns the ManualFillingController for the current + // |web_contents_|. The lazy initialization allows injecting mocks for tests. + base::WeakPtr<ManualFillingController> GetManualFillingController(); + // Contains the last set of credentials by origin. std::map<url::Origin, std::vector<SuggestionElementData>> origin_suggestions_;
diff --git a/chrome/browser/password_manager/password_store_signin_notifier_impl.cc b/chrome/browser/password_manager/password_store_signin_notifier_impl.cc index 210573b..dc47f00c 100644 --- a/chrome/browser/password_manager/password_store_signin_notifier_impl.cc +++ b/chrome/browser/password_manager/password_store_signin_notifier_impl.cc
@@ -6,8 +6,8 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/signin/account_tracker_service_factory.h" -#include "chrome/browser/signin/signin_manager_factory.h" -#include "components/signin/core/browser/signin_manager.h" +#include "chrome/browser/signin/identity_manager_factory.h" +#include "services/identity/public/cpp/identity_manager.h" namespace password_manager { @@ -22,34 +22,32 @@ void PasswordStoreSigninNotifierImpl::SubscribeToSigninEvents( PasswordStore* store) { set_store(store); - SigninManagerFactory::GetForProfile(profile_)->AddObserver(this); + IdentityManagerFactory::GetForProfile(profile_)->AddObserver(this); AccountTrackerServiceFactory::GetForProfile(profile_)->AddObserver(this); } void PasswordStoreSigninNotifierImpl::UnsubscribeFromSigninEvents() { - SigninManagerFactory::GetForProfile(profile_)->RemoveObserver(this); AccountTrackerServiceFactory::GetForProfile(profile_)->RemoveObserver(this); + IdentityManagerFactory::GetForProfile(profile_)->RemoveObserver(this); } -void PasswordStoreSigninNotifierImpl::GoogleSigninSucceededWithPassword( - const std::string& account_id, - const std::string& username, +void PasswordStoreSigninNotifierImpl::OnPrimaryAccountSetWithPassword( + const AccountInfo& account_info, const std::string& password) { - NotifySignin(username, password); + NotifySignin(account_info.email, password); } -void PasswordStoreSigninNotifierImpl::GoogleSignedOut( - const std::string& account_id, - const std::string& username) { - NotifySignedOut(username, /* primary_account= */ true); +void PasswordStoreSigninNotifierImpl::OnPrimaryAccountCleared( + const AccountInfo& account_info) { + NotifySignedOut(account_info.email, /* primary_account= */ true); } // AccountTrackerService::Observer implementations. void PasswordStoreSigninNotifierImpl::OnAccountRemoved( const AccountInfo& info) { // Only reacts to content area (non-primary) Gaia account sign-out event. - if (info.account_id != SigninManagerFactory::GetForProfile(profile_) - ->GetAuthenticatedAccountId()) { + if (info.account_id != + IdentityManagerFactory::GetForProfile(profile_)->GetPrimaryAccountId()) { NotifySignedOut(info.email, /* primary_account= */ false); } }
diff --git a/chrome/browser/password_manager/password_store_signin_notifier_impl.h b/chrome/browser/password_manager/password_store_signin_notifier_impl.h index 122995f..caa8efd 100644 --- a/chrome/browser/password_manager/password_store_signin_notifier_impl.h +++ b/chrome/browser/password_manager/password_store_signin_notifier_impl.h
@@ -9,7 +9,7 @@ #include "components/password_manager/core/browser/password_store_signin_notifier.h" #include "components/signin/core/browser/account_tracker_service.h" -#include "components/signin/core/browser/signin_manager_base.h" +#include "services/identity/public/cpp/identity_manager.h" class Profile; @@ -17,9 +17,10 @@ // Responsible for subscribing to Chrome sign-in events and passing them to // PasswordStore. -class PasswordStoreSigninNotifierImpl : public PasswordStoreSigninNotifier, - public SigninManagerBase::Observer, - public AccountTrackerService::Observer { +class PasswordStoreSigninNotifierImpl + : public PasswordStoreSigninNotifier, + public identity::IdentityManager::Observer, + public AccountTrackerService::Observer { public: explicit PasswordStoreSigninNotifierImpl(Profile* profile); ~PasswordStoreSigninNotifierImpl() override; @@ -29,12 +30,9 @@ void UnsubscribeFromSigninEvents() override; // SigninManagerBase::Observer implementations. - void GoogleSigninSucceededWithPassword(const std::string& account_id, - const std::string& username, - const std::string& password) override; - - void GoogleSignedOut(const std::string& account_id, - const std::string& username) override; + void OnPrimaryAccountSetWithPassword(const AccountInfo& account_info, + const std::string& password) override; + void OnPrimaryAccountCleared(const AccountInfo& account_info) override; // AccountTrackerService::Observer implementations. void OnAccountRemoved(const AccountInfo& info) override;
diff --git a/chrome/browser/policy/policy_browsertest.cc b/chrome/browser/policy/policy_browsertest.cc index 66d79b1..7e86df5 100644 --- a/chrome/browser/policy/policy_browsertest.cc +++ b/chrome/browser/policy/policy_browsertest.cc
@@ -5630,7 +5630,6 @@ const GURL url = g_browser_process->variations_service()->GetVariationsServerURL( - g_browser_process->local_state(), std::string(), variations::VariationsService::HttpOptions::USE_HTTPS); EXPECT_TRUE(base::StartsWith(url.spec(), default_variations_url, base::CompareCase::SENSITIVE));
diff --git a/chrome/browser/signin/signin_error_notifier_ash_unittest.cc b/chrome/browser/signin/signin_error_notifier_ash_unittest.cc index 50b0c73..effc6cd 100644 --- a/chrome/browser/signin/signin_error_notifier_ash_unittest.cc +++ b/chrome/browser/signin/signin_error_notifier_ash_unittest.cc
@@ -7,6 +7,7 @@ #include <stddef.h> #include <memory> +#include <string> #include "base/macros.h" #include "base/memory/ptr_util.h" @@ -14,26 +15,27 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/login/users/mock_user_manager.h" #include "chrome/browser/notifications/notification_display_service_tester.h" -#include "chrome/browser/signin/signin_error_controller_factory.h" +#include "chrome/browser/signin/account_tracker_service_factory.h" +#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" #include "chrome/browser/signin/signin_error_notifier_factory_ash.h" #include "chrome/test/base/browser_with_test_window_test.h" #include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile_manager.h" -#include "components/signin/core/browser/fake_auth_status_provider.h" -#include "components/signin/core/browser/signin_error_controller.h" +#include "components/signin/core/browser/account_tracker_service.h" +#include "components/signin/core/browser/profile_oauth2_token_service.h" #include "components/user_manager/scoped_user_manager.h" -#include "content/public/test/test_browser_thread_bundle.h" +#include "google_apis/gaia/oauth2_token_service_delegate.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/message_center/public/cpp/notification.h" namespace { -static const char kTestAccountId[] = "testing_profile"; +const char kTestGaiaId[] = "gaia_id"; +const char kTestEmail[] = "email@example.com"; // Notification ID corresponding to kProfileSigninNotificationId + // kTestAccountId. -static const char kNotificationId[] = - "chrome://settings/signin/testing_profile"; +const char kNotificationId[] = "chrome://settings/signin/testing_profile"; class SigninErrorNotifierTest : public BrowserWithTestWindowTest { public: @@ -44,84 +46,65 @@ user_manager_enabler_ = std::make_unique<user_manager::ScopedUserManager>( base::WrapUnique(mock_user_manager_)); - error_controller_ = - SigninErrorControllerFactory::GetForProfile(GetProfile()); SigninErrorNotifierFactory::GetForProfile(GetProfile()); display_service_ = std::make_unique<NotificationDisplayServiceTester>(profile()); } + void SetAuthError(const GoogleServiceAuthError& error) { + // TODO(https://crbug.com/836212): Do not use the delegate directly, because + // it is internal API. + ProfileOAuth2TokenService* token_service = + ProfileOAuth2TokenServiceFactory::GetForProfile(profile()); + std::string account_id = + AccountTrackerServiceFactory::GetForProfile(profile())->SeedAccountInfo( + kTestGaiaId, kTestEmail); + if (!token_service->RefreshTokenIsAvailable(account_id)) + token_service->UpdateCredentials(account_id, "refresh_token"); + token_service->GetDelegate()->UpdateAuthError(account_id, error); + } + protected: - SigninErrorController* error_controller_; std::unique_ptr<NotificationDisplayServiceTester> display_service_; chromeos::MockUserManager* mock_user_manager_; // Not owned. std::unique_ptr<user_manager::ScopedUserManager> user_manager_enabler_; }; -TEST_F(SigninErrorNotifierTest, NoErrorAuthStatusProviders) { - EXPECT_FALSE(display_service_->GetNotification(kNotificationId)); - { - // Add a provider (removes itself on exiting this scope). - FakeAuthStatusProvider provider(error_controller_); - EXPECT_FALSE(display_service_->GetNotification(kNotificationId)); - } +TEST_F(SigninErrorNotifierTest, NoNotification) { EXPECT_FALSE(display_service_->GetNotification(kNotificationId)); } -TEST_F(SigninErrorNotifierTest, ErrorAuthStatusProvider) { - { - FakeAuthStatusProvider provider(error_controller_); - EXPECT_FALSE(display_service_->GetNotification(kNotificationId)); - { - FakeAuthStatusProvider error_provider(error_controller_); - error_provider.SetAuthError( - kTestAccountId, - GoogleServiceAuthError( - GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)); - EXPECT_TRUE(display_service_->GetNotification(kNotificationId)); - } - // error_provider is removed now that we've left that scope. - EXPECT_FALSE(display_service_->GetNotification(kNotificationId)); - } - // All providers should be removed now. +TEST_F(SigninErrorNotifierTest, ErrorReset) { + EXPECT_FALSE(display_service_->GetNotification(kNotificationId)); + + SetAuthError( + GoogleServiceAuthError(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)); + EXPECT_TRUE(display_service_->GetNotification(kNotificationId)); + + SetAuthError(GoogleServiceAuthError::AuthErrorNone()); EXPECT_FALSE(display_service_->GetNotification(kNotificationId)); } -TEST_F(SigninErrorNotifierTest, AuthStatusProviderErrorTransition) { - { - FakeAuthStatusProvider provider0(error_controller_); - FakeAuthStatusProvider provider1(error_controller_); - provider0.SetAuthError( - kTestAccountId, - GoogleServiceAuthError( - GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)); +TEST_F(SigninErrorNotifierTest, ErrorTransition) { + SetAuthError( + GoogleServiceAuthError(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)); - base::Optional<message_center::Notification> notification = - display_service_->GetNotification(kNotificationId); - ASSERT_TRUE(notification); - base::string16 message = notification->message(); - EXPECT_FALSE(message.empty()); + base::Optional<message_center::Notification> notification = + display_service_->GetNotification(kNotificationId); + ASSERT_TRUE(notification); + base::string16 message = notification->message(); + EXPECT_FALSE(message.empty()); - // Now set another auth error and clear the original. - provider1.SetAuthError( - kTestAccountId, - GoogleServiceAuthError( - GoogleServiceAuthError::UNEXPECTED_SERVICE_RESPONSE)); - provider0.SetAuthError( - kTestAccountId, - GoogleServiceAuthError::AuthErrorNone()); + // Now set another auth error. + SetAuthError(GoogleServiceAuthError( + GoogleServiceAuthError::UNEXPECTED_SERVICE_RESPONSE)); - notification = display_service_->GetNotification(kNotificationId); - ASSERT_TRUE(notification); - base::string16 new_message = notification->message(); - EXPECT_FALSE(new_message.empty()); + notification = display_service_->GetNotification(kNotificationId); + ASSERT_TRUE(notification); + base::string16 new_message = notification->message(); + EXPECT_FALSE(new_message.empty()); - ASSERT_NE(new_message, message); - - provider1.SetAuthError( - kTestAccountId, GoogleServiceAuthError::AuthErrorNone()); - EXPECT_FALSE(display_service_->GetNotification(kNotificationId)); - } + ASSERT_NE(new_message, message); } // Verify that SigninErrorNotifier ignores certain errors. @@ -153,9 +136,8 @@ for (size_t i = 0; i < arraysize(table); ++i) { if (GoogleServiceAuthError::IsDeprecated(table[i].error_state)) continue; - FakeAuthStatusProvider provider(error_controller_); - provider.SetAuthError(kTestAccountId, - GoogleServiceAuthError(table[i].error_state)); + + SetAuthError(GoogleServiceAuthError(table[i].error_state)); base::Optional<message_center::Notification> notification = display_service_->GetNotification(kNotificationId); ASSERT_EQ(table[i].is_error, !!notification); @@ -164,6 +146,7 @@ EXPECT_FALSE(notification->message().empty()); EXPECT_EQ((size_t)1, notification->buttons().size()); } + SetAuthError(GoogleServiceAuthError::AuthErrorNone()); } }
diff --git a/chrome/browser/sync/test/integration/two_client_preferences_sync_test.cc b/chrome/browser/sync/test/integration/two_client_preferences_sync_test.cc index 38410a3..47f1be8 100644 --- a/chrome/browser/sync/test/integration/two_client_preferences_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_preferences_sync_test.cc
@@ -8,6 +8,7 @@ #include "base/macros.h" #include "base/strings/stringprintf.h" #include "base/test/metrics/histogram_tester.h" +#include "build/build_config.h" #include "chrome/browser/sync/test/integration/feature_toggler.h" #include "chrome/browser/sync/test/integration/preferences_helper.h" #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h" @@ -139,8 +140,17 @@ ASSERT_TRUE(ListPrefMatchChecker(prefs::kURLsToRestoreOnStartup).Wait()); } -IN_PROC_BROWSER_TEST_P(TwoClientPreferencesSyncTest, - E2E_ENABLED(SingleClientEnabledEncryptionBothChanged)) { +// Disabled due to flakiness on Chrome OS: https://crbug.com/873902. +#if defined(OS_CHROMEOS) +#define MAYBE_SingleClientEnabledEncryptionBothChanged \ + DISABLED_SingleClientEnabledEncryptionBothChanged +#else +#define MAYBE_SingleClientEnabledEncryptionBothChanged \ + SingleClientEnabledEncryptionBothChanged +#endif +IN_PROC_BROWSER_TEST_P( + TwoClientPreferencesSyncTest, + E2E_ENABLED(MAYBE_SingleClientEnabledEncryptionBothChanged)) { ASSERT_TRUE(SetupSync()); ASSERT_TRUE(BooleanPrefMatchChecker(prefs::kHomePageIsNewTabPage).Wait()); ASSERT_TRUE(StringPrefMatchChecker(prefs::kHomePage).Wait());
diff --git a/chrome/browser/sync/test/integration/two_client_typed_urls_sync_test.cc b/chrome/browser/sync/test/integration/two_client_typed_urls_sync_test.cc index 1b865ad..3d76356 100644 --- a/chrome/browser/sync/test/integration/two_client_typed_urls_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_typed_urls_sync_test.cc
@@ -186,6 +186,47 @@ EXPECT_TRUE(CheckSyncHasURLMetadata(1, new_url)); } +IN_PROC_BROWSER_TEST_F(TwoClientTypedUrlsSyncTest, + AddThenExpireOnSecondClient) { + ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; + + base::Time now = base::Time::Now(); + + // Populate one client with a URL, should sync to the other. + GURL url("http://www.add-one-history.google.com/"); + base::Time insertion_time = now - base::TimeDelta::FromDays(1); + AddUrlToHistoryWithTimestamp(0, url, ui::PAGE_TRANSITION_TYPED, + history::SOURCE_BROWSED, insertion_time); + std::vector<history::URLRow> urls = GetTypedUrlsFromClient(0); + ASSERT_EQ(1U, urls.size()); + ASSERT_EQ(url, urls[0].url()); + history::URLID url_id_on_first_client = urls[0].id(); + + // Wait for sync to finish. + ASSERT_TRUE(TypedURLChecker(1, url.spec()).Wait()); + + // Second client should have the url. + ASSERT_EQ(1U, GetTypedUrlsFromClient(1).size()); + EXPECT_TRUE(CheckSyncHasURLMetadata(1, url)); + + // Expire the url on the second client. + ExpireHistoryBefore(1, insertion_time + base::TimeDelta::FromSeconds(1)); + + // The data and the metadata should be gone on the second client. + ASSERT_EQ(0U, GetTypedUrlsFromClient(1).size()); + EXPECT_FALSE(CheckSyncHasURLMetadata(1, url)); + + // Let sync finish; Add a dummy url to the second client and sync it. + AddUrlToHistory(1, GURL(kDummyUrl)); + ASSERT_EQ(1U, GetTypedUrlsFromClient(1).size()); + ASSERT_TRUE(TypedURLChecker(0, kDummyUrl).Wait()); + + // The expiration should not get synced up, the first client still has the + // URL (and also the dummy URL) + ASSERT_EQ(2U, GetTypedUrlsFromClient(0).size()); + EXPECT_TRUE(CheckSyncHasMetadataForURLID(0, url_id_on_first_client)); +} + IN_PROC_BROWSER_TEST_F(TwoClientTypedUrlsSyncTest, AddThenExpireThenAddAgain) { ASSERT_TRUE(SetupSync()) << "SetupSync() failed.";
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 71c7676..992223e 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -91,6 +91,8 @@ "blocked_content/scoped_visibility_tracker.h", "blocked_content/tab_under_navigation_throttle.cc", "blocked_content/tab_under_navigation_throttle.h", + "blocked_content/url_list_manager.cc", + "blocked_content/url_list_manager.h", "bookmarks/bookmark_bar.h", "bookmarks/bookmark_bubble_observer.h", "bookmarks/bookmark_editor.cc",
diff --git a/chrome/browser/ui/blocked_content/framebust_block_tab_helper.cc b/chrome/browser/ui/blocked_content/framebust_block_tab_helper.cc index 2f65d63..77c2301 100644 --- a/chrome/browser/ui/blocked_content/framebust_block_tab_helper.cc +++ b/chrome/browser/ui/blocked_content/framebust_block_tab_helper.cc
@@ -28,9 +28,7 @@ callbacks_.push_back(std::move(click_callback)); DCHECK_EQ(blocked_urls_.size(), callbacks_.size()); - for (Observer& observer : observers_) { - observer.OnBlockedUrlAdded(blocked_url); - } + manager_.NotifyObservers(0 /* id */, blocked_url); UpdateLocationBarUI(web_contents()); } @@ -49,14 +47,6 @@ ui::PAGE_TRANSITION_LINK, false)); } -void FramebustBlockTabHelper::AddObserver(Observer* observer) { - observers_.AddObserver(observer); -} - -void FramebustBlockTabHelper::RemoveObserver(const Observer* observer) { - observers_.RemoveObserver(observer); -} - FramebustBlockTabHelper::FramebustBlockTabHelper( content::WebContents* web_contents) : content::WebContentsObserver(web_contents) {}
diff --git a/chrome/browser/ui/blocked_content/framebust_block_tab_helper.h b/chrome/browser/ui/blocked_content/framebust_block_tab_helper.h index 11245b9..4544edecc 100644 --- a/chrome/browser/ui/blocked_content/framebust_block_tab_helper.h +++ b/chrome/browser/ui/blocked_content/framebust_block_tab_helper.h
@@ -9,7 +9,7 @@ #include "base/callback.h" #include "base/macros.h" -#include "base/observer_list.h" +#include "chrome/browser/ui/blocked_content/url_list_manager.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_user_data.h" #include "url/gurl.h" @@ -27,16 +27,6 @@ using ClickCallback = base::OnceCallback< void(const GURL&, size_t /* index */, size_t /* total_size */)>; - // There is expected to be at most one observer at a time. - class Observer { - public: - // Called whenever a new URL was blocked. - virtual void OnBlockedUrlAdded(const GURL& blocked_url) = 0; - - protected: - virtual ~Observer() = default; - }; - ~FramebustBlockTabHelper() override; // Shows the blocked Framebust icon in the Omnibox for the |blocked_url|. @@ -52,12 +42,11 @@ // vector of blocked URLs. void OnBlockedUrlClicked(size_t index); - void AddObserver(Observer* observer); - void RemoveObserver(const Observer* observer); - // Returns all of the currently blocked URLs. const std::vector<GURL>& blocked_urls() const { return blocked_urls_; } + UrlListManager* manager() { return &manager_; } + private: friend class content::WebContentsUserData<FramebustBlockTabHelper>; @@ -67,6 +56,8 @@ void DidFinishNavigation( content::NavigationHandle* navigation_handle) override; + UrlListManager manager_; + // Remembers all the currently blocked URLs. This is cleared on each // navigation. std::vector<GURL> blocked_urls_; @@ -75,8 +66,6 @@ // distribution of the URLs in blocked_urls(). std::vector<ClickCallback> callbacks_; - base::ObserverList<Observer>::Unchecked observers_; - DISALLOW_COPY_AND_ASSIGN(FramebustBlockTabHelper); };
diff --git a/chrome/browser/ui/blocked_content/popup_blocker_tab_helper.cc b/chrome/browser/ui/blocked_content/popup_blocker_tab_helper.cc index 41fe6169..e7eda19 100644 --- a/chrome/browser/ui/blocked_content/popup_blocker_tab_helper.cc +++ b/chrome/browser/ui/blocked_content/popup_blocker_tab_helper.cc
@@ -54,14 +54,6 @@ PopupBlockerTabHelper::~PopupBlockerTabHelper() { } -void PopupBlockerTabHelper::AddObserver(Observer* observer) { - observers_.AddObserver(observer); -} - -void PopupBlockerTabHelper::RemoveObserver(Observer* observer) { - observers_.RemoveObserver(observer); -} - void PopupBlockerTabHelper::DidFinishNavigation( content::NavigationHandle* navigation_handle) { // Clear all page actions, blocked content notifications and browser actions @@ -101,8 +93,7 @@ std::move(*params), window_features, block_type); TabSpecificContentSettings::FromWebContents(web_contents())-> OnContentBlocked(CONTENT_SETTINGS_TYPE_POPUPS); - for (auto& observer : observers_) - observer.BlockedPopupAdded(id, blocked_popups_[id]->params.url); + manager_.NotifyObservers(id, blocked_popups_[id]->params.url); #if defined(OS_ANDROID) // Should replace existing popup infobars, with an updated count of how many
diff --git a/chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h b/chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h index 572d48e..359d585 100644 --- a/chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h +++ b/chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h
@@ -12,9 +12,9 @@ #include <memory> #include "base/macros.h" -#include "base/observer_list.h" #include "chrome/browser/ui/blocked_content/blocked_window_params.h" #include "chrome/browser/ui/blocked_content/popup_blocker.h" +#include "chrome/browser/ui/blocked_content/url_list_manager.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_user_data.h" #include "ui/base/window_open_disposition.h" @@ -52,19 +52,8 @@ kMaxValue = kClickedThroughAbusive }; - class Observer { - public: - virtual void BlockedPopupAdded(int32_t id, const GURL& url) {} - - protected: - virtual ~Observer() = default; - }; - ~PopupBlockerTabHelper() override; - void AddObserver(Observer* observer); - void RemoveObserver(Observer* observer); - // Returns the number of blocked popups. size_t GetBlockedPopupsCount() const; @@ -87,6 +76,8 @@ // Logs a histogram measuring popup blocker actions. static void LogAction(Action action); + UrlListManager* manager() { return &manager_; } + private: struct BlockedRequest; friend class content::WebContentsUserData<PopupBlockerTabHelper>; @@ -96,12 +87,12 @@ // Called when the blocked popup notification is hidden. void HidePopupNotification(); + UrlListManager manager_; + // Note, this container should be sorted based on the position in the popup // list, so it is keyed by an id which is continually increased. std::map<int32_t, std::unique_ptr<BlockedRequest>> blocked_popups_; - base::ObserverList<Observer>::Unchecked observers_; - int32_t next_id_ = 0; DISALLOW_COPY_AND_ASSIGN(PopupBlockerTabHelper);
diff --git a/chrome/browser/ui/blocked_content/url_list_manager.cc b/chrome/browser/ui/blocked_content/url_list_manager.cc new file mode 100644 index 0000000..daac148c --- /dev/null +++ b/chrome/browser/ui/blocked_content/url_list_manager.cc
@@ -0,0 +1,23 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/blocked_content/url_list_manager.h" + +UrlListManager::UrlListManager() = default; + +UrlListManager::~UrlListManager() = default; + +void UrlListManager::AddObserver(Observer* observer) { + observers_.AddObserver(observer); +} + +void UrlListManager::RemoveObserver(Observer* observer) { + observers_.RemoveObserver(observer); +} + +void UrlListManager::NotifyObservers(int32_t id, const GURL& url) { + for (auto& observer : observers_) { + observer.BlockedUrlAdded(id, url); + } +}
diff --git a/chrome/browser/ui/blocked_content/url_list_manager.h b/chrome/browser/ui/blocked_content/url_list_manager.h new file mode 100644 index 0000000..351b2a52 --- /dev/null +++ b/chrome/browser/ui/blocked_content/url_list_manager.h
@@ -0,0 +1,43 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_BLOCKED_CONTENT_URL_LIST_MANAGER_H_ +#define CHROME_BROWSER_UI_BLOCKED_CONTENT_URL_LIST_MANAGER_H_ + +#include <stdint.h> + +#include "base/macros.h" +#include "base/observer_list.h" + +class GURL; + +// This class manages lists of blocked URLs in order to drive UI surfaces. +// Currently it is used by the redirect / popup blocked UIs. +// +// TODO(csharrison): Currently this object is composed within the framebust / +// popup tab helpers. Eventually those objects could be replaced almost entirely +// by shared logic here. +class UrlListManager { + public: + class Observer { + public: + virtual ~Observer() {} + virtual void BlockedUrlAdded(int32_t id, const GURL& url) = 0; + }; + + UrlListManager(); + ~UrlListManager(); + + void AddObserver(Observer* observer); + void RemoveObserver(Observer* observer); + + void NotifyObservers(int32_t id, const GURL& url); + + private: + base::ObserverList<Observer>::Unchecked observers_; + + DISALLOW_COPY_AND_ASSIGN(UrlListManager); +}; + +#endif // CHROME_BROWSER_UI_BLOCKED_CONTENT_URL_LIST_MANAGER_H_
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index 4a39fe8..1ee0924 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc
@@ -1361,6 +1361,7 @@ nav_params.window_action = NavigateParams::SHOW_WINDOW; nav_params.user_gesture = params.user_gesture; nav_params.blob_url_loader_factory = params.blob_url_loader_factory; + nav_params.href_translate = params.href_translate; bool is_popup = source && ConsiderForPopupBlocking(params.disposition); if (is_popup && MaybeBlockPopup(source, base::Optional<GURL>(), &nav_params, ¶ms, blink::mojom::WindowFeatures())) {
diff --git a/chrome/browser/ui/browser_navigator.cc b/chrome/browser/ui/browser_navigator.cc index 7abfd399..57cc96c 100644 --- a/chrome/browser/ui/browser_navigator.cc +++ b/chrome/browser/ui/browser_navigator.cc
@@ -328,6 +328,7 @@ load_url_params.blob_url_loader_factory = params->blob_url_loader_factory; load_url_params.input_start = params->input_start; load_url_params.was_activated = params->was_activated; + load_url_params.href_translate = params->href_translate; // |frame_tree_node_id| is kNoFrameTreeNodeId for main frame navigations. if (params->frame_tree_node_id ==
diff --git a/chrome/browser/ui/browser_navigator_params.h b/chrome/browser/ui/browser_navigator_params.h index abc8acf..8ba5b47 100644 --- a/chrome/browser/ui/browser_navigator_params.h +++ b/chrome/browser/ui/browser_navigator_params.h
@@ -267,6 +267,11 @@ content::WasActivatedOption was_activated = content::WasActivatedOption::kUnknown; + // If this navigation was initiated from a link that specified the + // hrefTranslate attribute, this contains the attribute's value (a BCP47 + // language code). Empty otherwise. + std::string href_translate; + private: NavigateParams(); DISALLOW_COPY_AND_ASSIGN(NavigateParams);
diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc index e3ac112..ea390f1 100644 --- a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc +++ b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc
@@ -955,7 +955,7 @@ // ContentSettingPopupBubbleModel ---------------------------------------------- class ContentSettingPopupBubbleModel : public ContentSettingSingleRadioGroup, - public PopupBlockerTabHelper::Observer { + public UrlListManager::Observer { public: ContentSettingPopupBubbleModel(Delegate* delegate, WebContents* web_contents, @@ -966,7 +966,7 @@ void CommitChanges() override; // PopupBlockerTabHelper::Observer: - void BlockedPopupAdded(int32_t id, const GURL& url) override; + void BlockedUrlAdded(int32_t id, const GURL& url) override; // content::NotificationObserver: void Observe(int type, @@ -980,8 +980,7 @@ return bubble_content().list_items[index].item_id; } - ScopedObserver<PopupBlockerTabHelper, PopupBlockerTabHelper::Observer> - popup_blocker_observer_; + ScopedObserver<UrlListManager, UrlListManager::Observer> url_list_observer_; DISALLOW_COPY_AND_ASSIGN(ContentSettingPopupBubbleModel); }; @@ -994,7 +993,7 @@ web_contents, profile, CONTENT_SETTINGS_TYPE_POPUPS), - popup_blocker_observer_(this) { + url_list_observer_(this) { if (!web_contents) return; @@ -1006,13 +1005,13 @@ for (const auto& blocked_popup : blocked_popups) AddListItem(CreateUrlListItem(blocked_popup.first, blocked_popup.second)); - popup_blocker_observer_.Add(helper); + url_list_observer_.Add(helper->manager()); content_settings::RecordPopupsAction( content_settings::POPUPS_ACTION_DISPLAYED_BUBBLE); } -void ContentSettingPopupBubbleModel::BlockedPopupAdded(int32_t id, - const GURL& url) { +void ContentSettingPopupBubbleModel::BlockedUrlAdded(int32_t id, + const GURL& url) { AddListItem(CreateUrlListItem(id, url)); } @@ -1022,7 +1021,7 @@ const content::NotificationDetails& details) { ContentSettingSingleRadioGroup::Observe(type, source, details); if (type == content::NOTIFICATION_WEB_CONTENTS_DESTROYED) - popup_blocker_observer_.RemoveAll(); + url_list_observer_.RemoveAll(); } void ContentSettingPopupBubbleModel::OnListItemClicked(int index, @@ -1047,12 +1046,7 @@ ContentSettingSingleRadioGroup::CommitChanges(); } -ContentSettingPopupBubbleModel::~ContentSettingPopupBubbleModel() { - if (web_contents()) { - auto* helper = PopupBlockerTabHelper::FromWebContents(web_contents()); - helper->RemoveObserver(this); - } -} +ContentSettingPopupBubbleModel::~ContentSettingPopupBubbleModel() = default; // ContentSettingMediaStreamBubbleModel ---------------------------------------- @@ -1565,7 +1559,8 @@ : ContentSettingSingleRadioGroup(delegate, web_contents, profile, - CONTENT_SETTINGS_TYPE_POPUPS) { + CONTENT_SETTINGS_TYPE_POPUPS), + url_list_observer_(this) { if (!web_contents) return; @@ -1576,27 +1571,18 @@ for (const auto& blocked_url : helper->blocked_urls()) AddListItem(CreateUrlListItem(0 /* id */, blocked_url)); - helper->AddObserver(this); + url_list_observer_.Add(helper->manager()); } ContentSettingFramebustBlockBubbleModel:: - ~ContentSettingFramebustBlockBubbleModel() { - if (web_contents()) { - FramebustBlockTabHelper::FromWebContents(web_contents()) - ->RemoveObserver(this); - } -} + ~ContentSettingFramebustBlockBubbleModel() = default; void ContentSettingFramebustBlockBubbleModel::Observe( int type, const content::NotificationSource& source, const content::NotificationDetails& details) { - // The order is important because ContentSettingBubbleModel::Observer() clears - // the value of |web_contents()|. - if (type == content::NOTIFICATION_WEB_CONTENTS_DESTROYED) { - FramebustBlockTabHelper::FromWebContents(web_contents()) - ->RemoveObserver(this); - } + if (type == content::NOTIFICATION_WEB_CONTENTS_DESTROYED) + url_list_observer_.RemoveAll(); ContentSettingSingleRadioGroup::Observe(type, source, details); } @@ -1615,7 +1601,8 @@ return this; } -void ContentSettingFramebustBlockBubbleModel::OnBlockedUrlAdded( +void ContentSettingFramebustBlockBubbleModel::BlockedUrlAdded( + int32_t id, const GURL& blocked_url) { AddListItem(CreateUrlListItem(0 /* id */, blocked_url)); }
diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model.h b/chrome/browser/ui/content_settings/content_setting_bubble_model.h index 2acd68e..89e9b21 100644 --- a/chrome/browser/ui/content_settings/content_setting_bubble_model.h +++ b/chrome/browser/ui/content_settings/content_setting_bubble_model.h
@@ -14,10 +14,12 @@ #include "base/compiler_specific.h" #include "base/macros.h" +#include "base/scoped_observer.h" #include "base/strings/string16.h" #include "build/build_config.h" #include "chrome/browser/content_settings/tab_specific_content_settings.h" #include "chrome/browser/ui/blocked_content/framebust_block_tab_helper.h" +#include "chrome/browser/ui/blocked_content/url_list_manager.h" #include "chrome/common/custom_handlers/protocol_handler.h" #include "components/content_settings/core/common/content_settings.h" #include "components/content_settings/core/common/content_settings_types.h" @@ -477,7 +479,7 @@ // The model for the blocked Framebust bubble. class ContentSettingFramebustBlockBubbleModel : public ContentSettingSingleRadioGroup, - public FramebustBlockTabHelper::Observer { + public UrlListManager::Observer { public: ContentSettingFramebustBlockBubbleModel(Delegate* delegate, content::WebContents* web_contents, @@ -495,12 +497,14 @@ ContentSettingFramebustBlockBubbleModel* AsFramebustBlockBubbleModel() override; - // FramebustBlockTabHelper::Observer: - void OnBlockedUrlAdded(const GURL& blocked_url) override; + // UrlListManager::Observer: + void BlockedUrlAdded(int32_t id, const GURL& blocked_url) override; private: ListItem CreateListItem(const GURL& url); + ScopedObserver<UrlListManager, UrlListManager::Observer> url_list_observer_; + DISALLOW_COPY_AND_ASSIGN(ContentSettingFramebustBlockBubbleModel); }; #endif // !defined(OS_ANDROID)
diff --git a/chrome/browser/ui/content_settings/framebust_block_browsertest.cc b/chrome/browser/ui/content_settings/framebust_block_browsertest.cc index 5abaf0e5..4975b79 100644 --- a/chrome/browser/ui/content_settings/framebust_block_browsertest.cc +++ b/chrome/browser/ui/content_settings/framebust_block_browsertest.cc
@@ -12,6 +12,7 @@ #include "base/strings/utf_string_conversions.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/ui/blocked_content/framebust_block_tab_helper.h" +#include "chrome/browser/ui/blocked_content/url_list_manager.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_content_setting_bubble_model_delegate.h" #include "chrome/browser/ui/browser_finder.h" @@ -42,7 +43,7 @@ } // namespace class FramebustBlockBrowserTest : public InProcessBrowserTest, - public FramebustBlockTabHelper::Observer { + public UrlListManager::Observer { public: FramebustBlockBrowserTest() { scoped_feature_list_.InitAndEnableFeature( @@ -55,11 +56,12 @@ ASSERT_TRUE(embedded_test_server()->Start()); current_browser_ = InProcessBrowserTest::browser(); FramebustBlockTabHelper::FromWebContents(GetWebContents()) + ->manager() ->AddObserver(this); } - // FramebustBlockTabHelper::Observer: - void OnBlockedUrlAdded(const GURL& blocked_url) override { + // UrlListManager::Observer: + void BlockedUrlAdded(int32_t id, const GURL& blocked_url) override { if (!blocked_url_added_closure_.is_null()) std::move(blocked_url_added_closure_).Run(); }
diff --git a/chrome/browser/ui/search/search_tab_helper.cc b/chrome/browser/ui/search/search_tab_helper.cc index c331e093..216d3ed 100644 --- a/chrome/browser/ui/search/search_tab_helper.cc +++ b/chrome/browser/ui/search/search_tab_helper.cc
@@ -96,9 +96,9 @@ // their history. bool IsHistorySyncEnabled(Profile* profile) { browser_sync::ProfileSyncService* sync = - ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile); - return sync && - sync->GetPreferredDataTypes().Has(syncer::HISTORY_DELETE_DIRECTIVES); + ProfileSyncServiceFactory::GetForProfile(profile); + return sync->IsSyncFeatureEnabled() && + sync->GetUserSettings()->GetChosenDataTypes().Has(syncer::TYPED_URLS); } } // namespace
diff --git a/chrome/browser/ui/search/search_tab_helper_unittest.cc b/chrome/browser/ui/search/search_tab_helper_unittest.cc index 53102d0..24d4b95 100644 --- a/chrome/browser/ui/search/search_tab_helper_unittest.cc +++ b/chrome/browser/ui/search/search_tab_helper_unittest.cc
@@ -8,7 +8,6 @@ #include <memory> #include <string> -#include <tuple> #include <utility> #include "base/bind.h" @@ -18,8 +17,6 @@ #include "chrome/browser/sync/profile_sync_service_factory.h" #include "chrome/browser/sync/profile_sync_test_util.h" #include "chrome/browser/ui/search/search_ipc_router.h" -#include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/common/render_messages.h" #include "chrome/common/search/mock_embedded_search_client.h" #include "chrome/common/url_constants.h" #include "chrome/grit/generated_resources.h" @@ -27,64 +24,19 @@ #include "chrome/test/base/chrome_render_view_host_test_harness.h" #include "chrome/test/base/testing_profile.h" #include "components/browser_sync/profile_sync_service.h" -#include "components/omnibox/common/omnibox_focus_state.h" #include "components/strings/grit/components_strings.h" -#include "content/public/browser/navigation_controller.h" -#include "content/public/browser/navigation_entry.h" #include "content/public/browser/web_contents.h" -#include "content/public/test/mock_render_process_host.h" -#include "ipc/ipc_message.h" -#include "ipc/ipc_test_sink.h" -#include "net/base/net_errors.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/l10n/l10n_util.h" #include "url/gurl.h" -class OmniboxView; - -using testing::Eq; -using testing::Return; using testing::_; +using testing::NiceMock; +using testing::Return; namespace { -class MockSearchIPCRouterDelegate : public SearchIPCRouter::Delegate { - public: - virtual ~MockSearchIPCRouterDelegate() {} - - MOCK_METHOD1(FocusOmnibox, void(bool focus)); - MOCK_METHOD1(OnDeleteMostVisitedItem, void(const GURL& url)); - MOCK_METHOD1(OnUndoMostVisitedDeletion, void(const GURL& url)); - MOCK_METHOD0(OnUndoAllMostVisitedDeletions, void()); - MOCK_METHOD2(OnAddCustomLink, - bool(const GURL& url, const std::string& title)); - MOCK_METHOD3(OnUpdateCustomLink, - bool(const GURL& url, - const GURL& new_url, - const std::string& new_title)); - MOCK_METHOD2(OnReorderCustomLink, bool(const GURL& url, int new_pos)); - MOCK_METHOD1(OnDeleteCustomLink, bool(const GURL& url)); - MOCK_METHOD0(OnUndoCustomLinkAction, void()); - MOCK_METHOD0(OnResetCustomLinks, void()); - MOCK_METHOD2(OnLogEvent, void(NTPLoggingEventType event, - base::TimeDelta time)); - MOCK_METHOD1(OnLogMostVisitedImpression, - void(const ntp_tiles::NTPTileImpression& impression)); - MOCK_METHOD1(OnLogMostVisitedNavigation, - void(const ntp_tiles::NTPTileImpression& impression)); - MOCK_METHOD1(PasteIntoOmnibox, void(const base::string16&)); - MOCK_METHOD1(ChromeIdentityCheck, bool(const base::string16& identity)); - MOCK_METHOD0(HistorySyncCheck, bool()); - MOCK_METHOD1(OnSetCustomBackgroundURL, void(const GURL& url)); - MOCK_METHOD4(OnSetCustomBackgroundURLWithAttributions, - void(const GURL& background_url, - const std::string& attribution_line_1, - const std::string& attribution_line_2, - const GURL& action_url)); - MOCK_METHOD0(OnSelectLocalBackgroundImage, void()); -}; - class MockEmbeddedSearchClientFactory : public SearchIPCRouter::EmbeddedSearchClientFactory { public: @@ -104,7 +56,8 @@ std::make_unique<IdentityTestEnvironmentProfileAdaptor>(profile()); SearchTabHelper::CreateForWebContents(web_contents()); auto* search_tab = SearchTabHelper::FromWebContents(web_contents()); - auto factory = std::make_unique<MockEmbeddedSearchClientFactory>(); + auto factory = + std::make_unique<NiceMock<MockEmbeddedSearchClientFactory>>(); ON_CALL(*factory, GetEmbeddedSearchClient()) .WillByDefault(Return(&mock_embedded_search_client_)); search_tab->ipc_router_for_testing() @@ -144,16 +97,13 @@ syncer::ModelTypeSet result; if (sync_history) { + result.Put(syncer::TYPED_URLS); result.Put(syncer::HISTORY_DELETE_DIRECTIVES); + result.Put(syncer::SESSIONS); } - EXPECT_CALL(*sync_service, GetPreferredDataTypes()) - .WillRepeatedly(Return(result)); - } - - MockSearchIPCRouterDelegate* mock_delegate() { return &delegate_; } - - MockEmbeddedSearchClient* mock_embedded_search_client() { - return &mock_embedded_search_client_; + ON_CALL(*sync_service, IsFirstSetupComplete()).WillByDefault(Return(true)); + ON_CALL(*sync_service, GetPreferredDataTypes()) + .WillByDefault(Return(result)); } identity::IdentityTestEnvironment* identity_test_env() { @@ -162,8 +112,7 @@ } private: - MockSearchIPCRouterDelegate delegate_; - MockEmbeddedSearchClient mock_embedded_search_client_; + NiceMock<MockEmbeddedSearchClient> mock_embedded_search_client_; std::unique_ptr<IdentityTestEnvironmentProfileAdaptor> identity_test_env_adaptor_; };
diff --git a/chrome/browser/ui/views/frame/browser_view_browsertest.cc b/chrome/browser/ui/views/frame/browser_view_browsertest.cc index a7eb602..1cc766a 100644 --- a/chrome/browser/ui/views/frame/browser_view_browsertest.cc +++ b/chrome/browser/ui/views/frame/browser_view_browsertest.cc
@@ -270,14 +270,12 @@ contents, 1, content::MessageLoopRunner::QuitMode::DEFERRED); TabStrip* tab_strip = browser_view()->tabstrip(); - // Navigate without blocking. - ui_test_utils::NavigateToURLWithDispositionBlockUntilNavigationsComplete( - browser(), - ui_test_utils::GetTestUrl( - base::FilePath(base::FilePath::kCurrentDirectory), - base::FilePath(FILE_PATH_LITERAL("title2.html"))), - 0, WindowOpenDisposition::CURRENT_TAB, ui_test_utils::BROWSER_TEST_NONE); + const GURL test_url = ui_test_utils::GetTestUrl( + base::FilePath(base::FilePath::kCurrentDirectory), + base::FilePath(FILE_PATH_LITERAL("title2.html"))); + contents->GetController().LoadURL(test_url, content::Referrer(), + ui::PAGE_TRANSITION_LINK, std::string()); EXPECT_TRUE(browser()->tab_strip_model()->TabsAreLoading()); EXPECT_EQ(TabNetworkState::kWaiting, tab_strip->tab_at(0)->data().network_state);
diff --git a/chrome/browser/ui/views/tabs/tab_icon.cc b/chrome/browser/ui/views/tabs/tab_icon.cc index c7cbe32d..63788a60 100644 --- a/chrome/browser/ui/views/tabs/tab_icon.cc +++ b/chrome/browser/ui/views/tabs/tab_icon.cc
@@ -276,7 +276,7 @@ (kProgressIndicatorAnimationDuration - 1.0))); } - canvas->DrawRoundRect(bounds, bounds.height() / 2, flags); + canvas->DrawRect(bounds, flags); } void TabIcon::PaintLoadingAnimation(gfx::Canvas* canvas,
diff --git a/chrome/browser/ui/views/toolbar/toolbar_button.cc b/chrome/browser/ui/views/toolbar/toolbar_button.cc index 42fcf76..2bca636 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_button.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_button.cc
@@ -303,8 +303,10 @@ menu_showing_ = false; // Set the state back to normal after the drop down menu is closed. - if (state() != STATE_DISABLED) + if (state() != STATE_DISABLED) { + GetInkDrop()->SetHovered(IsMouseHovered()); SetState(STATE_NORMAL); + } menu_runner_.reset(); menu_model_adapter_.reset();
diff --git a/chrome/browser/ui/webui/settings/people_handler_unittest.cc b/chrome/browser/ui/webui/settings/people_handler_unittest.cc index d49102be..d7bf193a 100644 --- a/chrome/browser/ui/webui/settings/people_handler_unittest.cc +++ b/chrome/browser/ui/webui/settings/people_handler_unittest.cc
@@ -16,6 +16,7 @@ #include "base/values.h" #include "build/build_config.h" #include "chrome/browser/signin/identity_test_environment_profile_adaptor.h" +#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" #include "chrome/browser/signin/scoped_account_consistency.h" #include "chrome/browser/signin/signin_error_controller_factory.h" #include "chrome/browser/sync/profile_sync_service_factory.h" @@ -32,7 +33,8 @@ #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile.h" #include "components/prefs/pref_service.h" -#include "components/signin/core/browser/fake_auth_status_provider.h" +#include "components/signin/core/browser/profile_oauth2_token_service.h" +#include "components/signin/core/browser/signin_manager.h" #include "components/sync/base/sync_prefs.h" #include "components/sync_preferences/pref_service_syncable.h" #include "components/unified_consent/scoped_unified_consent.h" @@ -44,6 +46,7 @@ #include "content/public/test/test_browser_thread_bundle.h" #include "content/public/test/test_web_ui.h" #include "content/public/test/web_contents_tester.h" +#include "google_apis/gaia/oauth2_token_service_delegate.h" #include "services/identity/public/cpp/identity_manager.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/layout.h" @@ -827,9 +830,17 @@ DCHECK_EQ( identity_test_env()->identity_manager()->GetPrimaryAccountInfo().email, kTestUser); - FakeAuthStatusProvider provider( - SigninErrorControllerFactory::GetForProfile(profile())); - provider.SetAuthError(kTestUser, error_); + const std::string& account_id = identity_test_env() + ->identity_manager() + ->GetPrimaryAccountInfo() + .account_id; + ProfileOAuth2TokenService* token_service = + ProfileOAuth2TokenServiceFactory::GetForProfile(profile()); + token_service->UpdateCredentials(account_id, "refresh_token"); + // TODO(https://crbug.com/836212): Do not use the delegate directly, because + // it is internal API. + token_service->GetDelegate()->UpdateAuthError(account_id, error_); + ON_CALL(*mock_pss_, GetDisableReasons()) .WillByDefault(Return(syncer::SyncService::DISABLE_REASON_NONE)); ON_CALL(*mock_pss_, IsPassphraseRequired()).WillByDefault(Return(false));
diff --git a/chrome/renderer/chrome_render_frame_observer_browsertest.cc b/chrome/renderer/chrome_render_frame_observer_browsertest.cc index ee94526..6869d20 100644 --- a/chrome/renderer/chrome_render_frame_observer_browsertest.cc +++ b/chrome/renderer/chrome_render_frame_observer_browsertest.cc
@@ -77,7 +77,8 @@ "This is a main document" "<iframe srcdoc=\"This a document in an iframe.\">" "</body>"); - view_->GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + view_->GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases( + blink::WebWidget::LifecycleUpdateReason::kTest); base::RunLoop().RunUntilIdle(); ASSERT_TRUE(fake_translate_driver_.called_new_page_);
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json index 03f5c02..e34a7a89 100644 --- a/chrome/test/data/policy/policy_test_cases.json +++ b/chrome/test/data/policy/policy_test_cases.json
@@ -4086,6 +4086,23 @@ "WebAppInstallForceList": { }, + "PluginVmAllowed": { + "os": ["chromeos"], + "test_policy": { "PluginVmAllowed": true }, + "pref_mappings": [] + }, + + "PluginVmImage": { + "os": ["chromeos"], + "test_policy": { + "PluginVmImage": { + "url": "http://localhost/", + "hash": "842841a4c75a55ad050d686f4ea5f77e83ae059877fe9b6946aa63d3d057ed32" + } + }, + "pref_mappings": [] + }, + "----- Chrome Frame policies -------------------------------------------": {}, "ChromeFrameRendererSettings": {
diff --git a/components/autofill/content/renderer/form_cache.cc b/components/autofill/content/renderer/form_cache.cc index b40e25d..cdb343ce 100644 --- a/components/autofill/content/renderer/form_cache.cc +++ b/components/autofill/content/renderer/form_cache.cc
@@ -472,8 +472,15 @@ title += "\nform signature: "; title += form.signature; + // Set this debug string to the title so that a developer can easily debug + // by hovering the mouse over the input field. element.SetAttribute("title", WebString::FromUTF8(title)); + // Set the same debug string to an attribute that does not get mangled if + // Google Translate is triggered for the site. This is useful for + // automated processing of the data. + element.SetAttribute("autofill-information", WebString::FromUTF8(title)); + element.SetAttribute("autofill-prediction", WebString::FromUTF8(field.overall_type)); }
diff --git a/components/autofill_assistant/browser/actions/get_payment_information_action.cc b/components/autofill_assistant/browser/actions/get_payment_information_action.cc index 2cc9add..5498cc4 100644 --- a/components/autofill_assistant/browser/actions/get_payment_information_action.cc +++ b/components/autofill_assistant/browser/actions/get_payment_information_action.cc
@@ -12,6 +12,7 @@ #include "components/autofill/core/browser/autofill_data_util.h" #include "components/autofill/core/browser/autofill_profile.h" #include "components/autofill/core/browser/credit_card.h" +#include "components/autofill/core/browser/personal_data_manager.h" #include "components/autofill_assistant/browser/actions/action_delegate.h" #include "components/autofill_assistant/browser/client_memory.h" #include "third_party/blink/public/mojom/payments/payment_request.mojom.h" @@ -82,10 +83,17 @@ } if (!get_payment_information.shipping_address_name().empty()) { - DCHECK(payment_information->address); + DCHECK(payment_information->shipping_address); delegate->GetClientMemory()->set_selected_address( get_payment_information.shipping_address_name(), - std::move(payment_information->address)); + std::move(payment_information->shipping_address)); + } + + if (!get_payment_information.billing_address_name().empty()) { + DCHECK(payment_information->billing_address); + delegate->GetClientMemory()->set_selected_address( + get_payment_information.billing_address_name(), + std::move(payment_information->billing_address)); } if (get_payment_information.has_contact_details()) {
diff --git a/components/autofill_assistant/browser/payment_information.h b/components/autofill_assistant/browser/payment_information.h index 4344a55f5..d4ffdf0d 100644 --- a/components/autofill_assistant/browser/payment_information.h +++ b/components/autofill_assistant/browser/payment_information.h
@@ -21,7 +21,8 @@ bool succeed; std::unique_ptr<autofill::CreditCard> card; - std::unique_ptr<autofill::AutofillProfile> address; + std::unique_ptr<autofill::AutofillProfile> shipping_address; + std::unique_ptr<autofill::AutofillProfile> billing_address; std::string payer_name; std::string payer_phone; std::string payer_email;
diff --git a/components/consent_auditor/consent_sync_bridge_impl.cc b/components/consent_auditor/consent_sync_bridge_impl.cc index f2d3cedaa..cb4ee3b 100644 --- a/components/consent_auditor/consent_sync_bridge_impl.cc +++ b/components/consent_auditor/consent_sync_bridge_impl.cc
@@ -248,8 +248,6 @@ return; } - // TODO(vitaliii): Garbage collect old consents if sync is disabled. - store_ = std::move(store); store_->ReadAllMetadata( base::BindOnce(&ConsentSyncBridgeImpl::OnReadAllMetadata,
diff --git a/components/history/core/browser/expire_history_backend.cc b/components/history/core/browser/expire_history_backend.cc index be43789..1f957507 100644 --- a/components/history/core/browser/expire_history_backend.cc +++ b/components/history/core/browser/expire_history_backend.cc
@@ -380,7 +380,9 @@ const DeletionTimeRange& time_range, base::Optional<std::set<GURL>> restrict_urls) { if (!effects->modified_urls.empty()) { - notifier_->NotifyURLsModified(effects->modified_urls); + notifier_->NotifyURLsModified( + effects->modified_urls, + /*is_from_expiration=*/type == DELETION_EXPIRED); } if (!effects->deleted_urls.empty() || time_range.IsValid()) { notifier_->NotifyURLsDeleted(DeletionInfo(
diff --git a/components/history/core/browser/expire_history_backend_unittest.cc b/components/history/core/browser/expire_history_backend_unittest.cc index c0422c5..f3cc09e 100644 --- a/components/history/core/browser/expire_history_backend_unittest.cc +++ b/components/history/core/browser/expire_history_backend_unittest.cc
@@ -113,7 +113,8 @@ // Returns whether HistoryBackendNotifier::NotifyURLsModified was // called for |url|. - bool ModifiedNotificationSent(const GURL& url); + bool ModifiedNotificationSentDueToExpiry(const GURL& url); + bool ModifiedNotificationSentDueToUserAction(const GURL& url); // Clears the list of notifications received. void ClearLastNotifications() { @@ -146,7 +147,7 @@ // base::Time at the beginning of the test, so everybody agrees what "now" is. const base::Time now_; - typedef std::vector<URLRows> URLsModifiedNotificationList; + typedef std::vector<std::pair<bool, URLRows>> URLsModifiedNotificationList; URLsModifiedNotificationList urls_modified_notifications_; typedef std::vector<DeletionInfo> URLsDeletedNotificationList; @@ -197,6 +198,9 @@ pref_service_.reset(); } + bool ModifiedNotificationSent(const GURL& url, + bool should_be_from_expiration); + // HistoryBackendNotifier: void NotifyFaviconsChanged(const std::set<GURL>& page_urls, const GURL& icon_url) override {} @@ -204,8 +208,10 @@ const URLRow& row, const RedirectList& redirects, base::Time visit_time) override {} - void NotifyURLsModified(const URLRows& rows) override { - urls_modified_notifications_.push_back(rows); + void NotifyURLsModified(const URLRows& rows, + bool is_from_expiration) override { + urls_modified_notifications_.push_back( + std::make_pair(is_from_expiration, rows)); } void NotifyURLsDeleted(DeletionInfo deletion_info) override { urls_deleted_notifications_.push_back(std::move(deletion_info)); @@ -385,7 +391,8 @@ found_delete_notification = true; } } - for (const auto& rows : urls_modified_notifications_) { + for (const auto& pair : urls_modified_notifications_) { + const auto& rows = pair.second; EXPECT_TRUE(std::find_if(rows.begin(), rows.end(), history::URLRow::URLRowHasURL(row.url())) == rows.end()); @@ -393,11 +400,27 @@ EXPECT_TRUE(found_delete_notification); } -bool ExpireHistoryTest::ModifiedNotificationSent(const GURL& url) { - for (const auto& rows : urls_modified_notifications_) { - if (std::find_if(rows.begin(), rows.end(), - history::URLRow::URLRowHasURL(url)) != rows.end()) +bool ExpireHistoryTest::ModifiedNotificationSentDueToExpiry(const GURL& url) { + return ModifiedNotificationSent(url, + /*should_be_from_expiration=*/true); +} +bool ExpireHistoryTest::ModifiedNotificationSentDueToUserAction( + const GURL& url) { + return ModifiedNotificationSent(url, + /*should_be_from_expiration=*/false); +} + +bool ExpireHistoryTest::ModifiedNotificationSent( + const GURL& url, + bool should_be_from_expiration) { + for (const auto& pair : urls_modified_notifications_) { + const bool is_from_expiration = pair.first; + const auto& rows = pair.second; + if (is_from_expiration == should_be_from_expiration && + std::find_if(rows.begin(), rows.end(), + history::URLRow::URLRowHasURL(url)) != rows.end()) { return true; + } } return false; } @@ -630,7 +653,7 @@ EXPECT_EQ(1U, visits.size()); // Verify that the middle URL visit time and visit counts were updated. - EXPECT_TRUE(ModifiedNotificationSent(url_row1.url())); + EXPECT_TRUE(ModifiedNotificationSentDueToUserAction(url_row1.url())); URLRow temp_row; ASSERT_TRUE(main_db_->GetURLRow(url_ids[1], &temp_row)); EXPECT_TRUE(visit_times[2] == url_row1.last_visit()); // Previous value. @@ -732,7 +755,7 @@ EXPECT_EQ(1U, visits.size()); // Verify that the middle URL visit time and visit counts were updated. - EXPECT_TRUE(ModifiedNotificationSent(url_row1.url())); + EXPECT_TRUE(ModifiedNotificationSentDueToUserAction(url_row1.url())); URLRow temp_row; ASSERT_TRUE(main_db_->GetURLRow(url_ids[1], &temp_row)); EXPECT_TRUE(visit_times[2] == url_row1.last_visit()); // Previous value. @@ -820,7 +843,7 @@ EXPECT_EQ(1U, visits.size()); // Verify that the middle URL visit time and visit counts were updated. - EXPECT_TRUE(ModifiedNotificationSent(url_row1.url())); + EXPECT_TRUE(ModifiedNotificationSentDueToUserAction(url_row1.url())); URLRow temp_row; ASSERT_TRUE(main_db_->GetURLRow(url_ids[1], &temp_row)); EXPECT_TRUE(visit_times[2] == url_row1.last_visit()); // Previous value. @@ -874,7 +897,7 @@ EXPECT_EQ(1U, visits.size()); // Verify that the middle URL visit time and visit counts were updated. - EXPECT_TRUE(ModifiedNotificationSent(url_row1.url())); + EXPECT_TRUE(ModifiedNotificationSentDueToUserAction(url_row1.url())); URLRow temp_row; ASSERT_TRUE(main_db_->GetURLRow(url_ids[1], &temp_row)); EXPECT_TRUE(visit_times[2] == url_row1.last_visit()); // Previous value. @@ -926,8 +949,8 @@ EXPECT_TRUE(new_url_row2.last_visit().is_null()); // No last visit time. // Visit/typed count should be updated. - EXPECT_TRUE(ModifiedNotificationSent(url_row1.url())); - EXPECT_TRUE(ModifiedNotificationSent(url_row2.url())); + EXPECT_TRUE(ModifiedNotificationSentDueToUserAction(url_row1.url())); + EXPECT_TRUE(ModifiedNotificationSentDueToUserAction(url_row2.url())); EXPECT_EQ(0, new_url_row1.typed_count()); EXPECT_EQ(1, new_url_row1.visit_count()); EXPECT_EQ(0, new_url_row2.typed_count()); @@ -967,7 +990,7 @@ URLRow temp_row; EnsureURLInfoGone(url_row0, true); EXPECT_TRUE(main_db_->GetURLRow(url_ids[1], &temp_row)); - EXPECT_TRUE(ModifiedNotificationSent(url_row1.url())); + EXPECT_TRUE(ModifiedNotificationSentDueToExpiry(url_row1.url())); VisitVector visits; main_db_->GetVisitsForURL(temp_row.id(), &visits); EXPECT_EQ(1U, visits.size()); @@ -1004,19 +1027,19 @@ URLRow temp_row; ASSERT_TRUE(main_db_->GetURLRow(url_ids[0], &temp_row)); - EXPECT_TRUE(ModifiedNotificationSent(url_row0.url())); + EXPECT_TRUE(ModifiedNotificationSentDueToExpiry(url_row0.url())); VisitVector visits; main_db_->GetVisitsForURL(temp_row.id(), &visits); EXPECT_EQ(0U, visits.size()); ASSERT_TRUE(main_db_->GetURLRow(url_ids[1], &temp_row)); - EXPECT_TRUE(ModifiedNotificationSent(url_row1.url())); + EXPECT_TRUE(ModifiedNotificationSentDueToExpiry(url_row1.url())); main_db_->GetVisitsForURL(temp_row.id(), &visits); EXPECT_EQ(0U, visits.size()); // The third URL should be unchanged. EXPECT_TRUE(main_db_->GetURLRow(url_ids[2], &temp_row)); - EXPECT_FALSE(ModifiedNotificationSent(temp_row.url())); + EXPECT_FALSE(ModifiedNotificationSentDueToExpiry(temp_row.url())); main_db_->GetVisitsForURL(temp_row.id(), &visits); EXPECT_EQ(1U, visits.size()); }
diff --git a/components/history/core/browser/history_backend.cc b/components/history/core/browser/history_backend.cc index 7b7dd85..00cf677 100644 --- a/components/history/core/browser/history_backend.cc +++ b/components/history/core/browser/history_backend.cc
@@ -915,7 +915,7 @@ // // TODO(brettw) bug 1140015: Add an "add page" notification so the history // views can keep in sync. - NotifyURLsModified(changed_urls); + NotifyURLsModified(changed_urls, /*is_from_expiration=*/false); ScheduleCommit(); } @@ -961,7 +961,7 @@ // Broadcast notifications for any URLs that have changed. This will // update the in-memory database and the InMemoryURLIndex. if (!changed_urls.empty()) { - NotifyURLsModified(changed_urls); + NotifyURLsModified(changed_urls, /*is_from_expiration=*/false); ScheduleCommit(); } } @@ -1037,7 +1037,7 @@ // will update the in-memory database and the InMemoryURLIndex. size_t num_updated_records = changed_urls.size(); if (num_updated_records) { - NotifyURLsModified(changed_urls); + NotifyURLsModified(changed_urls, /*is_from_expiration=*/false); ScheduleCommit(); } return num_updated_records; @@ -2641,12 +2641,13 @@ delegate_->NotifyURLVisited(transition, row, redirects, visit_time); } -void HistoryBackend::NotifyURLsModified(const URLRows& rows) { +void HistoryBackend::NotifyURLsModified(const URLRows& changed_urls, + bool is_from_expiration) { for (HistoryBackendObserver& observer : observers_) - observer.OnURLsModified(this, rows); + observer.OnURLsModified(this, changed_urls, is_from_expiration); if (delegate_) - delegate_->NotifyURLsModified(rows); + delegate_->NotifyURLsModified(changed_urls); } void HistoryBackend::NotifyURLsDeleted(DeletionInfo deletion_info) {
diff --git a/components/history/core/browser/history_backend.h b/components/history/core/browser/history_backend.h index d4c6cd6..c64e3c2 100644 --- a/components/history/core/browser/history_backend.h +++ b/components/history/core/browser/history_backend.h
@@ -820,7 +820,8 @@ const URLRow& row, const RedirectList& redirects, base::Time visit_time) override; - void NotifyURLsModified(const URLRows& rows) override; + void NotifyURLsModified(const URLRows& changed_urls, + bool is_from_expiration) override; void NotifyURLsDeleted(DeletionInfo deletion_info) override; // Deleting all history ------------------------------------------------------
diff --git a/components/history/core/browser/history_backend_notifier.h b/components/history/core/browser/history_backend_notifier.h index 9ede9c0b..17444c64 100644 --- a/components/history/core/browser/history_backend_notifier.h +++ b/components/history/core/browser/history_backend_notifier.h
@@ -37,7 +37,8 @@ base::Time visit_time) = 0; // Sends notification that |changed_urls| have been changed or added. - virtual void NotifyURLsModified(const URLRows& changed_urls) = 0; + virtual void NotifyURLsModified(const URLRows& changed_urls, + bool is_from_expiration) = 0; // Sends notification that some or the totality of the URLs have been // deleted.
diff --git a/components/history/core/browser/history_backend_observer.h b/components/history/core/browser/history_backend_observer.h index 80160923..f0e905ad 100644 --- a/components/history/core/browser/history_backend_observer.h +++ b/components/history/core/browser/history_backend_observer.h
@@ -34,9 +34,12 @@ // // |changed_urls| lists the information for each of the URLs affected. The // rows will have the IDs that are currently in effect in the main history - // database. + // database. |is_from_expiration| is true if the modification is caused by + // automatic history expiration (the visit count got reduced by expiring some + // of the visits); it is false if the modification is caused by user action. virtual void OnURLsModified(HistoryBackend* history_backend, - const URLRows& changed_urls) = 0; + const URLRows& changed_urls, + bool is_from_expiration) = 0; // Called when one or more of URLs are deleted. //
diff --git a/components/history/core/browser/sync/typed_url_sync_bridge.cc b/components/history/core/browser/sync/typed_url_sync_bridge.cc index 261bece..de78373 100644 --- a/components/history/core/browser/sync/typed_url_sync_bridge.cc +++ b/components/history/core/browser/sync/typed_url_sync_bridge.cc
@@ -366,7 +366,8 @@ } void TypedURLSyncBridge::OnURLsModified(HistoryBackend* history_backend, - const URLRows& changed_urls) { + const URLRows& changed_urls, + bool is_from_expiration) { DCHECK(sequence_checker_.CalledOnValidSequence()); DCHECK(sync_metadata_database_);
diff --git a/components/history/core/browser/sync/typed_url_sync_bridge.h b/components/history/core/browser/sync/typed_url_sync_bridge.h index 35e1939..d7da6da 100644 --- a/components/history/core/browser/sync/typed_url_sync_bridge.h +++ b/components/history/core/browser/sync/typed_url_sync_bridge.h
@@ -55,7 +55,8 @@ const RedirectList& redirects, base::Time visit_time) override; void OnURLsModified(HistoryBackend* history_backend, - const URLRows& changed_urls) override; + const URLRows& changed_urls, + bool is_from_expiration) override; void OnURLsDeleted(HistoryBackend* history_backend, bool all_history, bool expired,
diff --git a/components/history/core/browser/sync/typed_url_sync_bridge_unittest.cc b/components/history/core/browser/sync/typed_url_sync_bridge_unittest.cc index f0b9eb5a..360f58a 100644 --- a/components/history/core/browser/sync/typed_url_sync_bridge_unittest.cc +++ b/components/history/core/browser/sync/typed_url_sync_bridge_unittest.cc
@@ -291,7 +291,8 @@ changed_urls.push_back(rows->back()); } - bridge()->OnURLsModified(fake_history_backend_.get(), changed_urls); + bridge()->OnURLsModified(fake_history_backend_.get(), changed_urls, + /*is_from_expiration=*/false); } // Check that communication with sync was successful. @@ -843,7 +844,8 @@ // Notify typed url sync service of the update. const auto& changes_multimap = processor().put_multimap(); ASSERT_EQ(0U, changes_multimap.size()); - bridge()->OnURLsModified(fake_history_backend_.get(), changed_urls); + bridge()->OnURLsModified(fake_history_backend_.get(), changed_urls, + /*is_from_expiration=*/false); ASSERT_EQ(1U, changes_multimap.size()); sync_pb::TypedUrlSpecifics url_specifics = GetLastUpdateForURL(kURL); @@ -1633,7 +1635,8 @@ changed_urls.push_back(row); // Notify typed url sync service of the update. - bridge()->OnURLsModified(fake_history_backend_.get(), changed_urls); + bridge()->OnURLsModified(fake_history_backend_.get(), changed_urls, + /*is_from_expiration=*/false); // Check change processor did not receive expired typed URL. ASSERT_EQ(1U, changes_multimap.size());
diff --git a/components/plugins/renderer/webview_plugin.cc b/components/plugins/renderer/webview_plugin.cc index 54dff8d..ebb72780 100644 --- a/components/plugins/renderer/webview_plugin.cc +++ b/components/plugins/renderer/webview_plugin.cc
@@ -139,8 +139,9 @@ return delegate_->GetV8ScriptableObject(isolate); } -void WebViewPlugin::UpdateAllLifecyclePhases() { - web_view()->MainFrameWidget()->UpdateAllLifecyclePhases(); +void WebViewPlugin::UpdateAllLifecyclePhases( + blink::WebWidget::LifecycleUpdateReason reason) { + web_view()->MainFrameWidget()->UpdateAllLifecyclePhases(reason); } bool WebViewPlugin::IsErrorPlaceholder() { @@ -402,5 +403,6 @@ // The delegate may have dirtied style and layout of the WebView. // See for example the resizePoster function in plugin_poster.html. // Run the lifecycle now so that it is clean. - web_view()->MainFrameWidget()->UpdateAllLifecyclePhases(); + web_view()->MainFrameWidget()->UpdateAllLifecyclePhases( + blink::WebWidget::LifecycleUpdateReason::kOther); }
diff --git a/components/plugins/renderer/webview_plugin.h b/components/plugins/renderer/webview_plugin.h index 2226b848..015ed87 100644 --- a/components/plugins/renderer/webview_plugin.h +++ b/components/plugins/renderer/webview_plugin.h
@@ -90,7 +90,8 @@ bool IsErrorPlaceholder() override; - void UpdateAllLifecyclePhases() override; + void UpdateAllLifecyclePhases( + blink::WebWidget::LifecycleUpdateReason reason) override; void Paint(cc::PaintCanvas* canvas, const blink::WebRect& rect) override; // Coordinates are relative to the containing window.
diff --git a/components/policy/proto/chrome_device_policy.proto b/components/policy/proto/chrome_device_policy.proto index ced883c..d7ae0b5 100644 --- a/components/policy/proto/chrome_device_policy.proto +++ b/components/policy/proto/chrome_device_policy.proto
@@ -848,7 +848,7 @@ repeated string login_screen_input_methods = 1; } -// The url and hash that specified in JSON format that can be used to set the +// The url and hash specified in JSON format that can be used to set the // device-level wallpaper on the login screen before any user logs in. message DeviceWallpaperImageProto { optional string device_wallpaper_image = 1; @@ -936,7 +936,7 @@ repeated int32 ignored_policy_proto_tags = 3; } -// The url and hash that specified in JSON format that can be used to retrieve +// The url and hash specified in JSON format that can be used to retrieve // the device-level printers configuration file. message DeviceNativePrintersProto { // External policy blob encoded as JSON. @@ -1091,6 +1091,17 @@ optional bool device_unaffiliated_crostini_allowed = 1; } +// Setting that controls whether PluginVm is allowed to run on this device. +message PluginVmAllowedProto { + optional bool plugin_vm_allowed = 1; +} + +// The url and hash specified in JSON format that can be used to set the +// device-level PluginVm image. +message PluginVmImageProto { + optional string plugin_vm_image = 1; +} + message ChromeDeviceSettingsProto { reserved 61; optional DevicePolicyRefreshRateProto device_policy_refresh_rate = 1; @@ -1186,4 +1197,6 @@ optional DeviceWiFiFastTransitionEnabledProto device_wifi_fast_transition_enabled = 73; optional DeviceDisplayResolutionProto device_display_resolution = 74; + optional PluginVmAllowedProto plugin_vm_allowed = 75; + optional PluginVmImageProto plugin_vm_image = 76; }
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index f5dd806..38f21fc 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -1626,7 +1626,7 @@ 'caption': '''Monochrome printing only''', }, ], - 'supported_on': ['chrome_os:70-'], + 'supported_on': ['chrome_os:71-'], 'features': { 'can_be_recommended': False, 'dynamic_refresh': True, @@ -1734,7 +1734,6 @@ }, ], 'supported_on': ['chrome_os:72-'], - 'future': True, 'features': { 'can_be_recommended': False, 'dynamic_refresh': True, @@ -1775,7 +1774,6 @@ }, ], 'supported_on': ['chrome_os:72-'], - 'future': True, 'features': { 'can_be_recommended': False, 'dynamic_refresh': True, @@ -13888,7 +13886,68 @@ their settings will be overriden by the policy value at the next reboot. If "recommended" flag is set to false or not set, users can't change the display settings.''', - } + }, + { + 'name': 'PluginVm', + 'type': 'group', + 'caption': '''PluginVm''', + 'policies': [ + 'PluginVmAllowed', + 'PluginVmImage', + ], + 'desc': '''This is a group policy for PluginVm related policies.''', + }, + { + 'name': 'PluginVmAllowed', + 'type': 'main', + 'schema': { 'type': 'boolean' }, + 'supported_on': ['chrome_os:72-'], + 'device_only': True, + 'features': { + 'dynamic_refresh': True, + }, + 'example_value': True, + 'id': 503, + 'caption': '''Device is enabled to run PluginVm''', + 'tags': [], + 'desc': '''Enable this device to run PluginVm. + + If the policy is set to false or left unset, PluginVm is not enabled for the device. + If set to true, PluginVm is enabled for the device as long as other settings also allow it. + PluginVmAllowed needs to be true and PluginVmImage needs to be set for PluginVm to be allowed to run.''', + }, + { + 'name': 'PluginVmImage', + 'type': 'dict', + 'schema': { + 'type': 'object', + 'properties': { + 'url': { + 'description': 'The URL from which the PluginVm image can be downloaded.', + 'type': 'string' + }, + 'hash': { + 'description': 'The SHA-256 hash of the PluginVm image.', + 'type': 'string' + } + }, + }, + 'supported_on': ['chrome_os:72-'], + 'device_only': True, + 'features': { + 'dynamic_refresh': True, + }, + 'example_value': { + "url": "https://example.com/plugin_vm_image", + "hash": "842841a4c75a55ad050d686f4ea5f77e83ae059877fe9b6946aa63d3d057ed32" + }, + 'id': 504, + 'caption': '''PluginVm image''', + 'tags': [], + 'desc': '''Configure device-level PluginVm image. The policy is set by specifying the URL from which the Chrome OS device can download the image and a SHA-256 hash used to verify the integrity of the download. + + The policy should be specified as a string that expresses the URL and hash in the JSON format.''', + }, ], 'messages': { @@ -14030,5 +14089,5 @@ }, 'placeholders': [], 'deleted_policy_ids': [412], - 'highest_id_currently_used': 502 + 'highest_id_currently_used': 504 }
diff --git a/components/signin/core/browser/BUILD.gn b/components/signin/core/browser/BUILD.gn index 0f9812f..999bd69 100644 --- a/components/signin/core/browser/BUILD.gn +++ b/components/signin/core/browser/BUILD.gn
@@ -24,6 +24,8 @@ sources = [ "account_info.cc", "account_info.h", + "identity_utils.cc", + "identity_utils.h", "signin_metrics.cc", "signin_metrics.h", "signin_pref_names.cc", @@ -34,6 +36,7 @@ deps = [ ":signin_buildflags", "//components/account_id", + "//third_party/icu:icui18n", ] public_deps = [ "//base", @@ -272,6 +275,7 @@ "device_id_helper_unittest.cc", "dice_account_reconcilor_delegate_unittest.cc", "gaia_cookie_manager_service_unittest.cc", + "identity_utils_unittest.cc", "signin_error_controller_unittest.cc", "signin_header_helper_unittest.cc", "signin_investigator_unittest.cc",
diff --git a/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerFacade.java b/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerFacade.java index 0a378288..5f4cc8d 100644 --- a/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerFacade.java +++ b/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerFacade.java
@@ -33,6 +33,8 @@ import org.chromium.net.NetworkChangeNotifier; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.concurrent.CountDownLatch; @@ -83,9 +85,9 @@ // These two variables should be accessed from either UI thread or during initialization phase. private PatternMatcher[] mAccountRestrictionPatterns; - private AccountManagerResult<Account[]> mAllAccounts; + private AccountManagerResult<List<Account>> mAllAccounts; - private final AtomicReference<AccountManagerResult<Account[]>> mFilteredAccounts = + private final AtomicReference<AccountManagerResult<List<Account>>> mFilteredAccounts = new AtomicReference<>(); private final CountDownLatch mPopulateAccountCacheLatch = new CountDownLatch(1); private final CachedMetrics.TimesHistogramSample mPopulateAccountCacheWaitingTimeHistogram = @@ -270,7 +272,9 @@ @AnyThread public List<String> tryGetGoogleAccountNames() { List<String> accountNames = new ArrayList<>(); - for (Account account : tryGetGoogleAccounts()) { + List<Account> tryGetGoogleAccounts = tryGetGoogleAccounts(); + for (int i = 0; i < tryGetGoogleAccounts.size(); i++) { + Account account = tryGetGoogleAccounts.get(i); accountNames.add(account.name); } return accountNames; @@ -291,10 +295,10 @@ public void getGoogleAccountNames( final Callback<AccountManagerResult<List<String>>> callback) { runAfterCacheIsPopulated(() -> { - final AccountManagerResult<Account[]> accounts = mFilteredAccounts.get(); + final AccountManagerResult<List<Account>> accounts = mFilteredAccounts.get(); final AccountManagerResult<List<String>> result; if (accounts.hasValue()) { - List<String> accountNames = new ArrayList<>(accounts.getValue().length); + List<String> accountNames = new ArrayList<>(accounts.getValue().size()); for (Account account : accounts.getValue()) { accountNames.add(account.name); } @@ -313,8 +317,8 @@ * Chrome lacks necessary permissions, etc. */ @AnyThread - public Account[] getGoogleAccounts() throws AccountManagerDelegateException { - AccountManagerResult<Account[]> maybeAccounts = mFilteredAccounts.get(); + public List<Account> getGoogleAccounts() throws AccountManagerDelegateException { + AccountManagerResult<List<Account>> maybeAccounts = mFilteredAccounts.get(); if (maybeAccounts == null) { try { // First call to update hasn't finished executing yet, should wait for it @@ -336,7 +340,7 @@ * Asynchronous version of {@link #getGoogleAccounts()}. */ @MainThread - public void getGoogleAccounts(final Callback<AccountManagerResult<Account[]>> callback) { + public void getGoogleAccounts(Callback<AccountManagerResult<List<Account>>> callback) { runAfterCacheIsPopulated(() -> callback.onResult(mFilteredAccounts.get())); } @@ -345,11 +349,11 @@ * Returns an empty array if an error occurs while getting account list. */ @AnyThread - public Account[] tryGetGoogleAccounts() { + public List<Account> tryGetGoogleAccounts() { try { return getGoogleAccounts(); } catch (AccountManagerDelegateException e) { - return new Account[0]; + return Collections.emptyList(); } } @@ -357,7 +361,7 @@ * Asynchronous version of {@link #tryGetGoogleAccounts()}. */ @MainThread - public void tryGetGoogleAccounts(final Callback<Account[]> callback) { + public void tryGetGoogleAccounts(final Callback<List<Account>> callback) { runAfterCacheIsPopulated(() -> callback.onResult(tryGetGoogleAccounts())); } @@ -367,7 +371,7 @@ */ @AnyThread public boolean hasGoogleAccounts() { - return tryGetGoogleAccounts().length > 0; + return !tryGetGoogleAccounts().isEmpty(); } /** @@ -398,7 +402,7 @@ @AnyThread public Account getAccountFromName(String accountName) { String canonicalName = canonicalizeName(accountName); - Account[] accounts = tryGetGoogleAccounts(); + List<Account> accounts = tryGetGoogleAccounts(); for (Account account : accounts) { if (canonicalizeName(account.name).equals(canonicalName)) { return account; @@ -615,15 +619,16 @@ ContextUtils.getApplicationContext().registerReceiver(receiver, filter); } - private AccountManagerResult<Account[]> getAllAccounts() { + private AccountManagerResult<List<Account>> getAllAccounts() { try { - return new AccountManagerResult<>(mDelegate.getAccountsSync()); + List<Account> accounts = Arrays.asList(mDelegate.getAccountsSync()); + return new AccountManagerResult<>(Collections.unmodifiableList(accounts)); } catch (AccountManagerDelegateException ex) { return new AccountManagerResult<>(ex); } } - private AccountManagerResult<Account[]> getFilteredAccounts() { + private AccountManagerResult<List<Account>> getFilteredAccounts() { if (mAllAccounts.hasException() || mAccountRestrictionPatterns == null) return mAllAccounts; ArrayList<Account> filteredAccounts = new ArrayList<>(); for (Account account : mAllAccounts.getValue()) { @@ -634,7 +639,7 @@ } } } - return new AccountManagerResult<>(filteredAccounts.toArray(new Account[0])); + return new AccountManagerResult<>(Collections.unmodifiableList(filteredAccounts)); } private static PatternMatcher[] getAccountRestrictionPatterns() { @@ -673,7 +678,7 @@ fireOnAccountsChangedNotification(); } - private void setAllAccounts(AccountManagerResult<Account[]> allAccounts) { + private void setAllAccounts(AccountManagerResult<List<Account>> allAccounts) { mAllAccounts = allAccounts; mFilteredAccounts.set(getFilteredAccounts()); fireOnAccountsChangedNotification(); @@ -741,19 +746,19 @@ } } - private class UpdateAccountsTask extends AsyncTask<AccountManagerResult<Account[]>> { + private class UpdateAccountsTask extends AsyncTask<AccountManagerResult<List<Account>>> { @Override protected void onPreExecute() { ++mUpdateTasksCounter; } @Override - protected AccountManagerResult<Account[]> doInBackground() { + protected AccountManagerResult<List<Account>> doInBackground() { return getAllAccounts(); } @Override - protected void onPostExecute(AccountManagerResult<Account[]> allAccounts) { + protected void onPostExecute(AccountManagerResult<List<Account>> allAccounts) { setAllAccounts(allAccounts); decrementUpdateCounter(); }
diff --git a/components/signin/core/browser/android/junit/src/org/chromium/components/signin/test/AccountManagerFacadeRobolectricTest.java b/components/signin/core/browser/android/junit/src/org/chromium/components/signin/test/AccountManagerFacadeRobolectricTest.java index 5eaf1fa3..00795ee 100644 --- a/components/signin/core/browser/android/junit/src/org/chromium/components/signin/test/AccountManagerFacadeRobolectricTest.java +++ b/components/signin/core/browser/android/junit/src/org/chromium/components/signin/test/AccountManagerFacadeRobolectricTest.java
@@ -14,6 +14,8 @@ import android.support.test.filters.SmallTest; import android.support.test.rule.UiThreadTestRule; +import com.google.common.collect.ImmutableList; + import org.junit.Assert; import org.junit.Before; import org.junit.Rule; @@ -22,7 +24,6 @@ import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; -import org.chromium.base.Callback; import org.chromium.base.task.test.CustomShadowAsyncTask; import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.components.signin.AccountManagerDelegateException; @@ -130,20 +131,20 @@ @Test @SmallTest public void testGetAccounts() throws AccountManagerDelegateException { - Assert.assertArrayEquals(new Account[] {}, mFacade.getGoogleAccounts()); + Assert.assertEquals(ImmutableList.of(), mFacade.getGoogleAccounts()); Account account = addTestAccount("test@gmail.com"); - Assert.assertArrayEquals(new Account[] {account}, mFacade.getGoogleAccounts()); + Assert.assertEquals(ImmutableList.of(account), mFacade.getGoogleAccounts()); Account account2 = addTestAccount("test2@gmail.com"); - Assert.assertArrayEquals(new Account[] {account, account2}, mFacade.getGoogleAccounts()); + Assert.assertEquals(ImmutableList.of(account, account2), mFacade.getGoogleAccounts()); Account account3 = addTestAccount("test3@gmail.com"); - Assert.assertArrayEquals( - new Account[] {account, account2, account3}, mFacade.getGoogleAccounts()); + Assert.assertEquals( + ImmutableList.of(account, account2, account3), mFacade.getGoogleAccounts()); removeTestAccount(account2); - Assert.assertArrayEquals(new Account[] {account, account3}, mFacade.getGoogleAccounts()); + Assert.assertEquals(ImmutableList.of(account, account3), mFacade.getGoogleAccounts()); } @Test @@ -151,19 +152,19 @@ public void testGetAccountsWithAccountPattern() throws AccountManagerDelegateException { setAccountRestrictionPatterns("*@example.com"); Account account = addTestAccount("test@example.com"); - Assert.assertArrayEquals(new Account[] {account}, mFacade.getGoogleAccounts()); + Assert.assertEquals(ImmutableList.of(account), mFacade.getGoogleAccounts()); addTestAccount("test@gmail.com"); // Doesn't match the pattern. - Assert.assertArrayEquals(new Account[] {account}, mFacade.getGoogleAccounts()); + Assert.assertEquals(ImmutableList.of(account), mFacade.getGoogleAccounts()); Account account2 = addTestAccount("test2@example.com"); - Assert.assertArrayEquals(new Account[] {account, account2}, mFacade.getGoogleAccounts()); + Assert.assertEquals(ImmutableList.of(account, account2), mFacade.getGoogleAccounts()); addTestAccount("test2@gmail.com"); // Doesn't match the pattern. - Assert.assertArrayEquals(new Account[] {account, account2}, mFacade.getGoogleAccounts()); + Assert.assertEquals(ImmutableList.of(account, account2), mFacade.getGoogleAccounts()); removeTestAccount(account); - Assert.assertArrayEquals(new Account[] {account2}, mFacade.getGoogleAccounts()); + Assert.assertEquals(ImmutableList.of(account2), mFacade.getGoogleAccounts()); } @Test @@ -172,44 +173,44 @@ setAccountRestrictionPatterns("test1@example.com", "test2@gmail.com"); addTestAccount("test@gmail.com"); // Doesn't match the pattern. addTestAccount("test@example.com"); // Doesn't match the pattern. - Assert.assertArrayEquals(new Account[] {}, mFacade.getGoogleAccounts()); + Assert.assertEquals(ImmutableList.of(), mFacade.getGoogleAccounts()); Account account = addTestAccount("test1@example.com"); - Assert.assertArrayEquals(new Account[] {account}, mFacade.getGoogleAccounts()); + Assert.assertEquals(ImmutableList.of(account), mFacade.getGoogleAccounts()); addTestAccount("test2@example.com"); // Doesn't match the pattern. - Assert.assertArrayEquals(new Account[] {account}, mFacade.getGoogleAccounts()); + Assert.assertEquals(ImmutableList.of(account), mFacade.getGoogleAccounts()); Account account2 = addTestAccount("test2@gmail.com"); - Assert.assertArrayEquals(new Account[] {account, account2}, mFacade.getGoogleAccounts()); + Assert.assertEquals(ImmutableList.of(account, account2), mFacade.getGoogleAccounts()); } @Test @SmallTest public void testGetAccountsWithAccountPatternsChange() throws AccountManagerDelegateException { - Assert.assertArrayEquals(new Account[] {}, mFacade.getGoogleAccounts()); + Assert.assertEquals(ImmutableList.of(), mFacade.getGoogleAccounts()); Account account = addTestAccount("test@gmail.com"); - Assert.assertArrayEquals(new Account[] {account}, mFacade.getGoogleAccounts()); + Assert.assertEquals(ImmutableList.of(account), mFacade.getGoogleAccounts()); Account account2 = addTestAccount("test2@example.com"); - Assert.assertArrayEquals(new Account[] {account, account2}, mFacade.getGoogleAccounts()); + Assert.assertEquals(ImmutableList.of(account, account2), mFacade.getGoogleAccounts()); Account account3 = addTestAccount("test3@gmail.com"); - Assert.assertArrayEquals( - new Account[] {account, account2, account3}, mFacade.getGoogleAccounts()); + Assert.assertEquals( + ImmutableList.of(account, account2, account3), mFacade.getGoogleAccounts()); setAccountRestrictionPatterns("test@gmail.com"); - Assert.assertArrayEquals(new Account[] {account}, mFacade.getGoogleAccounts()); + Assert.assertEquals(ImmutableList.of(account), mFacade.getGoogleAccounts()); setAccountRestrictionPatterns("*@example.com", "test3@gmail.com"); - Assert.assertArrayEquals(new Account[] {account2, account3}, mFacade.getGoogleAccounts()); + Assert.assertEquals(ImmutableList.of(account2, account3), mFacade.getGoogleAccounts()); removeTestAccount(account3); - Assert.assertArrayEquals(new Account[] {account2}, mFacade.getGoogleAccounts()); + Assert.assertEquals(ImmutableList.of(account2), mFacade.getGoogleAccounts()); clearAccountRestrictionPatterns(); - Assert.assertArrayEquals(new Account[] {account, account2}, mFacade.getGoogleAccounts()); + Assert.assertEquals(ImmutableList.of(account, account2), mFacade.getGoogleAccounts()); } @Test @@ -217,7 +218,7 @@ public void testGetAccountsMultipleMatchingPatterns() throws AccountManagerDelegateException { setAccountRestrictionPatterns("*@gmail.com", "test@gmail.com"); Account account = addTestAccount("test@gmail.com"); // Matches both patterns - Assert.assertArrayEquals(new Account[] {account}, mFacade.getGoogleAccounts()); + Assert.assertEquals(ImmutableList.of(account), mFacade.getGoogleAccounts()); } @Test @@ -256,12 +257,9 @@ private void assertChildAccountStatus( Account account, @ChildAccountStatus.Status Integer status) { final AtomicInteger callCount = new AtomicInteger(); - AccountManagerFacade.get().checkChildAccountStatus(account, new Callback<Integer>() { - @Override - public void onResult(@ChildAccountStatus.Status Integer result) { - callCount.incrementAndGet(); - Assert.assertEquals(result, status); - } + AccountManagerFacade.get().checkChildAccountStatus(account, result -> { + callCount.incrementAndGet(); + Assert.assertEquals(result, status); }); Assert.assertEquals(1, callCount.get()); }
diff --git a/components/signin/core/browser/identity_utils.cc b/components/signin/core/browser/identity_utils.cc new file mode 100644 index 0000000..2019357 --- /dev/null +++ b/components/signin/core/browser/identity_utils.cc
@@ -0,0 +1,49 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/signin/core/browser/identity_utils.h" + +#include <string> + +#include "base/strings/string_util.h" +#include "base/strings/utf_string_conversions.h" +#include "third_party/icu/source/i18n/unicode/regex.h" + +namespace identity { + +bool IsUsernameAllowedByPattern(base::StringPiece username, + base::StringPiece pattern) { + if (pattern.empty()) + return true; + + // Patterns like "*@foo.com" are not accepted by our regex engine (since they + // are not valid regular expressions - they should instead be ".*@foo.com"). + // For convenience, detect these patterns and insert a "." character at the + // front. + base::string16 utf16_pattern = base::UTF8ToUTF16(pattern); + if (utf16_pattern[0] == L'*') + utf16_pattern.insert(utf16_pattern.begin(), L'.'); + + // See if the username matches the policy-provided pattern. + UErrorCode status = U_ZERO_ERROR; + const icu::UnicodeString icu_pattern(FALSE, utf16_pattern.data(), + utf16_pattern.length()); + icu::RegexMatcher matcher(icu_pattern, UREGEX_CASE_INSENSITIVE, status); + if (!U_SUCCESS(status)) { + LOG(ERROR) << "Invalid login regex: " << utf16_pattern + << ", status: " << status; + // If an invalid pattern is provided, then prohibit *all* logins (better to + // break signin than to quietly allow users to sign in). + return false; + } + // The default encoding is UTF-8 in Chromium's ICU. + icu::UnicodeString icu_input(username.data()); + matcher.reset(icu_input); + status = U_ZERO_ERROR; + UBool match = matcher.matches(status); + DCHECK(U_SUCCESS(status)); + return !!match; // !! == convert from UBool to bool. +} + +} // namespace identity
diff --git a/components/signin/core/browser/identity_utils.h b/components/signin/core/browser/identity_utils.h new file mode 100644 index 0000000..7528847e --- /dev/null +++ b/components/signin/core/browser/identity_utils.h
@@ -0,0 +1,21 @@ +// 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. +// +// Collection of utility functions to support migrating different consumers of +// the SigninManager component to the Identity service, which will eventually be +// migrated to //services/identity once the SigninManager class gets removed. + +#ifndef COMPONENTS_SIGNIN_CORE_BROWSER_IDENTITY_UTILS_H_ +#define COMPONENTS_SIGNIN_CORE_BROWSER_IDENTITY_UTILS_H_ + +#include "base/strings/string_piece.h" + +namespace identity { + +// Returns true if the username is allowed based on the pattern string. +bool IsUsernameAllowedByPattern(base::StringPiece username, + base::StringPiece pattern); +} // namespace identity + +#endif // COMPONENTS_SIGNIN_CORE_BROWSER_IDENTITY_UTILS_H_
diff --git a/components/signin/core/browser/identity_utils_unittest.cc b/components/signin/core/browser/identity_utils_unittest.cc new file mode 100644 index 0000000..a1b81343 --- /dev/null +++ b/components/signin/core/browser/identity_utils_unittest.cc
@@ -0,0 +1,60 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/signin/core/browser/identity_utils.h" +#include "testing/gtest/include/gtest/gtest.h" + +class IdentityUtilsTest : public testing::Test {}; + +const char kUsername[] = "test@test.com"; + +const char kValidWildcardPattern[] = ".*@test.com"; +const char kInvalidWildcardPattern[] = "*@test.com"; + +const char kMatchingPattern1[] = "test@test.com"; +const char kMatchingPattern2[] = ".*@test.com"; +const char kMatchingPattern3[] = "test@.*.com"; +const char kMatchingPattern4[] = ".*@.*.com"; +const char kMatchingPattern5[] = ".*@.*"; +const char kMatchingPattern6[] = ".*"; + +const char kNonMatchingPattern[] = ".*foo.*"; +const char kNonMatchingUsernamePattern[] = "foo@test.com"; +const char kNonMatchingDomainPattern[] = "test@foo.com"; + +TEST_F(IdentityUtilsTest, IsUsernameAllowedByPattern_EmptyPatterns) { + EXPECT_TRUE(identity::IsUsernameAllowedByPattern(kUsername, "")); + EXPECT_FALSE(identity::IsUsernameAllowedByPattern(kUsername, " ")); +} + +TEST_F(IdentityUtilsTest, IsUsernameAllowedByPattern_InvalidWildcardPatterns) { + // identity::IsUsernameAllowedByPattern should recognize invalid wildcard + // patterns like "*@foo.com" and insert a "." before them automatically. + EXPECT_TRUE( + identity::IsUsernameAllowedByPattern(kUsername, kValidWildcardPattern)); + EXPECT_TRUE( + identity::IsUsernameAllowedByPattern(kUsername, kInvalidWildcardPattern)); +} + +TEST_F(IdentityUtilsTest, IsUsernameAllowedByPattern_MatchingWildcardPatterns) { + EXPECT_TRUE( + identity::IsUsernameAllowedByPattern(kUsername, kMatchingPattern1)); + EXPECT_TRUE( + identity::IsUsernameAllowedByPattern(kUsername, kMatchingPattern2)); + EXPECT_TRUE( + identity::IsUsernameAllowedByPattern(kUsername, kMatchingPattern3)); + EXPECT_TRUE( + identity::IsUsernameAllowedByPattern(kUsername, kMatchingPattern4)); + EXPECT_TRUE( + identity::IsUsernameAllowedByPattern(kUsername, kMatchingPattern5)); + EXPECT_TRUE( + identity::IsUsernameAllowedByPattern(kUsername, kMatchingPattern6)); + + EXPECT_FALSE( + identity::IsUsernameAllowedByPattern(kUsername, kNonMatchingPattern)); + EXPECT_FALSE(identity::IsUsernameAllowedByPattern( + kUsername, kNonMatchingUsernamePattern)); + EXPECT_FALSE(identity::IsUsernameAllowedByPattern(kUsername, + kNonMatchingDomainPattern)); +}
diff --git a/components/signin/core/browser/signin_manager.cc b/components/signin/core/browser/signin_manager.cc index 395f479..738def7 100644 --- a/components/signin/core/browser/signin_manager.cc +++ b/components/signin/core/browser/signin_manager.cc
@@ -15,6 +15,7 @@ #include "components/prefs/pref_service.h" #include "components/signin/core/browser/account_tracker_service.h" #include "components/signin/core/browser/gaia_cookie_manager_service.h" +#include "components/signin/core/browser/identity_utils.h" #include "components/signin/core/browser/signin_internals_util.h" #include "components/signin/core/browser/signin_metrics.h" #include "components/signin/core/browser/signin_pref_names.h" @@ -335,39 +336,6 @@ } // static -bool SigninManager::IsUsernameAllowedByPolicy(const std::string& username, - const std::string& policy) { - if (policy.empty()) - return true; - - // Patterns like "*@foo.com" are not accepted by our regex engine (since they - // are not valid regular expressions - they should instead be ".*@foo.com"). - // For convenience, detect these patterns and insert a "." character at the - // front. - base::string16 pattern = base::UTF8ToUTF16(policy); - if (pattern[0] == L'*') - pattern.insert(pattern.begin(), L'.'); - - // See if the username matches the policy-provided pattern. - UErrorCode status = U_ZERO_ERROR; - const icu::UnicodeString icu_pattern(FALSE, pattern.data(), pattern.length()); - icu::RegexMatcher matcher(icu_pattern, UREGEX_CASE_INSENSITIVE, status); - if (!U_SUCCESS(status)) { - LOG(ERROR) << "Invalid login regex: " << pattern << ", status: " << status; - // If an invalid pattern is provided, then prohibit *all* logins (better to - // break signin than to quietly allow users to sign in). - return false; - } - // The default encoding is UTF-8 in Chromium's ICU. - icu::UnicodeString icu_input(username.data()); - matcher.reset(icu_input); - status = U_ZERO_ERROR; - UBool match = matcher.matches(status); - DCHECK(U_SUCCESS(status)); - return !!match; // !! == convert from UBool to bool. -} - -// static SigninManager* SigninManager::FromSigninManagerBase( SigninManagerBase* manager) { return static_cast<SigninManager*>(manager); @@ -380,7 +348,7 @@ std::string pattern = local_state->GetString(prefs::kGoogleServicesUsernamePattern); - return IsUsernameAllowedByPolicy(username, pattern); + return identity::IsUsernameAllowedByPattern(username, pattern); } bool SigninManager::AuthInProgress() const { @@ -468,12 +436,10 @@ } void SigninManager::FireGoogleSigninSucceeded() { - std::string account_id = GetAuthenticatedAccountId(); - std::string email = GetAuthenticatedAccountInfo().email; + const AccountInfo account_info = GetAuthenticatedAccountInfo(); for (auto& observer : observer_list_) { - observer.GoogleSigninSucceeded(account_id, email); - observer.GoogleSigninSucceeded(GetAuthenticatedAccountInfo()); - observer.GoogleSigninSucceededWithPassword(account_id, email, password_); + observer.GoogleSigninSucceeded(account_info); + observer.GoogleSigninSucceededWithPassword(account_info, password_); } }
diff --git a/components/signin/core/browser/signin_manager.h b/components/signin/core/browser/signin_manager.h index 1aaeba46..836a9910 100644 --- a/components/signin/core/browser/signin_manager.h +++ b/components/signin/core/browser/signin_manager.h
@@ -31,6 +31,7 @@ #include "base/logging.h" #include "base/macros.h" #include "base/observer_list.h" +#include "base/strings/string_piece.h" #include "components/keyed_service/core/keyed_service.h" #include "components/prefs/pref_change_registrar.h" #include "components/prefs/pref_member.h" @@ -53,7 +54,7 @@ namespace identity { class IdentityManager; -} +} // namespace identity class SigninManager : public SigninManagerBase, public AccountTrackerService::Observer, @@ -90,10 +91,6 @@ signin::AccountConsistencyMethod account_consistency); ~SigninManager() override; - // Returns true if the username is allowed based on the policy string. - static bool IsUsernameAllowedByPolicy(const std::string& username, - const std::string& policy); - // Returns |manager| as a SigninManager instance. Relies on the fact that on // platforms where signin_manager.* is built, all SigninManagerBase instances // are actually SigninManager instances.
diff --git a/components/signin/core/browser/signin_manager_base.h b/components/signin/core/browser/signin_manager_base.h index d82f423..e010297 100644 --- a/components/signin/core/browser/signin_manager_base.h +++ b/components/signin/core/browser/signin_manager_base.h
@@ -44,10 +44,6 @@ class SigninClient; class SigninErrorController; -namespace password_manager { -class PasswordStoreSigninNotifierImpl; -} - class SigninManagerBase : public KeyedService { public: class Observer { @@ -59,9 +55,21 @@ // This method is not called during a reauth. virtual void GoogleSigninSucceeded(const AccountInfo& account_info) {} - // DEPRECATED: Use the above method instead. - virtual void GoogleSigninSucceeded(const std::string& account_id, - const std::string& username) {} + // Called when a user signs into Google services such as sync. Also passes + // the password of the Google account that was used to sign in. + // This method is not called during a reauth. + // + // Observers should override |GoogleSigninSucceeded| if they are not + // interested in the password thas was used during the sign-in. + // + // Note: The password is always empty on mobile as the user signs in to + // Chrome with accounts that were added to the device, so Chrome does not + // have access to the password. + // DEPRECATED: password will be empty if login is using DICE workflow; the + // method will be removed once all login is using the DICE workflow. + virtual void GoogleSigninSucceededWithPassword( + const AccountInfo& account_info, + const std::string& password) {} // Called when the currently signed-in user for a user has been signed out. virtual void GoogleSignedOut(const AccountInfo& account_info) {} @@ -74,29 +82,10 @@ virtual ~Observer() {} private: - // Observers that can observer the password of the Google account after a - // successful sign-in. - friend class PasswordStoreSigninNotifierImpl; - // SigninManagers that fire |GoogleSigninSucceededWithPassword| // notifications. friend class SigninManager; friend class FakeSigninManager; - - // Called when a user signs into Google services such as sync. Also passes - // the password of the Google account that was used to sign in. - // This method is not called during a reauth. - // - // Observers should override |GoogleSigninSucceeded| if they are not - // interested in the password thas was used during the sign-in. - // - // Note: The password is always empty on mobile as the user signs in to - // Chrome with accounts that were added to the device, so Chrome does not - // have access to the password. - virtual void GoogleSigninSucceededWithPassword( - const std::string& account_id, - const std::string& username, - const std::string& password) {} }; // On non-ChromeOS platforms, SigninManagerBase should only be instantiated
diff --git a/components/signin/core/browser/signin_manager_unittest.cc b/components/signin/core/browser/signin_manager_unittest.cc index 8c555177..740fb56 100644 --- a/components/signin/core/browser/signin_manager_unittest.cc +++ b/components/signin/core/browser/signin_manager_unittest.cc
@@ -56,13 +56,11 @@ num_failed_signins_++; } - void GoogleSigninSucceeded(const std::string& account_id, - const std::string& username) override { + void GoogleSigninSucceeded(const AccountInfo& account_info) override { num_successful_signins_++; } - void GoogleSigninSucceededWithPassword(const std::string& account_id, - const std::string& username, + void GoogleSigninSucceededWithPassword(const AccountInfo& account_info, const std::string& password) override { num_successful_signins_with_password_++; }
diff --git a/components/signin/core/browser/signin_status_metrics_provider.cc b/components/signin/core/browser/signin_status_metrics_provider.cc index 1b499cd3..d1ff779 100644 --- a/components/signin/core/browser/signin_status_metrics_provider.cc +++ b/components/signin/core/browser/signin_status_metrics_provider.cc
@@ -76,8 +76,7 @@ } void SigninStatusMetricsProvider::GoogleSigninSucceeded( - const std::string& account_id, - const std::string& username) { + const AccountInfo& account_info) { SigninStatus recorded_signin_status = signin_status(); if (recorded_signin_status == ALL_PROFILES_NOT_SIGNED_IN) { UpdateSigninStatus(MIXED_SIGNIN_STATUS);
diff --git a/components/signin/core/browser/signin_status_metrics_provider.h b/components/signin/core/browser/signin_status_metrics_provider.h index 73cd0a4..b9b5363 100644 --- a/components/signin/core/browser/signin_status_metrics_provider.h +++ b/components/signin/core/browser/signin_status_metrics_provider.h
@@ -69,8 +69,7 @@ bool is_test); // SigninManagerBase::Observer: - void GoogleSigninSucceeded(const std::string& account_id, - const std::string& username) override; + void GoogleSigninSucceeded(const AccountInfo& account_info) override; void GoogleSignedOut(const std::string& account_id, const std::string& username) override;
diff --git a/components/signin/core/browser/signin_status_metrics_provider_unittest.cc b/components/signin/core/browser/signin_status_metrics_provider_unittest.cc index ed1a8712..f56ff6d 100644 --- a/components/signin/core/browser/signin_status_metrics_provider_unittest.cc +++ b/components/signin/core/browser/signin_status_metrics_provider_unittest.cc
@@ -27,13 +27,13 @@ // Initial status is all signed out and then one of the profiles is signed in. metrics_provider.UpdateInitialSigninStatus(2, 0); - metrics_provider.GoogleSigninSucceeded(std::string(), std::string()); + metrics_provider.GoogleSigninSucceeded(AccountInfo()); EXPECT_EQ(SigninStatusMetricsProviderBase::MIXED_SIGNIN_STATUS, metrics_provider.GetSigninStatusForTesting()); // Initial status is mixed and then one of the profiles is signed in. metrics_provider.UpdateInitialSigninStatus(2, 1); - metrics_provider.GoogleSigninSucceeded(std::string(), std::string()); + metrics_provider.GoogleSigninSucceeded(AccountInfo()); EXPECT_EQ(SigninStatusMetricsProviderBase::MIXED_SIGNIN_STATUS, metrics_provider.GetSigninStatusForTesting()); }
diff --git a/components/signin/core/browser/signin_tracker.cc b/components/signin/core/browser/signin_tracker.cc index b24469f..0a82a89 100644 --- a/components/signin/core/browser/signin_tracker.cc +++ b/components/signin/core/browser/signin_tracker.cc
@@ -32,9 +32,8 @@ cookie_manager_service_->AddObserver(this); } -void SigninTracker::GoogleSigninSucceeded(const std::string& account_id, - const std::string& username) { - if (token_service_->RefreshTokenIsAvailable(account_id)) +void SigninTracker::GoogleSigninSucceeded(const AccountInfo& account_info) { + if (token_service_->RefreshTokenIsAvailable(account_info.account_id)) observer_->SigninSuccess(); }
diff --git a/components/signin/core/browser/signin_tracker.h b/components/signin/core/browser/signin_tracker.h index 11961fa..cb857e3a 100644 --- a/components/signin/core/browser/signin_tracker.h +++ b/components/signin/core/browser/signin_tracker.h
@@ -80,8 +80,7 @@ ~SigninTracker() override; // SigninManagerBase::Observer implementation. - void GoogleSigninSucceeded(const std::string& account_id, - const std::string& username) override; + void GoogleSigninSucceeded(const AccountInfo& account_info) override; void GoogleSigninFailed(const GoogleServiceAuthError& error) override; // OAuth2TokenService::Observer implementation.
diff --git a/components/signin/ios/browser/account_consistency_service.h b/components/signin/ios/browser/account_consistency_service.h index 4a060f6..a2ecd59c 100644 --- a/components/signin/ios/browser/account_consistency_service.h +++ b/components/signin/ios/browser/account_consistency_service.h
@@ -156,8 +156,7 @@ const GoogleServiceAuthError& error) override; // SigninManagerBase::Observer implementation. - void GoogleSigninSucceeded(const std::string& account_id, - const std::string& username) override; + void GoogleSigninSucceeded(const AccountInfo& account_info) override; void GoogleSignedOut(const std::string& account_id, const std::string& username) override;
diff --git a/components/signin/ios/browser/account_consistency_service.mm b/components/signin/ios/browser/account_consistency_service.mm index f0ef383..62110fa 100644 --- a/components/signin/ios/browser/account_consistency_service.mm +++ b/components/signin/ios/browser/account_consistency_service.mm
@@ -491,8 +491,7 @@ } void AccountConsistencyService::GoogleSigninSucceeded( - const std::string& account_id, - const std::string& username) { + const AccountInfo& account_info) { AddChromeConnectedCookies(); }
diff --git a/components/sync/android/java/src/org/chromium/components/sync/AndroidSyncSettings.java b/components/sync/android/java/src/org/chromium/components/sync/AndroidSyncSettings.java index 7f09ff7..dacc6886 100644 --- a/components/sync/android/java/src/org/chromium/components/sync/AndroidSyncSettings.java +++ b/components/sync/android/java/src/org/chromium/components/sync/AndroidSyncSettings.java
@@ -14,6 +14,7 @@ import org.chromium.base.Callback; import org.chromium.base.ContextUtils; import org.chromium.base.ObserverList; +import org.chromium.base.StrictModeContext; import org.chromium.base.ThreadUtils; import org.chromium.base.VisibleForTesting; import org.chromium.components.signin.AccountManagerFacade; @@ -242,41 +243,36 @@ mIsSyncable = shouldBeSyncable; - StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); - // Make account syncable if there is one. - if (shouldBeSyncable) { - mSyncContentResolverDelegate.setIsSyncable(mAccount, mContractAuthority, 1); - // This reduces unnecessary resource usage. See http://crbug.com/480688 for details. - mSyncContentResolverDelegate.removePeriodicSync( - mAccount, mContractAuthority, Bundle.EMPTY); + try (StrictModeContext ignored = StrictModeContext.allowDiskWrites()) { + // Make account syncable if there is one. + if (shouldBeSyncable) { + mSyncContentResolverDelegate.setIsSyncable(mAccount, mContractAuthority, 1); + // This reduces unnecessary resource usage. See http://crbug.com/480688 for details. + mSyncContentResolverDelegate.removePeriodicSync( + mAccount, mContractAuthority, Bundle.EMPTY); + } } - StrictMode.setThreadPolicy(oldPolicy); // Disable the syncability of Chrome for all other accounts. - ThreadUtils.postOnUiThread(new Runnable() { - @Override - public void run() { - AccountManagerFacade.get().tryGetGoogleAccounts(new Callback<Account[]>() { - @Override - public void onResult(Account[] accounts) { - synchronized (mLock) { - StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); - for (Account account : accounts) { - if (!account.equals(mAccount) - && mSyncContentResolverDelegate.getIsSyncable( - account, mContractAuthority) - > 0) { - mSyncContentResolverDelegate.setIsSyncable( - account, mContractAuthority, 0); - } + ThreadUtils.postOnUiThread(() -> { + AccountManagerFacade.get().tryGetGoogleAccounts(accounts -> { + synchronized (mLock) { + try (StrictModeContext ignored = StrictModeContext.allowDiskWrites()) { + for (int i = 0; i < accounts.size(); i++) { + Account account = accounts.get(i); + if (!account.equals(mAccount) + && mSyncContentResolverDelegate.getIsSyncable( + account, mContractAuthority) + > 0) { + mSyncContentResolverDelegate.setIsSyncable( + account, mContractAuthority, 0); } - StrictMode.setThreadPolicy(oldPolicy); } - - if (callback != null) callback.onResult(true); } - }); - } + } + + if (callback != null) callback.onResult(true); + }); }); }
diff --git a/components/sync/engine_impl/model_type_worker.cc b/components/sync/engine_impl/model_type_worker.cc index 5b81c964..aaa8144f 100644 --- a/components/sync/engine_impl/model_type_worker.cc +++ b/components/sync/engine_impl/model_type_worker.cc
@@ -392,9 +392,11 @@ } void ModelTypeWorker::ApplyPendingUpdates() { - if (!entries_pending_decryption_.empty()) + if (BlockForEncryption()) return; + DCHECK(entries_pending_decryption_.empty()); + DVLOG(1) << ModelTypeToString(type_) << ": " << base::StringPrintf("Delivering %" PRIuS " applicable updates.", pending_updates_.size()); @@ -538,6 +540,9 @@ } bool ModelTypeWorker::BlockForEncryption() const { + if (!entries_pending_decryption_.empty()) + return true; + // Should be using encryption, but we do not have the keys. return cryptographer_ && !cryptographer_->is_ready(); }
diff --git a/components/sync/user_events/user_event_service_impl.cc b/components/sync/user_events/user_event_service_impl.cc index eb0ddef..5baab49 100644 --- a/components/sync/user_events/user_event_service_impl.cc +++ b/components/sync/user_events/user_event_service_impl.cc
@@ -101,19 +101,22 @@ } bool UserEventServiceImpl::CanRecordHistory() { - // Before the engine is initialized, we cannot trust the other fields. - // TODO(vitaliii): Consider using GetState() instead of IsEngineInitialized(), - // because even when IsEngineInitialized() the user still may be configuring - // the datatypes. + // Before the engine is initialized, Sync doesn't know if there is a + // secondary passphrase. Similarly, unless the Sync feature is enabled, + // GetPreferredDataTypes() isn't meaningful. return sync_service_->IsEngineInitialized() && !sync_service_->IsUsingSecondaryPassphrase() && + sync_service_->IsSyncFeatureEnabled() && sync_service_->GetPreferredDataTypes().Has(HISTORY_DELETE_DIRECTIVES); } bool UserEventServiceImpl::IsUserEventsDatatypeEnabled() { - // Before the engine is initialized, we cannot trust the other fields. + // Before the engine is initialized, Sync doesn't know if there is a + // secondary passphrase. Similarly, unless the Sync feature is enabled, + // GetPreferredDataTypes() isn't meaningful. return sync_service_->IsEngineInitialized() && !sync_service_->IsUsingSecondaryPassphrase() && + sync_service_->IsSyncFeatureEnabled() && sync_service_->GetPreferredDataTypes().Has(USER_EVENTS); }
diff --git a/components/sync/user_events/user_event_sync_bridge.cc b/components/sync/user_events/user_event_sync_bridge.cc index 10e2099..9a53a14 100644 --- a/components/sync/user_events/user_event_sync_bridge.cc +++ b/components/sync/user_events/user_event_sync_bridge.cc
@@ -322,8 +322,6 @@ return; } - // TODO(vitaliii): Garbage collect old user consents if sync is disabled. - store_ = std::move(store); store_->ReadAllMetadata(base::BindOnce( &UserEventSyncBridge::OnReadAllMetadata, weak_ptr_factory_.GetWeakPtr()));
diff --git a/components/translate/content/renderer/translate_helper.cc b/components/translate/content/renderer/translate_helper.cc index a12241e9..9286e6ec 100644 --- a/components/translate/content/renderer/translate_helper.cc +++ b/components/translate/content/renderer/translate_helper.cc
@@ -134,7 +134,9 @@ // captured, it should be treated as a new page to do translation. ResetPage(); mojom::PagePtr page; - binding_.Bind(mojo::MakeRequest(&page)); + binding_.Bind( + mojo::MakeRequest(&page), + main_frame->GetTaskRunner(blink::TaskType::kInternalTranslation)); GetTranslateHandler()->RegisterPage( std::move(page), details, !details.has_notranslate && !language.empty()); }
diff --git a/components/ui_devtools/ui_element.cc b/components/ui_devtools/ui_element.cc index 1de4106..869475c 100644 --- a/components/ui_devtools/ui_element.cc +++ b/components/ui_devtools/ui_element.cc
@@ -52,6 +52,10 @@ delegate_->OnUIElementAdded(this, child); } +void UIElement::ClearChildren() { + children_.clear(); +} + void UIElement::RemoveChild(UIElement* child) { delegate()->OnUIElementRemoved(child); auto iter = std::find(children_.begin(), children_.end(), child);
diff --git a/components/ui_devtools/ui_element.h b/components/ui_devtools/ui_element.h index 5d20b5c..ce7d95a 100644 --- a/components/ui_devtools/ui_element.h +++ b/components/ui_devtools/ui_element.h
@@ -44,6 +44,10 @@ // is inserted at the end. Parent takes ownership of the added child. void AddChild(UIElement* child, UIElement* before = nullptr); + // Removes all elements from |children_|. Caller is responsible for destroying + // children. + void ClearChildren(); + // Remove |child| out of vector |children_| but |child| is not destroyed. // The caller is responsible for destroying |child|. void RemoveChild(UIElement* child);
diff --git a/components/ui_devtools/viz_views/dom_agent_viz.cc b/components/ui_devtools/viz_views/dom_agent_viz.cc index 78f6b509..5fe2b4b 100644 --- a/components/ui_devtools/viz_views/dom_agent_viz.cc +++ b/components/ui_devtools/viz_views/dom_agent_viz.cc
@@ -22,8 +22,8 @@ // attach it to the RootElement which serves as the root of the // CompositorFrameSink tree. In this state the CompositorFrameSink is considered // unembedded and it is a sibling of RootCompositorFrameSinks. If it is present -// in a tree we just change the properties (|is_registered_| or -// |is_client_connected_|). These events don't know anything about the hierarchy +// in a tree we just change the properties (|has_created_frame_sink_|). +// These events don't know anything about the hierarchy // so we don't change it. When we get OnRegisteredHierarchy from parent to child // the corresponding elements must already be present in a tree. The usual state // is: child is attached to RootElement and now we will detach it from the @@ -39,12 +39,11 @@ // 2. Deleting. We unregister hierarchy, destroy a CompositorFrameSink and // invalidate a FrameSinkId. When we invalidate an FrameSinkId or destroy a // FrameSink we check if it's the last action that has to happen with the -// corresponding element. For example, if the element has |is_client_connected_| -// = true and |is_registered_| = true and we get a |OnDestroyedFrameSink| event -// we just set |is_client_connected_| = false, but don't remove it from a tree, +// corresponding element. For example, if the element has +// |has_created_frame_sink_| = true and we get a |OnDestroyedFrameSink| event we +// just set |has_created_frame_sink_| = false, but don't remove it from a tree, // because its FrameSinkId is still registered, so it's not completely dead. But -// when after that we get |OnInvalidatedFrameSinkId| we set |is_registered_| = -// false and since both these fields are false we can go ahead and remove the +// when after that we get |OnInvalidatedFrameSinkId| we can remove the // node from the tree. When we get OnUnregisteredHierarchy we assume the nodes // are still present in a tree, so we do the same work as we did in registering // case. Only here we move a subtree of parent rooted from child to the @@ -67,10 +66,7 @@ element_root()->AddChild( new FrameSinkElement(frame_sink_id, frame_sink_manager_, this, element_root(), /*is_root=*/false, - /*is_registered=*/true, - /*is_client_connected=*/false), - element_root()->children().empty() ? nullptr - : element_root()->children().back()); + /*has_created_frame_sink=*/false)); } } @@ -79,26 +75,21 @@ auto it = frame_sink_elements_.find(frame_sink_id); DCHECK(it != frame_sink_elements_.end()); - // Destroy the FrameSinkElement |element| after updating the frame-tree. - std::unique_ptr<FrameSinkElement> element(it->second); - element->SetRegistered(false); - // A FrameSinkElement with |frame_sink_id| can only be invalidated after // being destroyed. - DCHECK(!element->is_client_connected()); - RemoveFrameSinkSubtree(element.get()); - frame_sink_elements_.erase(frame_sink_id); + DCHECK(!it->second->has_created_frame_sink()); + DestroyElementAndRemoveSubtree(it->second); } void DOMAgentViz::OnCreatedCompositorFrameSink( const viz::FrameSinkId& frame_sink_id, bool is_root) { - auto frame_sink_element = frame_sink_elements_.find(frame_sink_id); - DCHECK(frame_sink_element != frame_sink_elements_.end()); + auto it = frame_sink_elements_.find(frame_sink_id); + DCHECK(it != frame_sink_elements_.end()); // The corresponding element is already present in a tree, so we - // should update its |is_client_connected_| and |is_root_| properties. - frame_sink_element->second->SetClientConnected(true); - frame_sink_element->second->SetRoot(is_root); + // should update its |has_created_frame_sink_| and |is_root_| properties. + it->second->SetHasCreatedFrameSink(true); + it->second->SetRoot(is_root); } void DOMAgentViz::OnDestroyedCompositorFrameSink( @@ -106,9 +97,8 @@ auto it = frame_sink_elements_.find(frame_sink_id); DCHECK(it != frame_sink_elements_.end()); - FrameSinkElement* element = it->second; - // Set FrameSinkElement to not connected to make it as destroyed. - element->SetClientConnected(false); + // Set FrameSinkElement to not connected to mark it as destroyed. + it->second->SetHasCreatedFrameSink(false); } void DOMAgentViz::OnRegisteredFrameSinkHierarchy( @@ -126,11 +116,7 @@ FrameSinkElement* new_parent = it_parent->second; // TODO: Add support for |child| to have multiple parents. - if (child->parent()) - child->parent()->RemoveChild(child); - - new_parent->AddChild(child); - child->set_parent(new_parent); + Reparent(new_parent, child); } void DOMAgentViz::OnUnregisteredFrameSinkHierarchy( @@ -139,18 +125,14 @@ // At this point these elements must be present in a tree. // We should detach a child from its current parent and attach to the // RootElement since it wasn't destroyed yet. - auto it_parent = frame_sink_elements_.find(parent_frame_sink_id); auto it_child = frame_sink_elements_.find(child_frame_sink_id); - DCHECK(it_parent != frame_sink_elements_.end()); DCHECK(it_child != frame_sink_elements_.end()); FrameSinkElement* child = it_child->second; - FrameSinkElement* parent = it_parent->second; - parent->RemoveChild(child); // TODO: Add support for |child| to have multiple parents: only adds |child| // to RootElement if all parents of |child| are unregistered. - child->set_parent(element_root()); + Reparent(element_root(), child); } std::unique_ptr<DOM::Node> DOMAgentViz::BuildTreeForFrameSink( @@ -163,16 +145,12 @@ // subtree. So we iterate through |frame_sink_element|'s children and // recursively build the subtree for them. for (auto& child : frame_sink_manager_->GetChildrenByParent(frame_sink_id)) { - bool is_registered = base::ContainsValue( - frame_sink_manager_->GetRegisteredFrameSinkIds(), frame_sink_id); - bool is_client_connected = - is_registered && - base::ContainsValue(frame_sink_manager_->GetCreatedFrameSinkIds(), - frame_sink_id); + bool has_created_frame_sink = + !!frame_sink_manager_->GetFrameSinkForId(child); FrameSinkElement* f_s_element = new FrameSinkElement( child, frame_sink_manager_, this, frame_sink_element, - /*is_root=*/false, is_registered, is_client_connected); + /*is_root=*/false, has_created_frame_sink); children->addItem(BuildTreeForFrameSink(f_s_element, child)); frame_sink_element->AddChild(f_s_element); @@ -184,7 +162,6 @@ } protocol::Response DOMAgentViz::enable() { - InitFrameSinkSets(); frame_sink_manager_->AddObserver(this); return protocol::Response::OK(); } @@ -192,110 +169,102 @@ protocol::Response DOMAgentViz::disable() { frame_sink_manager_->RemoveObserver(this); Clear(); + element_root()->ClearChildren(); return DOMAgent::disable(); } std::vector<UIElement*> DOMAgentViz::CreateChildrenForRoot() { std::vector<UIElement*> children; - // Add created RootFrameSinks and detached FrameSinks. - for (auto& frame_sink_id : frame_sink_manager_->GetRegisteredFrameSinkIds()) { - if (base::ContainsValue(frame_sink_manager_->GetCreatedFrameSinkIds(), - frame_sink_id)) { - const viz::CompositorFrameSinkSupport* support = - frame_sink_manager_->GetFrameSinkForId(frame_sink_id); - // Do nothing if it's a non-detached non-root FrameSink. - if (support && !support->is_root() && - attached_frame_sinks_.find(frame_sink_id) != - attached_frame_sinks_.end()) { - continue; - } + // Find all elements that are not part of any hierarchy. This will be + // FrameSinks that are either root, or detached. + std::vector<viz::FrameSinkId> registered_frame_sinks = + frame_sink_manager_->GetRegisteredFrameSinkIds(); + base::flat_set<viz::FrameSinkId> detached_frame_sinks(registered_frame_sinks); - bool is_root = support && support->is_root(); - - UIElement* frame_sink_element = new FrameSinkElement( - frame_sink_id, frame_sink_manager_, this, element_root(), is_root, - /*is_registered=*/true, /*is_client_connected=*/true); - children.push_back(frame_sink_element); - - // Add registered but not created FrameSinks. If a FrameSinkId was - // registered but not created we don't really know whether it's a root or - // not. And we don't know any information about the hierarchy. Therefore - // we process FrameSinks that are in the correct state first and only - // after that we process registered but not created FrameSinks. We - // consider them unembedded as well. - } else { - UIElement* frame_sink_element = new FrameSinkElement( - frame_sink_id, frame_sink_manager_, this, element_root(), - /*is_root=*/false, /*is_registered=*/true, - /*is_client_connected=*/false); - - children.push_back(frame_sink_element); + for (auto& frame_sink_id : registered_frame_sinks) { + for (auto& child_id : + frame_sink_manager_->GetChildrenByParent(frame_sink_id)) { + detached_frame_sinks.erase(child_id); } } + // Add created RootFrameSinks and detached FrameSinks. + for (auto& frame_sink_id : detached_frame_sinks) { + const viz::CompositorFrameSinkSupport* support = + frame_sink_manager_->GetFrameSinkForId(frame_sink_id); + bool is_root = support && support->is_root(); + bool has_created_frame_sink = !!support; + // TODO(sgilhuly): Use unique_ptr instead of new for the FrameSinkElements. + UIElement* frame_sink_element = + new FrameSinkElement(frame_sink_id, frame_sink_manager_, this, + element_root(), is_root, has_created_frame_sink); + children.push_back(frame_sink_element); + } + return children; } std::unique_ptr<DOM::Node> DOMAgentViz::BuildTreeForUIElement( UIElement* ui_element) { if (ui_element->type() == UIElementType::FRAMESINK) { - viz::FrameSinkId frame_sink_id = FrameSinkElement::From(ui_element); - - bool is_registered = base::ContainsValue( - frame_sink_manager_->GetRegisteredFrameSinkIds(), frame_sink_id); - bool is_client_connected = - is_registered && - base::ContainsValue(frame_sink_manager_->GetCreatedFrameSinkIds(), - frame_sink_id); - FrameSinkElement* frame_sink_element = new FrameSinkElement( - frame_sink_id, frame_sink_manager_, this, nullptr, - /*is_root=*/false, is_registered, is_client_connected); - - return BuildTreeForFrameSink(frame_sink_element, frame_sink_id); + FrameSinkElement* frame_sink_element = + static_cast<FrameSinkElement*>(ui_element); + return BuildTreeForFrameSink(frame_sink_element, + frame_sink_element->frame_sink_id()); } return nullptr; } void DOMAgentViz::Clear() { - attached_frame_sinks_.clear(); + for (auto& entry : frame_sink_elements_) { + entry.second->ClearChildren(); + delete entry.second; + } frame_sink_elements_.clear(); } -void DOMAgentViz::InitFrameSinkSets() { - // Init the |attached_frame_sinks_| set. All RootFrameSinks and accessible - // from roots are attached. All the others are detached. - for (auto& frame_sink_id : frame_sink_manager_->GetRegisteredFrameSinkIds()) { - if (base::ContainsValue(frame_sink_manager_->GetCreatedFrameSinkIds(), - frame_sink_id)) { - const viz::CompositorFrameSinkSupport* support = - frame_sink_manager_->GetFrameSinkForId(frame_sink_id); - // Start only from roots. - if (!support || !support->is_root()) - continue; - - SetAttachedFrameSink(frame_sink_id); - } - } -} - -void DOMAgentViz::SetAttachedFrameSink(const viz::FrameSinkId& frame_sink_id) { - attached_frame_sinks_.insert(frame_sink_id); - for (auto& child : frame_sink_manager_->GetChildrenByParent(frame_sink_id)) - SetAttachedFrameSink(child); -} - -void DOMAgentViz::RemoveFrameSinkSubtree(UIElement* root) { +void DOMAgentViz::DestroyElementAndRemoveSubtree(UIElement* element) { // We may come across the case where we've got the event to delete the // FrameSink, but we haven't got events to delete its children. We should // detach all its children and attach them to RootElement and then delete the // node we were asked for. - std::vector<viz::FrameSinkId> children; - for (auto* child : root->children()) - child->set_parent(element_root()); + for (auto* child : element->children()) + Reparent(element_root(), child); - if (root->parent()) - root->parent()->RemoveChild(root); + element->parent()->RemoveChild(element); + DestroyElement(element); +} + +void DOMAgentViz::Reparent(UIElement* new_parent, UIElement* child) { + DestroySubtree(child); + child->ClearChildren(); + + // This removes the child element from the Node map. It has to be added with + // null parent to recreate the entry. + child->parent()->RemoveChild(child); + OnUIElementAdded(nullptr, child); + new_parent->AddChild(child); + child->set_parent(new_parent); +} + +void DOMAgentViz::DestroyElement(UIElement* element) { + if (element->type() == UIElementType::FRAMESINK) { + // TODO(sgilhuly): Use unique_ptr, so that the element doesn't need to be + // deleted manually. + frame_sink_elements_.erase(FrameSinkElement::From(element)); + delete element; + } else { + NOTREACHED(); + } +} + +void DOMAgentViz::DestroySubtree(UIElement* element) { + for (auto* child : element->children()) { + DestroySubtree(child); + DestroyElement(child); + } + element->ClearChildren(); } } // namespace ui_devtools
diff --git a/components/ui_devtools/viz_views/dom_agent_viz.h b/components/ui_devtools/viz_views/dom_agent_viz.h index 144729c1..afcabd3 100644 --- a/components/ui_devtools/viz_views/dom_agent_viz.h +++ b/components/ui_devtools/viz_views/dom_agent_viz.h
@@ -59,16 +59,23 @@ // FrameSinks, registered FrameSinkIds and those that have corresponding // FrameSinkElements created. void Clear(); - // Initializes the sets of FrameSinkIds that correspond to registered - // FrameSinkIds and created FrameSinks. - void InitFrameSinkSets(); - // Mark a FrameSink that has |frame_sink_id| and all its subtree as attached. - void SetAttachedFrameSink(const viz::FrameSinkId& frame_sink_id); + // Destroy |element| and attach all its children to the root_element(). + void DestroyElementAndRemoveSubtree(UIElement* element); - // We remove |root| from its parents and attach all its children to the - // root_element(). - void RemoveFrameSinkSubtree(UIElement* root); + // Destroy all children and move to |new_parent|. This also rebuilds the + // subtree via BuildTreeForUIElement. + // TODO(sgilhuly): Improve the way reparenting is handled. Currently, after + // the node is removed, you have to remove all of its children, and add the + // element back to the tree. Then, the list of children is repopulated. + void Reparent(UIElement* new_parent, UIElement* child); + + // Removes an element from |frame_sink_elements_|. + void DestroyElement(UIElement* element); + + // Remove all subtree elements from |frame_sink_elements_|. |element| itself + // is preserved. + void DestroySubtree(UIElement* element); // This is used to track created FrameSinkElements in a FrameSink tree. Every // time we register/invalidate a FrameSinkId, create/destroy a FrameSink, @@ -76,9 +83,6 @@ // involve deleting and adding elements. base::flat_map<viz::FrameSinkId, FrameSinkElement*> frame_sink_elements_; - // This is used to denote attached FrameSinks. - base::flat_set<viz::FrameSinkId> attached_frame_sinks_; - viz::FrameSinkManagerImpl* frame_sink_manager_; DISALLOW_COPY_AND_ASSIGN(DOMAgentViz);
diff --git a/components/ui_devtools/viz_views/frame_sink_element.cc b/components/ui_devtools/viz_views/frame_sink_element.cc index 209ff71c..ab3c8bd 100644 --- a/components/ui_devtools/viz_views/frame_sink_element.cc +++ b/components/ui_devtools/viz_views/frame_sink_element.cc
@@ -20,14 +20,12 @@ UIElementDelegate* ui_element_delegate, UIElement* parent, bool is_root, - bool is_registered, - bool is_client_connected) + bool has_created_frame_sink) : UIElement(UIElementType::FRAMESINK, ui_element_delegate, parent), frame_sink_id_(frame_sink_id), frame_sink_manager_(frame_sink_manager), is_root_(is_root), - is_registered_(is_registered), - is_client_connected_(is_client_connected) {} + has_created_frame_sink_(has_created_frame_sink) {} FrameSinkElement::~FrameSinkElement() {} @@ -37,10 +35,8 @@ // Hierarchical information about the FrameSink. v.push_back(std::make_pair("Is root", is_root_ ? "true" : "false")); - v.push_back( - std::make_pair("Is registered", is_registered_ ? "true" : "false")); - v.push_back(std::make_pair("Is connected by client", - is_client_connected_ ? "true" : "false")); + v.push_back(std::make_pair("Has created frame sink", + has_created_frame_sink_ ? "true" : "false")); // LastUsedBeingFrameArgs information. const viz::CompositorFrameSinkSupport* support =
diff --git a/components/ui_devtools/viz_views/frame_sink_element.h b/components/ui_devtools/viz_views/frame_sink_element.h index 5d8bb76..07a6355a 100644 --- a/components/ui_devtools/viz_views/frame_sink_element.h +++ b/components/ui_devtools/viz_views/frame_sink_element.h
@@ -22,20 +22,18 @@ UIElementDelegate* ui_element_delegate, UIElement* parent, bool is_root, - bool is_registered, - bool is_client_connected); + bool has_created_frame_sink); ~FrameSinkElement() override; // Used by DOMAgentViz on updates when element is already present // in a tree but its properties need to be changed. - void SetRegistered(bool is_registered) { is_registered_ = is_registered; } - void SetClientConnected(bool is_client_connected) { - is_client_connected_ = is_client_connected; + void SetHasCreatedFrameSink(bool has_created_frame_sink) { + has_created_frame_sink_ = has_created_frame_sink; } void SetRoot(bool is_root) { is_root_ = is_root; } - bool is_registered() const { return is_registered_; } - bool is_client_connected() const { return is_client_connected_; } + const viz::FrameSinkId& frame_sink_id() const { return frame_sink_id_; } + bool has_created_frame_sink() const { return has_created_frame_sink_; } // UIElement: std::vector<std::pair<std::string, std::string>> GetCustomProperties() @@ -57,12 +55,9 @@ // Properties of the FrameSink. If element is a RootFrameSink then it has // |is_root_| = true. If element is not a root than it has |is_root_| = false. // If an element is a sibling of a RootFrameSink but has property |is_root_| = - // false then it is considered detached. If the FrameSink was registered then - // corresponding element's |is_registered_| = true. If a FrameSink was created - // then |is_client_connected_| = true. + // false then it is considered detached. bool is_root_; - bool is_registered_; - bool is_client_connected_; + bool has_created_frame_sink_; DISALLOW_COPY_AND_ASSIGN(FrameSinkElement); };
diff --git a/components/ukm/observers/sync_disable_observer.cc b/components/ukm/observers/sync_disable_observer.cc index 824463a..0309c13 100644 --- a/components/ukm/observers/sync_disable_observer.cc +++ b/components/ukm/observers/sync_disable_observer.cc
@@ -21,6 +21,8 @@ const base::Feature kUkmCheckAuthErrorFeature{"UkmCheckAuthError", base::FEATURE_ENABLED_BY_DEFAULT}; +const base::Feature kUkmCheckEnabledForDatatypes{ + "UkmCheckEnabledForDatatypes", base::FEATURE_ENABLED_BY_DEFAULT}; const base::Feature kUkmPurgingOnConnection{"UkmPurgingOnConnection", base::FEATURE_DISABLED_BY_DEFAULT}; @@ -79,13 +81,37 @@ UrlKeyedDataCollectionConsentHelper* consent_helper) { syncer::SyncTokenStatus status = sync_service->GetSyncTokenStatus(); SyncState state; - state.history_enabled = sync_service->GetPreferredDataTypes().Has( - syncer::HISTORY_DELETE_DIRECTIVES); - state.extensions_enabled = - sync_service->GetPreferredDataTypes().Has(syncer::EXTENSIONS); + + // For the following two settings, we want them to match the state of a user + // having history/extensions enabled in their Sync settings. Using it to track + // active connections here is undesirable as changes in these states trigger + // data purges. + if (base::FeatureList::IsEnabled(kUkmCheckEnabledForDatatypes)) { + state.history_enabled = sync_service->GetPreferredDataTypes().Has( + syncer::HISTORY_DELETE_DIRECTIVES) && + sync_service->IsSyncFeatureEnabled(); + + state.extensions_enabled = + sync_service->GetPreferredDataTypes().Has(syncer::EXTENSIONS) && + sync_service->IsSyncFeatureEnabled(); + } else { + // If kUkmCheckEnabledForDatatypes is disabled, use legacy settings. + // TODO(rkaplow): Clean this up after crbug.com/906609. + state.history_enabled = sync_service->GetPreferredDataTypes().Has( + syncer::HISTORY_DELETE_DIRECTIVES); + + state.extensions_enabled = + sync_service->GetPreferredDataTypes().Has(syncer::EXTENSIONS); + } + state.initialized = sync_service->IsEngineInitialized(); + + // We use CONNECTION_OK here as an auth error can be used in the sync + // paused state. Therefore we need to be more direct and check CONNECTION_OK + // as opposed to using something like IsSyncFeatureActive(). state.connected = !base::FeatureList::IsEnabled(kUkmCheckAuthErrorFeature) || status.connection_status == syncer::CONNECTION_OK; + state.passphrase_protected = state.initialized && sync_service->IsUsingSecondaryPassphrase(); if (consent_helper) {
diff --git a/components/unified_consent/unified_consent_service.cc b/components/unified_consent/unified_consent_service.cc index 80a0278..c882adb2 100644 --- a/components/unified_consent/unified_consent_service.cc +++ b/components/unified_consent/unified_consent_service.cc
@@ -217,8 +217,7 @@ } void UnifiedConsentService::OnStateChanged(syncer::SyncService* sync) { - if (sync_service_->GetDisableReasons() != - syncer::SyncService::DISABLE_REASON_NONE || + if (!sync_service_->CanSyncFeatureStart() || !sync_service_->IsEngineInitialized()) { return; } @@ -339,6 +338,7 @@ // Set URL-keyed anonymized metrics to the state it had before unified // consent. bool url_keyed_metrics_enabled = + sync_service_->IsSyncFeatureEnabled() && sync_service_->GetUserSettings()->GetChosenDataTypes().Has( syncer::TYPED_URLS) && !sync_service_->GetUserSettings()->IsUsingSecondaryPassphrase();
diff --git a/components/variations/service/variations_service.cc b/components/variations/service/variations_service.cc index b482b84b..77d99f6 100644 --- a/components/variations/service/variations_service.cc +++ b/components/variations/service/variations_service.cc
@@ -116,9 +116,14 @@ #endif } -// Gets the restrict parameter from either the client or |policy_pref_service|. -std::string GetRestrictParameterPref(VariationsServiceClient* client, - PrefService* policy_pref_service) { +// Gets the restrict parameter from either the passed override, the client or +// |policy_pref_service|. +std::string GetRestrictParameterValue(const std::string& restrict_mode_override, + VariationsServiceClient* client, + PrefService* policy_pref_service) { + if (!restrict_mode_override.empty()) + return restrict_mode_override; + std::string parameter; if (client->OverridesRestrictParameter(¶meter) || !policy_pref_service) return parameter; @@ -369,11 +374,16 @@ restrict_mode_ = restrict_mode; } -GURL VariationsService::GetVariationsServerURL( - PrefService* policy_pref_service, - const std::string& restrict_mode_override, - HttpOptions http_options) { - bool secure = http_options == USE_HTTPS; +GURL VariationsService::GetVariationsServerURL(HttpOptions http_options) { + const bool secure = http_options == USE_HTTPS; + const std::string restrict_mode = GetRestrictParameterValue( + restrict_mode_, client_.get(), policy_pref_service_); + + // If there's a restrict mode, we don't want to fall back to HTTP to avoid + // toggling restrict mode state. + if (!secure && !restrict_mode.empty()) + return GURL(); + std::string server_url_string( base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( secure ? switches::kVariationsServerURL @@ -381,15 +391,10 @@ if (server_url_string.empty()) server_url_string = secure ? kDefaultServerUrl : kDefaultInsecureServerUrl; GURL server_url = GURL(server_url_string); - if (secure) { - const std::string restrict_param = - !restrict_mode_override.empty() - ? restrict_mode_override - : GetRestrictParameterPref(client_.get(), policy_pref_service); - if (!restrict_param.empty()) { - server_url = net::AppendOrReplaceQueryParameter(server_url, "restrict", - restrict_param); - } + if (!restrict_mode.empty()) { + DCHECK(secure); + server_url = net::AppendOrReplaceQueryParameter(server_url, "restrict", + restrict_mode); } server_url = net::AppendOrReplaceQueryParameter(server_url, "osname", GetPlatformString()); @@ -601,14 +606,11 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // Initialize the Variations server URL. - variations_server_url_ = - GetVariationsServerURL(policy_pref_service_, restrict_mode_, USE_HTTPS); + variations_server_url_ = GetVariationsServerURL(USE_HTTPS); // Initialize the fallback HTTP URL if the HTTP retry feature is enabled. - if (base::FeatureList::IsEnabled(kHttpRetryFeature)) { - insecure_variations_server_url_ = - GetVariationsServerURL(policy_pref_service_, restrict_mode_, USE_HTTP); - } + if (base::FeatureList::IsEnabled(kHttpRetryFeature)) + insecure_variations_server_url_ = GetVariationsServerURL(USE_HTTP); DCHECK(!request_scheduler_); request_scheduler_.reset(VariationsRequestScheduler::Create( @@ -676,6 +678,15 @@ if (!is_success) { DVLOG(1) << "Variations server request failed with error: " << net_error << ": " << net::ErrorToString(net_error); + // It's common for the very first fetch attempt to fail (e.g. the network + // may not yet be available). In such a case, try again soon, rather than + // waiting the full time interval. + // |request_scheduler_| will be null during unit tests. + if (is_first_request && request_scheduler_) { + request_scheduler_->ScheduleFetchShortly(); + return; + } + // If the current fetch attempt was over an HTTPS connection, retry the // fetch immediately over an HTTP connection. // Currently we only do this if if the 'VariationsHttpRetry' feature is @@ -686,12 +697,6 @@ if (DoFetchFromURL(insecure_variations_server_url_, true)) return; } - // It's common for the very first fetch attempt to fail (e.g. the network - // may not yet be available). In such a case, try again soon, rather than - // waiting the full time interval. - // |request_scheduler_| will be null during unit tests. - if (is_first_request && request_scheduler_) - request_scheduler_->ScheduleFetchShortly(); return; }
diff --git a/components/variations/service/variations_service.h b/components/variations/service/variations_service.h index a18b8545..30db64c 100644 --- a/components/variations/service/variations_service.h +++ b/components/variations/service/variations_service.h
@@ -108,13 +108,11 @@ // to |StartRepeatedVariationsSeedFetch|. void SetRestrictMode(const std::string& restrict_mode); - // Returns the variations server URL, which can vary if a command-line flag is - // set and/or the variations restrict pref is set in |local_prefs|. Declared - // static for test purposes. |http_options| determines whether to use the http - // or https URL. - GURL GetVariationsServerURL(PrefService* local_prefs, - const std::string& restrict_mode_overrided, - HttpOptions http_options); + // Returns the variations server URL. |http_options| determines whether to + // use the http or https URL. This function will return an empty GURL when + // the restrict param exists for USE_HTTP, to indicate that no HTTP fallback + // should happen in that case. + GURL GetVariationsServerURL(HttpOptions http_options); // Returns the permanent country code stored for this client. Country code is // in the format of lowercase ISO 3166-1 alpha-2. Example: us, br, in
diff --git a/components/variations/service/variations_service_unittest.cc b/components/variations/service/variations_service_unittest.cc index 41dc47d..37957a1 100644 --- a/components/variations/service/variations_service_unittest.cc +++ b/components/variations/service/variations_service_unittest.cc
@@ -129,8 +129,8 @@ delta_compressed_seed_(false), gzip_compressed_seed_(false), insecurely_fetched_seed_(false) { - interception_url_ = GetVariationsServerURL( - local_state, std::string(), use_secure_url ? USE_HTTPS : USE_HTTP); + interception_url_ = + GetVariationsServerURL(use_secure_url ? USE_HTTPS : USE_HTTP); set_variations_server_url(interception_url_); } @@ -324,37 +324,46 @@ std::make_unique<web_resource::TestRequestAllowedNotifier>( &prefs_, network_tracker_), &prefs_, GetMetricsStateManager(), UIStringOverrider()); - GURL url = service.GetVariationsServerURL(&prefs_, std::string(), - TestVariationsService::USE_HTTPS); + GURL url = service.GetVariationsServerURL(TestVariationsService::USE_HTTPS); EXPECT_TRUE(base::StartsWith(url.spec(), default_variations_url, base::CompareCase::SENSITIVE)); EXPECT_FALSE(net::GetValueForKeyInQuery(url, "restrict", &value)); + // There should be a fallback URL since restrict mode is not set. + EXPECT_NE(GURL(), + service.GetVariationsServerURL(TestVariationsService::USE_HTTP)); prefs_.SetString(prefs::kVariationsRestrictParameter, "restricted"); - url = service.GetVariationsServerURL(&prefs_, std::string(), - TestVariationsService::USE_HTTPS); + url = service.GetVariationsServerURL(TestVariationsService::USE_HTTPS); EXPECT_TRUE(base::StartsWith(url.spec(), default_variations_url, base::CompareCase::SENSITIVE)); EXPECT_TRUE(net::GetValueForKeyInQuery(url, "restrict", &value)); EXPECT_EQ("restricted", value); + // No fallback URL because restrict mode is set. + EXPECT_EQ(GURL(), + service.GetVariationsServerURL(TestVariationsService::USE_HTTP)); // A client override should take precedence over what's in prefs_. raw_client->set_restrict_parameter("client"); - url = service.GetVariationsServerURL(&prefs_, std::string(), - TestVariationsService::USE_HTTPS); + url = service.GetVariationsServerURL(TestVariationsService::USE_HTTPS); EXPECT_TRUE(base::StartsWith(url.spec(), default_variations_url, base::CompareCase::SENSITIVE)); EXPECT_TRUE(net::GetValueForKeyInQuery(url, "restrict", &value)); EXPECT_EQ("client", value); + // No fallback URL because restrict mode is set. + EXPECT_EQ(GURL(), + service.GetVariationsServerURL(TestVariationsService::USE_HTTP)); - // The override value passed to the method should take precedence over - // what's in prefs_ and a client override. - url = service.GetVariationsServerURL(&prefs_, "override", - TestVariationsService::USE_HTTPS); + // The value set via SetRestrictMode() should take precedence over what's + // in prefs_ and a client override. + service.SetRestrictMode("override"); + url = service.GetVariationsServerURL(TestVariationsService::USE_HTTPS); EXPECT_TRUE(base::StartsWith(url.spec(), default_variations_url, base::CompareCase::SENSITIVE)); EXPECT_TRUE(net::GetValueForKeyInQuery(url, "restrict", &value)); EXPECT_EQ("override", value); + // No fallback URL because restrict mode is set. + EXPECT_EQ(GURL(), + service.GetVariationsServerURL(TestVariationsService::USE_HTTP)); } TEST_F(VariationsServiceTest, VariationsURLHasParams) { @@ -367,8 +376,7 @@ &prefs_, network_tracker_), &prefs_, GetMetricsStateManager(), UIStringOverrider()); raw_client->set_channel(version_info::Channel::UNKNOWN); - GURL url = service.GetVariationsServerURL(&prefs_, std::string(), - TestVariationsService::USE_HTTPS); + GURL url = service.GetVariationsServerURL(TestVariationsService::USE_HTTPS); std::string value; EXPECT_TRUE(net::GetValueForKeyInQuery(url, "osname", &value)); @@ -384,8 +392,7 @@ EXPECT_TRUE(channel.empty()); raw_client->set_channel(version_info::Channel::STABLE); - url = service.GetVariationsServerURL(&prefs_, std::string(), - TestVariationsService::USE_HTTPS); + url = service.GetVariationsServerURL(TestVariationsService::USE_HTTPS); EXPECT_TRUE(net::GetValueForKeyInQuery(url, "channel", &channel)); EXPECT_FALSE(channel.empty()); }
diff --git a/components/viz/service/frame_sinks/frame_sink_manager_impl.cc b/components/viz/service/frame_sinks/frame_sink_manager_impl.cc index 859c61e1..8676bc24 100644 --- a/components/viz/service/frame_sinks/frame_sink_manager_impl.cc +++ b/components/viz/service/frame_sinks/frame_sink_manager_impl.cc
@@ -112,9 +112,6 @@ const FrameSinkId& frame_sink_id) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - for (auto& observer : observer_list_) - observer.OnInvalidatedFrameSinkId(frame_sink_id); - surface_manager_.InvalidateFrameSinkId(frame_sink_id); if (video_detector_) video_detector_->OnFrameSinkIdInvalidated(frame_sink_id); @@ -124,6 +121,9 @@ root_sink_map_.erase(frame_sink_id); frame_sink_data_.erase(frame_sink_id); + + for (auto& observer : observer_list_) + observer.OnInvalidatedFrameSinkId(frame_sink_id); } void FrameSinkManagerImpl::EnableSynchronizationReporting( @@ -555,13 +555,6 @@ observer_list_.RemoveObserver(obs); } -std::vector<FrameSinkId> FrameSinkManagerImpl::GetCreatedFrameSinkIds() const { - std::vector<FrameSinkId> frame_sink_ids; - for (auto& map_entry : support_map_) - frame_sink_ids.push_back(map_entry.first); - return frame_sink_ids; -} - std::vector<FrameSinkId> FrameSinkManagerImpl::GetRegisteredFrameSinkIds() const { std::vector<FrameSinkId> frame_sink_ids;
diff --git a/components/viz/service/frame_sinks/frame_sink_manager_impl.h b/components/viz/service/frame_sinks/frame_sink_manager_impl.h index 17f680e..9d2647b 100644 --- a/components/viz/service/frame_sinks/frame_sink_manager_impl.h +++ b/components/viz/service/frame_sinks/frame_sink_manager_impl.h
@@ -187,8 +187,6 @@ void AddObserver(FrameSinkObserver* obs); void RemoveObserver(FrameSinkObserver* obs); - // Returns ids of all FrameSinks that were created. - std::vector<FrameSinkId> GetCreatedFrameSinkIds() const; // Returns ids of all FrameSinks that were registered. std::vector<FrameSinkId> GetRegisteredFrameSinkIds() const;
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 85eb70e..3cd3e9e 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -559,6 +559,8 @@ "cache_storage/cache_storage_blob_to_disk_cache.h", "cache_storage/cache_storage_cache.cc", "cache_storage/cache_storage_cache.h", + "cache_storage/cache_storage_cache_entry_handler.cc", + "cache_storage/cache_storage_cache_entry_handler.h", "cache_storage/cache_storage_cache_handle.h", "cache_storage/cache_storage_cache_observer.h", "cache_storage/cache_storage_context_impl.cc",
diff --git a/content/browser/cache_storage/cache_storage_cache.cc b/content/browser/cache_storage/cache_storage_cache.cc index 393dbc2..c6fb90e 100644 --- a/content/browser/cache_storage/cache_storage_cache.cc +++ b/content/browser/cache_storage/cache_storage_cache.cc
@@ -27,6 +27,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "content/browser/cache_storage/cache_storage.pb.h" #include "content/browser/cache_storage/cache_storage_blob_to_disk_cache.h" +#include "content/browser/cache_storage/cache_storage_cache_entry_handler.h" #include "content/browser/cache_storage/cache_storage_cache_handle.h" #include "content/browser/cache_storage/cache_storage_cache_observer.h" #include "content/browser/cache_storage/cache_storage_histogram_utils.h" @@ -47,15 +48,12 @@ #include "net/disk_cache/disk_cache.h" #include "net/url_request/url_request_context_getter.h" #include "services/network/public/mojom/fetch_api.mojom.h" -#include "storage/browser/blob/blob_data_builder.h" #include "storage/browser/blob/blob_data_handle.h" -#include "storage/browser/blob/blob_impl.h" #include "storage/browser/blob/blob_storage_context.h" #include "storage/browser/blob/blob_url_request_job_factory.h" #include "storage/browser/quota/quota_manager_proxy.h" #include "storage/common/blob_storage/blob_handle.h" #include "storage/common/storage_histograms.h" -#include "third_party/blink/public/common/blob/blob_utils.h" #include "third_party/blink/public/common/cache_storage/cache_storage_utils.h" #include "third_party/blink/public/mojom/quota/quota_types.mojom.h" @@ -423,67 +421,6 @@ } // namespace -// This class ensures that the cache and the entry have a lifetime as long as -// the blob that is created to contain them. -class CacheStorageCache::BlobDataHandle - : public storage::BlobDataBuilder::DataHandle { - public: - BlobDataHandle(CacheStorageCacheHandle cache_handle, - disk_cache::ScopedEntryPtr entry) - : cache_handle_(std::move(cache_handle)), entry_(std::move(entry)) {} - - bool IsValid() override { return bool{entry_}; } - - void Invalidate() { - cache_handle_ = base::nullopt; - entry_ = nullptr; - } - - private: - ~BlobDataHandle() override { - if (cache_handle_ && cache_handle_->value()) { - cache_handle_->value()->blob_data_handles_.erase(this); - } - } - - base::Optional<CacheStorageCacheHandle> cache_handle_; - disk_cache::ScopedEntryPtr entry_; - - DISALLOW_COPY_AND_ASSIGN(BlobDataHandle); -}; - -// The state needed to pass between CacheStorageCache::Put callbacks. -struct CacheStorageCache::PutContext { - PutContext(std::unique_ptr<ServiceWorkerFetchRequest> request, - blink::mojom::FetchAPIResponsePtr response, - blink::mojom::BlobPtr blob, - uint64_t blob_size, - blink::mojom::BlobPtr side_data_blob, - uint64_t side_data_blob_size, - CacheStorageCache::ErrorCallback callback) - : request(std::move(request)), - response(std::move(response)), - blob(std::move(blob)), - blob_size(blob_size), - side_data_blob(std::move(side_data_blob)), - side_data_blob_size(side_data_blob_size), - callback(std::move(callback)) {} - - // Input parameters to the Put function. - std::unique_ptr<ServiceWorkerFetchRequest> request; - blink::mojom::FetchAPIResponsePtr response; - blink::mojom::BlobPtr blob; - uint64_t blob_size; - blink::mojom::BlobPtr side_data_blob; - uint64_t side_data_blob_size; - - CacheStorageCache::ErrorCallback callback; - disk_cache::ScopedEntryPtr cache_entry; - - private: - DISALLOW_COPY_AND_ASSIGN(PutContext); -}; - struct CacheStorageCache::QueryCacheResult { explicit QueryCacheResult(base::Time entry_time) : entry_time(entry_time) {} @@ -962,6 +899,9 @@ cache_padding_key_(std::move(cache_padding_key)), max_query_size_bytes_(kMaxQueryCacheResultBytes), cache_observer_(nullptr), + cache_entry_handler_( + CacheStorageCacheEntryHandler::CreateCacheEntryHandler(owner, + blob_context)), memory_only_(path.empty()), weak_ptr_factory_(this) { DCHECK(!origin_.opaque()); @@ -1188,7 +1128,8 @@ return; } - PopulateResponseBody(std::move(entry), match->response.get()); + cache_entry_handler_->PopulateResponseBody(CreateHandle(), std::move(entry), + match->response.get()); } else if (!(query_cache_context->query_types & QUERY_CACHE_RESPONSES_NO_BODIES)) { match->response.reset(); @@ -1459,27 +1400,13 @@ ErrorCallback callback) { DCHECK(BACKEND_OPEN == backend_state_ || initializing_); - blink::mojom::BlobPtr blob; - uint64_t blob_size = blink::BlobUtils::kUnknownSize; - blink::mojom::BlobPtr side_data_blob; - uint64_t side_data_blob_size = blink::BlobUtils::kUnknownSize; - - if (response->blob) { - blob.Bind(std::move(response->blob->blob)); - blob_size = response->blob->size; - } - if (response->side_data_blob) { - side_data_blob.Bind(std::move(response->side_data_blob->blob)); - side_data_blob_size = response->side_data_blob->size; - } - UMA_HISTOGRAM_ENUMERATION("ServiceWorkerCache.Cache.AllWritesResponseType", response->response_type); - auto put_context = std::make_unique<PutContext>( - std::move(request), std::move(response), std::move(blob), blob_size, - std::move(side_data_blob), side_data_blob_size, - scheduler_->WrapCallbackToRunNext(std::move(callback))); + auto put_context = cache_entry_handler_->CreatePutContext( + std::move(request), std::move(response)); + put_context->callback = + scheduler_->WrapCallbackToRunNext(std::move(callback)); scheduler_->ScheduleOperation(base::BindOnce(&CacheStorageCache::PutImpl, weak_ptr_factory_.GetWeakPtr(), @@ -1980,8 +1907,7 @@ void CacheStorageCache::GetSizeThenCloseDidGetSize(SizeCallback callback, int64_t cache_size) { - for (auto* handle : blob_data_handles_) - handle->Invalidate(); + cache_entry_handler_->InvalidateBlobDataHandles(); CloseImpl(base::BindOnce(std::move(callback), cache_size)); } @@ -2133,31 +2059,6 @@ std::move(callback).Run(); } -void CacheStorageCache::PopulateResponseBody( - disk_cache::ScopedEntryPtr entry, - blink::mojom::FetchAPIResponse* response) { - DCHECK(blob_storage_context_); - - // Create a blob with the response body data. - response->blob = blink::mojom::SerializedBlob::New(); - response->blob->size = entry->GetDataSize(INDEX_RESPONSE_BODY); - response->blob->uuid = base::GenerateGUID(); - auto blob_data = - std::make_unique<storage::BlobDataBuilder>(response->blob->uuid); - - disk_cache::Entry* temp_entry = entry.get(); - auto data_handle = - base::MakeRefCounted<BlobDataHandle>(CreateHandle(), std::move(entry)); - blob_data_handles_.insert(data_handle.get()); - blob_data->AppendDiskCacheEntryWithSideData( - std::move(data_handle), temp_entry, INDEX_RESPONSE_BODY, INDEX_SIDE_DATA); - auto blob_handle = - blob_storage_context_->AddFinishedBlob(std::move(blob_data)); - - storage::BlobImpl::Create(std::move(blob_handle), - MakeRequest(&response->blob->blob)); -} - int64_t CacheStorageCache::PaddedCacheSize() const { DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_); if (cache_size_ == CacheStorage::kSizeUnknown ||
diff --git a/content/browser/cache_storage/cache_storage_cache.h b/content/browser/cache_storage/cache_storage_cache.h index 3bc24387..e71a13e 100644 --- a/content/browser/cache_storage/cache_storage_cache.h +++ b/content/browser/cache_storage/cache_storage_cache.h
@@ -41,9 +41,11 @@ namespace content { class CacheStorage; class CacheStorageBlobToDiskCache; +class CacheStorageCacheEntryHandler; class CacheStorageCacheObserver; class CacheStorageScheduler; enum class CacheStorageOwner; +struct PutContext; namespace proto { class CacheMetadata; @@ -84,6 +86,9 @@ using SizeCallback = base::OnceCallback<void(int64_t)>; using SizePaddingCallback = base::OnceCallback<void(int64_t, int64_t)>; + // The stream index for a cache Entry. This cannot be extended without changes + // in the Entry implementation. INDEX_SIDE_DATA is used for storing any + // additional data, such as response side blobs or request bodies. enum EntryIndex { INDEX_HEADERS = 0, INDEX_RESPONSE_BODY, INDEX_SIDE_DATA }; static std::unique_ptr<CacheStorageCache> CreateMemoryCache( @@ -259,7 +264,6 @@ friend class cache_storage_cache_unittest::TestCacheStorageCache; friend class cache_storage_cache_unittest::CacheStorageCacheTest; - struct PutContext; struct QueryCacheContext; struct QueryCacheResult; @@ -477,9 +481,6 @@ int64_t cache_padding); void DeleteBackendCompletedIO(); - void PopulateResponseBody(disk_cache::ScopedEntryPtr entry, - blink::mojom::FetchAPIResponse* response); - // Be sure to check |backend_state_| before use. std::unique_ptr<disk_cache::Backend> backend_; @@ -505,17 +506,11 @@ size_t max_query_size_bytes_; size_t handle_ref_count_ = 0; CacheStorageCacheObserver* cache_observer_; + std::unique_ptr<CacheStorageCacheEntryHandler> cache_entry_handler_; // Owns the elements of the list BlobToDiskCacheIDMap active_blob_to_disk_cache_writers_; - // This class ensures that the cache and the entry have a lifetime as long as - // the blob that is created to contain them. We keep track of these instances - // to allow us to invalidate them if the cache has to be deleted while there - // are still references to data in it. - class BlobDataHandle; - std::set<BlobDataHandle*> blob_data_handles_; - // Whether or not to store data in disk or memory. bool memory_only_;
diff --git a/content/browser/cache_storage/cache_storage_cache_entry_handler.cc b/content/browser/cache_storage/cache_storage_cache_entry_handler.cc new file mode 100644 index 0000000..1e52178 --- /dev/null +++ b/content/browser/cache_storage/cache_storage_cache_entry_handler.cc
@@ -0,0 +1,147 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/cache_storage/cache_storage_cache_entry_handler.h" + +#include "base/guid.h" +#include "base/optional.h" +#include "content/browser/cache_storage/cache_storage_cache.h" +#include "content/browser/cache_storage/cache_storage_manager.h" +#include "storage/browser/blob/blob_data_builder.h" +#include "storage/browser/blob/blob_impl.h" +#include "storage/browser/blob/blob_storage_context.h" +#include "third_party/blink/public/common/blob/blob_utils.h" + +namespace content { + +CacheStorageCacheEntryHandler::BlobDataHandle::BlobDataHandle( + base::WeakPtr<CacheStorageCacheEntryHandler> entry_handler, + CacheStorageCacheHandle cache_handle, + disk_cache::ScopedEntryPtr entry) + : entry_handler_(std::move(entry_handler)), + cache_handle_(std::move(cache_handle)), + entry_(std::move(entry)) {} + +bool CacheStorageCacheEntryHandler::BlobDataHandle::IsValid() { + return entry_ != nullptr; +} + +void CacheStorageCacheEntryHandler::BlobDataHandle::Invalidate() { + cache_handle_ = base::nullopt; + entry_handler_ = nullptr; + entry_ = nullptr; +} + +CacheStorageCacheEntryHandler::BlobDataHandle::~BlobDataHandle() { + if (entry_handler_) + entry_handler_->EraseBlobDataHandle(this); +} + +PutContext::PutContext(std::unique_ptr<ServiceWorkerFetchRequest> request, + blink::mojom::FetchAPIResponsePtr response, + blink::mojom::BlobPtr blob, + uint64_t blob_size, + blink::mojom::BlobPtr side_data_blob, + uint64_t side_data_blob_size) + : request(std::move(request)), + response(std::move(response)), + blob(std::move(blob)), + blob_size(blob_size), + side_data_blob(std::move(side_data_blob)), + side_data_blob_size(side_data_blob_size) {} + +PutContext::~PutContext() = default; + +// Default implemetation of CacheStorageCacheEntryHandler. +class CacheStorageCacheEntryHandlerImpl : public CacheStorageCacheEntryHandler { + public: + CacheStorageCacheEntryHandlerImpl( + base::WeakPtr<storage::BlobStorageContext> blob_context) + : CacheStorageCacheEntryHandler(std::move(blob_context)) {} + ~CacheStorageCacheEntryHandlerImpl() override = default; + + std::unique_ptr<PutContext> CreatePutContext( + std::unique_ptr<ServiceWorkerFetchRequest> request, + blink::mojom::FetchAPIResponsePtr response) override { + blink::mojom::BlobPtr blob; + uint64_t blob_size = blink::BlobUtils::kUnknownSize; + blink::mojom::BlobPtr side_data_blob; + uint64_t side_data_blob_size = blink::BlobUtils::kUnknownSize; + + if (response->blob) { + blob.Bind(std::move(response->blob->blob)); + blob_size = response->blob->size; + } + if (response->side_data_blob) { + side_data_blob.Bind(std::move(response->side_data_blob->blob)); + side_data_blob_size = response->side_data_blob->size; + } + + return std::make_unique<PutContext>( + std::move(request), std::move(response), std::move(blob), blob_size, + std::move(side_data_blob), side_data_blob_size); + } + + void PopulateResponseBody(CacheStorageCacheHandle handle, + disk_cache::ScopedEntryPtr entry, + blink::mojom::FetchAPIResponse* response) override { + // Create a blob with the response body data. + response->blob = blink::mojom::SerializedBlob::New(); + response->blob->size = + entry->GetDataSize(CacheStorageCache::INDEX_RESPONSE_BODY); + response->blob->uuid = base::GenerateGUID(); + auto blob_data = + std::make_unique<storage::BlobDataBuilder>(response->blob->uuid); + + disk_cache::Entry* temp_entry = entry.get(); + auto data_handle = + base::MakeRefCounted<CacheStorageCacheEntryHandler::BlobDataHandle>( + weak_ptr_factory_.GetWeakPtr(), std::move(handle), + std::move(entry)); + blob_data_handles_.insert(data_handle.get()); + blob_data->AppendDiskCacheEntryWithSideData( + std::move(data_handle), temp_entry, + CacheStorageCache::INDEX_RESPONSE_BODY, + CacheStorageCache::INDEX_SIDE_DATA); + auto blob_handle = blob_context_->AddFinishedBlob(std::move(blob_data)); + + storage::BlobImpl::Create(std::move(blob_handle), + MakeRequest(&response->blob->blob)); + } + + void PopulateRequestBody(CacheStorageCacheHandle handle, + disk_cache::ScopedEntryPtr entry, + blink::mojom::FetchAPIRequest* request) override {} +}; + +CacheStorageCacheEntryHandler::CacheStorageCacheEntryHandler( + base::WeakPtr<storage::BlobStorageContext> blob_context) + : blob_context_(blob_context), weak_ptr_factory_(this) {} + +CacheStorageCacheEntryHandler::~CacheStorageCacheEntryHandler() = default; + +void CacheStorageCacheEntryHandler::InvalidateBlobDataHandles() { + // Calling Invalidate() can cause the CacheStorageCacheEntryHandler to be + // destroyed. Be careful not to touch |this| after calling Invalidate(). + std::set<BlobDataHandle*> handles = std::move(blob_data_handles_); + for (auto* handle : handles) + handle->Invalidate(); +} + +void CacheStorageCacheEntryHandler::EraseBlobDataHandle( + BlobDataHandle* handle) { + DCHECK_NE(blob_data_handles_.count(handle), 0u); + blob_data_handles_.erase(handle); +} + +// static +std::unique_ptr<CacheStorageCacheEntryHandler> +CacheStorageCacheEntryHandler::CreateCacheEntryHandler( + CacheStorageOwner owner, + base::WeakPtr<storage::BlobStorageContext> blob_context) { + return std::make_unique<CacheStorageCacheEntryHandlerImpl>( + std::move(blob_context)); +} + +} // namespace content
diff --git a/content/browser/cache_storage/cache_storage_cache_entry_handler.h b/content/browser/cache_storage/cache_storage_cache_entry_handler.h new file mode 100644 index 0000000..8922028 --- /dev/null +++ b/content/browser/cache_storage/cache_storage_cache_entry_handler.h
@@ -0,0 +1,121 @@ +// 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 CONTENT_BROWSER_CACHE_STORAGE_CACHE_STORAGE_CACHE_ENTRY_HANDLER_H_ +#define CONTENT_BROWSER_CACHE_STORAGE_CACHE_STORAGE_CACHE_ENTRY_HANDLER_H_ + +#include <memory> +#include <set> + +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "content/browser/cache_storage/cache_storage_cache_handle.h" +#include "content/common/content_export.h" +#include "net/disk_cache/disk_cache.h" +#include "storage/browser/blob/blob_data_builder.h" +#include "third_party/blink/public/platform/modules/cache_storage/cache_storage.mojom.h" + +namespace storage { +class BlobStorageContext; +} // namespace storage + +namespace content { + +enum class CacheStorageOwner; +struct ServiceWorkerFetchRequest; + +// The state needed to pass when writing to a cache. +struct PutContext { + using ErrorCallback = + base::OnceCallback<void(blink::mojom::CacheStorageError)>; + + PutContext(std::unique_ptr<ServiceWorkerFetchRequest> request, + blink::mojom::FetchAPIResponsePtr response, + blink::mojom::BlobPtr blob, + uint64_t blob_size, + blink::mojom::BlobPtr side_data_blob, + uint64_t side_data_blob_size); + + ~PutContext(); + + // Provided by the constructor. + std::unique_ptr<ServiceWorkerFetchRequest> request; + blink::mojom::FetchAPIResponsePtr response; + blink::mojom::BlobPtr blob; + uint64_t blob_size; + blink::mojom::BlobPtr side_data_blob; + uint64_t side_data_blob_size; + + // Provided while writing to the cache. + ErrorCallback callback; + disk_cache::ScopedEntryPtr cache_entry; + + private: + DISALLOW_COPY_AND_ASSIGN(PutContext); +}; + +class CONTENT_EXPORT CacheStorageCacheEntryHandler { + public: + // This class ensures that the cache and the entry have a lifetime as long as + // the blob that is created to contain them. + class BlobDataHandle : public storage::BlobDataBuilder::DataHandle { + public: + BlobDataHandle(base::WeakPtr<CacheStorageCacheEntryHandler> entry_handler, + CacheStorageCacheHandle cache_handle, + disk_cache::ScopedEntryPtr entry); + + bool IsValid() override; + + void Invalidate(); + + private: + ~BlobDataHandle() override; + + base::WeakPtr<CacheStorageCacheEntryHandler> entry_handler_; + base::Optional<CacheStorageCacheHandle> cache_handle_; + disk_cache::ScopedEntryPtr entry_; + + DISALLOW_COPY_AND_ASSIGN(BlobDataHandle); + }; + + virtual ~CacheStorageCacheEntryHandler(); + + virtual std::unique_ptr<PutContext> CreatePutContext( + std::unique_ptr<ServiceWorkerFetchRequest>, + blink::mojom::FetchAPIResponsePtr response) = 0; + virtual void PopulateResponseBody( + CacheStorageCacheHandle handle, + disk_cache::ScopedEntryPtr entry, + blink::mojom::FetchAPIResponse* response) = 0; + virtual void PopulateRequestBody(CacheStorageCacheHandle handle, + disk_cache::ScopedEntryPtr entry, + blink::mojom::FetchAPIRequest* request) = 0; + + static std::unique_ptr<CacheStorageCacheEntryHandler> CreateCacheEntryHandler( + CacheStorageOwner owner, + base::WeakPtr<storage::BlobStorageContext> blob_context); + + void InvalidateBlobDataHandles(); + + void EraseBlobDataHandle(BlobDataHandle* handle); + + protected: + CacheStorageCacheEntryHandler( + base::WeakPtr<storage::BlobStorageContext> blob_context); + + base::WeakPtr<storage::BlobStorageContext> blob_context_; + + // We keep track of the BlobDataHandle instances to allow us to invalidate + // them if the cache has to be deleted while there are still references to + // data in it. + std::set<BlobDataHandle*> blob_data_handles_; + + base::WeakPtrFactory<CacheStorageCacheEntryHandler> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(CacheStorageCacheEntryHandler); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_CACHE_STORAGE_CACHE_STORAGE_CACHE_ENTRY_HANDLER_H_
diff --git a/content/browser/frame_host/navigation_controller_impl.cc b/content/browser/frame_host/navigation_controller_impl.cc index d830713..4c3c161 100644 --- a/content/browser/frame_host/navigation_controller_impl.cc +++ b/content/browser/frame_host/navigation_controller_impl.cc
@@ -2799,7 +2799,7 @@ params.load_type == LOAD_TYPE_HTTP_POST ? "POST" : "GET", params.post_data, base::Optional<SourceLocation>(), params.started_from_context_menu, has_user_gesture, InitiatorCSPInfo(), - std::string(), params.input_start); + params.href_translate, params.input_start); RequestNavigationParams request_params( override_user_agent, params.redirect_chain, common_params.url,
diff --git a/content/browser/frame_host/navigator.h b/content/browser/frame_host/navigator.h index a02d2e9..5d81f7a 100644 --- a/content/browser/frame_host/navigator.h +++ b/content/browser/frame_host/navigator.h
@@ -112,6 +112,7 @@ bool should_replace_current_entry, bool user_gesture, blink::WebTriggeringEventInfo triggering_event_info, + const std::string& href_translate, scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory) {} // Called when a document requests a navigation in another document through a
diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc index bc8a8e08..fb60e94 100644 --- a/content/browser/frame_host/navigator_impl.cc +++ b/content/browser/frame_host/navigator_impl.cc
@@ -392,6 +392,7 @@ bool should_replace_current_entry, bool user_gesture, blink::WebTriggeringEventInfo triggering_event_info, + const std::string& href_translate, scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory) { // Note: This can be called for subframes (even when OOPIFs are not possible) // if the disposition calls for a different window. @@ -463,6 +464,7 @@ } params.blob_url_loader_factory = std::move(blob_url_loader_factory); + params.href_translate = href_translate; GetContentClient()->browser()->OverrideNavigationParams( current_site_instance, ¶ms.transition, ¶ms.is_renderer_initiated,
diff --git a/content/browser/frame_host/navigator_impl.h b/content/browser/frame_host/navigator_impl.h index cfc5634..89f8f323 100644 --- a/content/browser/frame_host/navigator_impl.h +++ b/content/browser/frame_host/navigator_impl.h
@@ -68,6 +68,7 @@ bool should_replace_current_entry, bool user_gesture, blink::WebTriggeringEventInfo triggering_event_info, + const std::string& href_translate, scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory) override; void NavigateFromFrameProxy(
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index abb6239..ec2bfc8 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -1970,7 +1970,8 @@ this, validated_url, params.uses_post, params.resource_request_body, params.extra_headers, params.referrer, params.disposition, params.should_replace_current_entry, params.user_gesture, - params.triggering_event_info, std::move(blob_url_loader_factory)); + params.triggering_event_info, params.href_translate, + std::move(blob_url_loader_factory)); } void RenderFrameHostImpl::CancelInitialHistoryLoad() {
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc index e3660e5..591a42a 100644 --- a/content/browser/renderer_host/compositor_impl_android.cc +++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -1009,7 +1009,7 @@ host_->SetNeedsAnimate(); } -void CompositorImpl::UpdateLayerTreeHost() { +void CompositorImpl::UpdateLayerTreeHost(bool record_main_frame_metrics) { client_->UpdateLayerTreeHost(); if (needs_animate_) { needs_animate_ = false;
diff --git a/content/browser/renderer_host/compositor_impl_android.h b/content/browser/renderer_host/compositor_impl_android.h index 5cabb3d..276577fe 100644 --- a/content/browser/renderer_host/compositor_impl_android.h +++ b/content/browser/renderer_host/compositor_impl_android.h
@@ -113,7 +113,7 @@ void BeginMainFrame(const viz::BeginFrameArgs& args) override {} void BeginMainFrameNotExpectedSoon() override {} void BeginMainFrameNotExpectedUntil(base::TimeTicks time) override {} - void UpdateLayerTreeHost() override; + void UpdateLayerTreeHost(bool record_main_frame_metrics) override; void ApplyViewportChanges(const cc::ApplyViewportChangesArgs& args) override { } void RecordWheelAndTouchScrollingCount(bool has_scrolled_by_wheel,
diff --git a/content/browser/security_exploit_browsertest.cc b/content/browser/security_exploit_browsertest.cc index 04581a9..4554f1e 100644 --- a/content/browser/security_exploit_browsertest.cc +++ b/content/browser/security_exploit_browsertest.cc
@@ -113,7 +113,7 @@ wc->GetFrameTree()->root()->current_frame_host(), extension_url, false, nullptr, std::string(), Referrer(), WindowOpenDisposition::CURRENT_TAB, false, true, blink::WebTriggeringEventInfo::kFromTrustedEvent, - nullptr /* blob_url_loader_factory */); + std::string(), nullptr /* blob_url_loader_factory */); // Since the navigation above requires a cross-process swap, there will be a // speculative/pending RenderFrameHost. Ensure it exists and is in a different
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 359a204..1cf8b6f3 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -1391,7 +1391,11 @@ } bool WebContentsImpl::IsWaitingForResponse() const { - return waiting_for_response_ && is_load_to_different_document_; + NavigationRequest* ongoing_navigation_request = + frame_tree_.root()->navigation_request(); + + // An ongoing navigation request means we're waiting for a response. + return ongoing_navigation_request != nullptr; } const net::LoadStateWithParam& WebContentsImpl::GetLoadState() const {
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index b7ba920..167f009 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h
@@ -1482,6 +1482,7 @@ // Indicates whether the current load is to a different document. Only valid // if |is_loading_| is true and only tracks loads in the main frame. + // TODO(pbos): Check navigation requests and handles instead of caching this. bool is_load_to_different_document_; // Indicates if the tab is considered crashed.
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h index 8984848f..b0635bb4 100644 --- a/content/common/frame_messages.h +++ b/content/common/frame_messages.h
@@ -573,6 +573,7 @@ IPC_STRUCT_MEMBER(bool, is_history_navigation_in_new_child) IPC_STRUCT_MEMBER(blink::WebTriggeringEventInfo, triggering_event_info) IPC_STRUCT_MEMBER(mojo::MessagePipeHandle, blob_url_token) + IPC_STRUCT_MEMBER(std::string, href_translate) IPC_STRUCT_END() IPC_STRUCT_BEGIN(FrameHostMsg_DownloadUrl_Params)
diff --git a/content/public/browser/navigation_controller.h b/content/public/browser/navigation_controller.h index 120151f2..4a9ba1f 100644 --- a/content/public/browser/navigation_controller.h +++ b/content/public/browser/navigation_controller.h
@@ -207,6 +207,11 @@ // is used by embedders where the activation has occurred outside the page. WasActivatedOption was_activated; + // If this navigation was initiated from a link that specified the + // hrefTranslate attribute, this contains the attribute's value (a BCP47 + // language code). Empty otherwise. + std::string href_translate; + explicit LoadURLParams(const GURL& url); ~LoadURLParams();
diff --git a/content/public/browser/page_navigator.h b/content/public/browser/page_navigator.h index 801566bf..cb1cac3 100644 --- a/content/public/browser/page_navigator.h +++ b/content/public/browser/page_navigator.h
@@ -116,6 +116,11 @@ // possible, i.e. if an app for the URL is installed. bool open_app_window_if_possible; + // If this navigation was initiated from a link that specified the + // hrefTranslate attribute, this contains the attribute's value (a BCP47 + // language code). Empty otherwise. + std::string href_translate; + private: OpenURLParams(); };
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index a75f9680..5929fdb 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc
@@ -184,6 +184,7 @@ // Causes the implementations of guests (inner WebContents) to use // out-of-process iframes. +// TODO(533069): Remove once BrowserPlugin is removed. const base::Feature kGuestViewCrossProcessFrames{ "GuestViewCrossProcessFrames", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/content/public/test/render_view_test.cc b/content/public/test/render_view_test.cc index 4e329d4..9c37de4c 100644 --- a/content/public/test/render_view_test.cc +++ b/content/public/test/render_view_test.cc
@@ -226,7 +226,8 @@ // The load actually happens asynchronously, so we pump messages to process // the pending continuation. FrameLoadWaiter(view_->GetMainRenderFrame()).Wait(); - view_->GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + view_->GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases( + blink::WebWidget::LifecycleUpdateReason::kTest); } void RenderViewTest::LoadHTMLWithUrlOverride(const char* html, @@ -236,7 +237,8 @@ // The load actually happens asynchronously, so we pump messages to process // the pending continuation. FrameLoadWaiter(view_->GetMainRenderFrame()).Wait(); - view_->GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + view_->GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases( + blink::WebWidget::LifecycleUpdateReason::kTest); } PageState RenderViewTest::GetCurrentPageState() { @@ -573,7 +575,8 @@ static_cast<TestRenderFrame*>(impl->GetMainRenderFrame()); frame->Navigate(common_params, RequestNavigationParams()); FrameLoadWaiter(frame).Wait(); - view_->GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + view_->GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases( + blink::WebWidget::LifecycleUpdateReason::kTest); } void RenderViewTest::Resize(gfx::Size new_size, @@ -725,7 +728,8 @@ // The load actually happens asynchronously, so we pump messages to process // the pending continuation. FrameLoadWaiter(frame).Wait(); - view_->GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + view_->GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases( + blink::WebWidget::LifecycleUpdateReason::kTest); } } // namespace content
diff --git a/content/renderer/browser_plugin/browser_plugin.h b/content/renderer/browser_plugin/browser_plugin.h index 9f42976..233f746 100644 --- a/content/renderer/browser_plugin/browser_plugin.h +++ b/content/renderer/browser_plugin/browser_plugin.h
@@ -111,7 +111,8 @@ bool SupportsEditCommands() const override; bool SupportsInputMethod() const override; bool CanProcessDrag() const override; - void UpdateAllLifecyclePhases() override {} + void UpdateAllLifecyclePhases( + blink::WebWidget::LifecycleUpdateReason) override {} void Paint(cc::PaintCanvas* canvas, const blink::WebRect& rect) override {} void UpdateGeometry(const blink::WebRect& window_rect, const blink::WebRect& clip_rect,
diff --git a/content/renderer/gpu/layer_tree_view.cc b/content/renderer/gpu/layer_tree_view.cc index ccf7fddf..cccbfea 100644 --- a/content/renderer/gpu/layer_tree_view.cc +++ b/content/renderer/gpu/layer_tree_view.cc
@@ -508,7 +508,7 @@ // frame, but the compositor does not support this. In this case, we only // run blink's lifecycle updates. delegate_->BeginMainFrame(base::TimeTicks::Now()); - delegate_->UpdateVisualState(); + delegate_->UpdateVisualState(false /* record_main_frame_metrics */); return; } @@ -645,8 +645,8 @@ web_main_thread_scheduler_->BeginMainFrameNotExpectedUntil(time); } -void LayerTreeView::UpdateLayerTreeHost() { - delegate_->UpdateVisualState(); +void LayerTreeView::UpdateLayerTreeHost(bool record_main_frame_metrics) { + delegate_->UpdateVisualState(record_main_frame_metrics); } void LayerTreeView::ApplyViewportChanges(
diff --git a/content/renderer/gpu/layer_tree_view.h b/content/renderer/gpu/layer_tree_view.h index 804d429..4d4a038 100644 --- a/content/renderer/gpu/layer_tree_view.h +++ b/content/renderer/gpu/layer_tree_view.h
@@ -191,7 +191,7 @@ void BeginMainFrame(const viz::BeginFrameArgs& args) override; void BeginMainFrameNotExpectedSoon() override; void BeginMainFrameNotExpectedUntil(base::TimeTicks time) override; - void UpdateLayerTreeHost() override; + void UpdateLayerTreeHost(bool record_main_frame_metrics) override; void ApplyViewportChanges(const cc::ApplyViewportChangesArgs& args) override; void RecordWheelAndTouchScrollingCount(bool has_scrolled_by_wheel, bool has_scrolled_by_touch) override;
diff --git a/content/renderer/gpu/layer_tree_view_delegate.h b/content/renderer/gpu/layer_tree_view_delegate.h index dba666a6..06dfd95 100644 --- a/content/renderer/gpu/layer_tree_view_delegate.h +++ b/content/renderer/gpu/layer_tree_view_delegate.h
@@ -68,8 +68,9 @@ virtual void RequestScheduleAnimation() = 0; // Requests a visual frame-based update to the state of the delegate if there - // an update available. - virtual void UpdateVisualState() = 0; + // is an update available. |record_main_frame_metrics| will be true if + // this is a main frame for which we want metrics. + virtual void UpdateVisualState(bool record_main_frame_metrics) = 0; // Indicates that the compositor is about to begin a frame. This is primarily // to signal to flow control mechanisms that a frame is beginning, not to
diff --git a/content/renderer/media/stream/media_stream_audio_processor.cc b/content/renderer/media/stream/media_stream_audio_processor.cc index c13de25..d680a24 100644 --- a/content/renderer/media/stream/media_stream_audio_processor.cc +++ b/content/renderer/media/stream/media_stream_audio_processor.cc
@@ -674,6 +674,8 @@ base::FeatureList::IsEnabled(features::kWebRtcHybridAgc); apm_config.gain_controller2.fixed_digital.gain_db = 0.f; + apm_config.gain_controller2.adaptive_digital.enabled = true; + const bool use_peaks_not_rms = base::GetFieldTrialParamByFeatureAsBool( features::kWebRtcHybridAgc, "use_peaks_not_rms", false); using Shortcut =
diff --git a/content/renderer/media/stream/media_stream_constraints_util.cc b/content/renderer/media/stream/media_stream_constraints_util.cc index 3652c2c..6bcb49d 100644 --- a/content/renderer/media/stream/media_stream_constraints_util.cc +++ b/content/renderer/media/stream/media_stream_constraints_util.cc
@@ -126,12 +126,10 @@ max_frame_rate_(max_frame_rate) { DCHECK(!min_frame_rate || *min_frame_rate_ <= capture_params.requested_format.frame_rate); - // TODO(crbug.com/854980): Update these DCHECKS to allow for unspecified - // target size. - DCHECK(track_adapter_settings.target_size() && + DCHECK(!track_adapter_settings.target_size() || track_adapter_settings.target_size()->width() <= capture_params.requested_format.frame_size.width()); - DCHECK(track_adapter_settings_.target_size() && + DCHECK(!track_adapter_settings_.target_size() || track_adapter_settings_.target_size()->height() <= capture_params.requested_format.frame_size.height()); }
diff --git a/content/renderer/media/stream/media_stream_constraints_util_audio.cc b/content/renderer/media/stream/media_stream_constraints_util_audio.cc index 0444aff..99a41b43 100644 --- a/content/renderer/media/stream/media_stream_constraints_util_audio.cc +++ b/content/renderer/media/stream/media_stream_constraints_util_audio.cc
@@ -26,77 +26,47 @@ namespace content { using EchoCancellationType = AudioProcessingProperties::EchoCancellationType; +using ConstraintSet = blink::WebMediaTrackConstraintSet; +using StringConstraint = blink::StringConstraint; +using BooleanConstraint = blink::BooleanConstraint; namespace { template <class T> using DiscreteSet = media_constraints::DiscreteSet<T>; -enum BoolConstraint { - // Constraints not related to audio processing. - HOTWORD_ENABLED, - DISABLE_LOCAL_ECHO, - RENDER_TO_ASSOCIATED_SINK, +// The presence of a MediaStreamAudioSource object indicates whether the source +// in question is currently in use, or not. This convenience enum helps identify +// whether a source is available and if so whether has audio processing enabled +// or disabled. +enum class SourceType { kNoSource, kUnprocessedSource, kProcessedSource }; - // Constraints that enable/disable audio processing. - ECHO_CANCELLATION, - GOOG_ECHO_CANCELLATION, +// This class encapsulates two values that together build up the score of each +// processed candidate. +// - Fitness, similarly defined by the W3C specification +// (https://w3c.github.io/mediacapture-main/#dfn-fitness-distance); +// - Distance from the default device ID. +// +// Differently from the definition in the W3C specification, the present +// algorithm maximizes the score. +struct Score { + public: + explicit Score(double fitness, bool is_default_device_id = false) { + score = std::make_tuple(fitness, is_default_device_id); + } - // Constraints that control audio-processing behavior. - GOOG_AUDIO_MIRRORING, - GOOG_AUTO_GAIN_CONTROL, - GOOG_EXPERIMENTAL_ECHO_CANCELLATION, - GOOG_TYPING_NOISE_DETECTION, - GOOG_NOISE_SUPPRESSION, - GOOG_EXPERIMENTAL_NOISE_SUPPRESSION, - GOOG_HIGHPASS_FILTER, - GOOG_EXPERIMENTAL_AUTO_GAIN_CONTROL, - NUM_BOOL_CONSTRAINTS + bool operator<(const Score& other) const { return score < other.score; } + + Score& operator+=(const Score& other) { + std::get<0>(score) += std::get<0>(other.score); + std::get<1>(score) |= std::get<1>(other.score); + + return *this; + } + + std::tuple<double, bool> score; }; -// This struct groups related fields or entries from AudioProcessingProperties, -// SingleDeviceCandidateSet::bool_sets_ and blink::WebMediaTrackConstraintSet. -struct AudioPropertyConstraintPair { - bool AudioProcessingProperties::* audio_property; - BoolConstraint bool_set_index; -}; - -// Boolean audio properties that are mapped directly to a boolean constraint -// and which are subject to the same processing. -const AudioPropertyConstraintPair kAudioPropertyConstraintMap[] = { - {&AudioProcessingProperties::goog_auto_gain_control, - GOOG_AUTO_GAIN_CONTROL}, - {&AudioProcessingProperties::goog_experimental_echo_cancellation, - GOOG_EXPERIMENTAL_ECHO_CANCELLATION}, - {&AudioProcessingProperties::goog_typing_noise_detection, - GOOG_TYPING_NOISE_DETECTION}, - {&AudioProcessingProperties::goog_noise_suppression, - GOOG_NOISE_SUPPRESSION}, - {&AudioProcessingProperties::goog_experimental_noise_suppression, - GOOG_EXPERIMENTAL_NOISE_SUPPRESSION}, - {&AudioProcessingProperties::goog_highpass_filter, GOOG_HIGHPASS_FILTER}, - {&AudioProcessingProperties::goog_experimental_auto_gain_control, - GOOG_EXPERIMENTAL_AUTO_GAIN_CONTROL}}; - -// Selects the best value from the nonempty |set|, subject to |constraint| and -// determines the associated fitness. The first selection criteria is equality -// to |constraint.Ideal()|, followed by equality to |default_value|. There is -// always a single best value. -std::tuple<bool, double> SelectBoolAndFitness( - const DiscreteSet<bool>& set, - const blink::BooleanConstraint& constraint, - bool default_value) { - DCHECK(!set.IsEmpty()); - if (constraint.HasIdeal() && set.Contains(constraint.Ideal())) - return std::make_tuple(constraint.Ideal(), 1.0); - - if (set.is_universal()) - return std::make_tuple(default_value, 0.0); - - DCHECK_EQ(set.elements().size(), 1U); - return std::make_tuple(set.FirstElement(), 0.0); -} - // Selects the best value from the nonempty |set|, subject to |constraint|. The // only decision criteria is equality to |constraint.Ideal()|. If there is no // single best value in |set|, returns nullopt. @@ -114,279 +84,246 @@ return set.FirstElement(); } -// Selects the best value from the nonempty |set|, subject to |constraint| and -// determines the associated fitness. The first selection criteria is inclusion -// in |constraint.Ideal()|, followed by equality to |default_value|. There is -// always a single best value. -std::tuple<std::string, double> SelectStringAndFitness( - const DiscreteSet<std::string>& set, - const blink::StringConstraint& constraint, - const std::string& default_value) { - DCHECK(!set.IsEmpty()); - - if (constraint.HasIdeal()) { - for (const blink::WebString& ideal_candidate : constraint.Ideal()) { - std::string candidate = ideal_candidate.Utf8(); - if (set.Contains(candidate)) - return std::make_tuple(candidate, 1.0); - } - } - - if (set.Contains(default_value)) - return std::make_tuple(default_value, 0.0); - - return std::make_tuple(set.FirstElement(), 0.0); -} - -bool SelectUseEchoCancellation(base::Optional<bool> echo_cancellation, - base::Optional<bool> goog_echo_cancellation, - bool is_device_capture) { - DCHECK(echo_cancellation && goog_echo_cancellation - ? *echo_cancellation == *goog_echo_cancellation - : true); - if (echo_cancellation) - return *echo_cancellation; - if (goog_echo_cancellation) - return *goog_echo_cancellation; - - // Echo cancellation is enabled by default for device capture and disabled by - // default for content capture. - return is_device_capture; -} - -std::vector<std::string> GetEchoCancellationTypesFromParameters( - const media::AudioParameters& audio_parameters) { - if (audio_parameters.effects() & - (media::AudioParameters::EXPERIMENTAL_ECHO_CANCELLER | - media::AudioParameters::ECHO_CANCELLER)) { - // If the system/hardware supports echo cancellation, return all echo - // cancellers. - return {blink::kEchoCancellationTypeBrowser, - blink::kEchoCancellationTypeAec3, - blink::kEchoCancellationTypeSystem}; - } - - // The browser and AEC3 echo cancellers are always available. - return {blink::kEchoCancellationTypeBrowser, - blink::kEchoCancellationTypeAec3}; -} - -// This class represents all the candidates settings for a single audio device. -class SingleDeviceCandidateSet { +// Container for each independent boolean constrainable property. +class BooleanContainer { public: - explicit SingleDeviceCandidateSet( - const AudioDeviceCaptureCapability& capability) - : parameters_(capability.Parameters()) { - // If empty, all values for the deviceId constraint are allowed and - // |device_id_set_| is the universal set. Otherwise, limit |device_id_set_| - // to the known device ID. - if (!capability.DeviceID().empty()) - device_id_set_ = DiscreteSet<std::string>({capability.DeviceID()}); + BooleanContainer(DiscreteSet<bool> allowed_values = DiscreteSet<bool>()) + : allowed_values_(std::move(allowed_values)) {} - if (!capability.GroupID().empty()) - group_id_set_ = DiscreteSet<std::string>({capability.GroupID()}); + const char* ApplyConstraintSet(const BooleanConstraint& constraint) { + allowed_values_ = allowed_values_.Intersection( + media_constraints::BoolSetFromConstraint(constraint)); + return allowed_values_.IsEmpty() ? constraint.GetName() : nullptr; + } - MediaStreamAudioSource* source = capability.source(); + std::tuple<double, bool> SelectSettingsAndScore( + const BooleanConstraint& constraint, + bool default_setting) const { + DCHECK(!IsEmpty()); - // Set up echo cancellation types. Depending on if we have a source or not - // it's set up differently. - if (!source) { - echo_cancellation_type_set_ = DiscreteSet<std::string>( - GetEchoCancellationTypesFromParameters(parameters_)); + if (constraint.HasIdeal() && allowed_values_.Contains(constraint.Ideal())) + return std::make_tuple(1.0, constraint.Ideal()); + + if (allowed_values_.is_universal()) + return std::make_tuple(0.0, default_setting); + + DCHECK_EQ(allowed_values_.elements().size(), 1U); + return std::make_tuple(0.0, allowed_values_.FirstElement()); + } + + bool IsEmpty() const { return allowed_values_.IsEmpty(); } + + private: + DiscreteSet<bool> allowed_values_; +}; + +// Container for each independent string constrainable property. +class StringContainer { + public: + explicit StringContainer( + DiscreteSet<std::string> allowed_values = DiscreteSet<std::string>()) + : allowed_values_(std::move(allowed_values)) {} + + const char* ApplyConstraintSet(const StringConstraint& constraint) { + allowed_values_ = allowed_values_.Intersection( + media_constraints::StringSetFromConstraint(constraint)); + return allowed_values_.IsEmpty() ? constraint.GetName() : nullptr; + } + + // Selects the best value from the nonempty |allowed_values_|, subject to + // |constraint_set.*constraint_member_| and determines the associated fitness. + // The first selection criteria is inclusion in the constraint's ideal value, + // followed by equality to |default_value|. There is always a single best + // value. + std::tuple<double, std::string> SelectSettingsAndScore( + const StringConstraint& constraint, + std::string default_setting) const { + DCHECK(!IsEmpty()); + if (constraint.HasIdeal()) { + for (const blink::WebString& ideal_candidate : constraint.Ideal()) { + std::string candidate = ideal_candidate.Utf8(); + if (allowed_values_.Contains(candidate)) + return std::make_tuple(1.0, candidate); + } + } + + std::string setting = allowed_values_.Contains(default_setting) + ? default_setting + : allowed_values_.FirstElement(); + + return std::make_tuple(0.0, setting); + } + + bool IsEmpty() const { return allowed_values_.IsEmpty(); } + + private: + DiscreteSet<std::string> allowed_values_; +}; + +// Container to manage the properties related to echo cancellation: +// echoCancellation, googEchoCancellation and echoCancellationType. +class EchoCancellationContainer { + public: + EchoCancellationContainer(SourceType source_type, + bool is_device_capture, + media::AudioParameters parameters, + AudioProcessingProperties properties) + : parameters_(parameters), is_device_capture_(is_device_capture) { + if (source_type == SourceType::kNoSource) { + ec_type_allowed_values_ = + GetEchoCancellationTypesFromParameters(parameters); return; } - // Properties not related to audio processing. - bool_sets_[HOTWORD_ENABLED] = - DiscreteSet<bool>({source->hotword_enabled()}); - bool_sets_[DISABLE_LOCAL_ECHO] = - DiscreteSet<bool>({source->disable_local_echo()}); - bool_sets_[RENDER_TO_ASSOCIATED_SINK] = - DiscreteSet<bool>({source->RenderToAssociatedSinkEnabled()}); + ec_allowed_values_ = DiscreteSet<bool>({IsEchoCancellationEnabled( + properties, parameters.effects(), + source_type == SourceType::kProcessedSource)}); + goog_ec_allowed_values_ = ec_allowed_values_; - // Properties related with audio processing. - AudioProcessingProperties properties; - ProcessedLocalAudioSource* processed_source = - ProcessedLocalAudioSource::From(source); - if (processed_source) - properties = processed_source->audio_processing_properties(); - else - properties.DisableDefaultProperties(); + auto type = ToBlinkEchoCancellationType(properties.echo_cancellation_type); + ec_type_allowed_values_ = + type ? DiscreteSet<std::string>({*type}) : DiscreteSet<std::string>(); + } + const char* ApplyConstraintSet(const ConstraintSet& constraint_set) { + ec_allowed_values_ = ec_allowed_values_.Intersection( + media_constraints::BoolSetFromConstraint( + constraint_set.echo_cancellation)); + if (ec_allowed_values_.IsEmpty()) + return constraint_set.echo_cancellation.GetName(); + + goog_ec_allowed_values_ = goog_ec_allowed_values_.Intersection( + media_constraints::BoolSetFromConstraint( + constraint_set.goog_echo_cancellation)); + if (goog_ec_allowed_values_.IsEmpty()) + return constraint_set.goog_echo_cancellation.GetName(); + + // Make sure that the results from googEchoCancellation and echoCancellation + // constraints do not contradict each other. + auto ec_intersection = + ec_allowed_values_.Intersection(goog_ec_allowed_values_); + if (ec_intersection.IsEmpty()) + return constraint_set.echo_cancellation.GetName(); + + ec_type_allowed_values_ = ec_type_allowed_values_.Intersection( + media_constraints::StringSetFromConstraint( + constraint_set.echo_cancellation_type)); + if (ec_type_allowed_values_.IsEmpty()) + return constraint_set.echo_cancellation_type.GetName(); + + // If the echoCancellation constraint is not true, the type set should not + // have explicit elements, otherwise the two constraints would contradict + // each other. + if (!ec_allowed_values_.Contains(true) && + constraint_set.echo_cancellation_type.HasExact()) { + return constraint_set.echo_cancellation_type.GetName(); + } + + return nullptr; + } + + std::tuple<double, EchoCancellationType> SelectSettingsAndScore( + const ConstraintSet& constraint_set) const { + DCHECK(!IsEmpty()); + double fitness = 0.0; + EchoCancellationType echo_cancellation_type = + EchoCancellationType::kEchoCancellationDisabled; + if (ShouldUseEchoCancellation(constraint_set.echo_cancellation, + constraint_set.goog_echo_cancellation)) { + std::tie(echo_cancellation_type, fitness) = + SelectEchoCancellationTypeAndFitness( + constraint_set.echo_cancellation_type); + } + + return std::make_tuple(fitness, echo_cancellation_type); + } + + bool IsEmpty() const { + return ec_allowed_values_.IsEmpty() || goog_ec_allowed_values_.IsEmpty() || + ec_type_allowed_values_.IsEmpty(); + } + + // Audio-processing properties are disabled by default for content capture, + // or if the |echo_cancellation| constraint is false. + void UpdateDefaultValues( + const BooleanConstraint& echo_cancellation_constraint, + AudioProcessingProperties* properties) const { + auto echo_cancellation = + SelectOptionalBool(ec_allowed_values_, echo_cancellation_constraint); + + bool default_audio_processing_value = true; + if (!is_device_capture_ || (echo_cancellation && !*echo_cancellation)) + default_audio_processing_value = false; + + properties->goog_audio_mirroring &= default_audio_processing_value; + properties->goog_auto_gain_control &= default_audio_processing_value; + properties->goog_experimental_echo_cancellation &= + default_audio_processing_value; + properties->goog_typing_noise_detection &= default_audio_processing_value; + properties->goog_noise_suppression &= default_audio_processing_value; + properties->goog_experimental_noise_suppression &= + default_audio_processing_value; + properties->goog_highpass_filter &= default_audio_processing_value; + properties->goog_experimental_auto_gain_control &= + default_audio_processing_value; + } + + private: + static DiscreteSet<std::string> GetEchoCancellationTypesFromParameters( + const media::AudioParameters& audio_parameters) { + // The browser and AEC3 echo cancellers are always available. + std::vector<std::string> types = {blink::kEchoCancellationTypeBrowser, + blink::kEchoCancellationTypeAec3}; + + if (audio_parameters.effects() & + (media::AudioParameters::EXPERIMENTAL_ECHO_CANCELLER | + media::AudioParameters::ECHO_CANCELLER)) { + // If the system/hardware supports echo cancellation, add it to the set. + types.push_back(blink::kEchoCancellationTypeSystem); + } + return DiscreteSet<std::string>(types); + } + + static bool IsEchoCancellationEnabled( + const AudioProcessingProperties& properties, + int effects, + bool is_processed) { const bool system_echo_cancellation_available = (properties.echo_cancellation_type == EchoCancellationType::kEchoCancellationSystem || - !processed_source) && - parameters_.effects() & media::AudioParameters::ECHO_CANCELLER; + !is_processed) && + effects & media::AudioParameters::ECHO_CANCELLER; const bool experimental_system_cancellation_available = properties.echo_cancellation_type == EchoCancellationType::kEchoCancellationSystem && - parameters_.effects() & - media::AudioParameters::EXPERIMENTAL_ECHO_CANCELLER; + effects & media::AudioParameters::EXPERIMENTAL_ECHO_CANCELLER; - const bool system_echo_cancellation_enabled = - system_echo_cancellation_available || - experimental_system_cancellation_available; - - const bool echo_cancellation_enabled = - properties.EchoCancellationIsWebRtcProvided() || - system_echo_cancellation_enabled; - - bool_sets_[ECHO_CANCELLATION] = - DiscreteSet<bool>({echo_cancellation_enabled}); - bool_sets_[GOOG_ECHO_CANCELLATION] = bool_sets_[ECHO_CANCELLATION]; - - if (properties.echo_cancellation_type == - EchoCancellationType::kEchoCancellationAec2) { - echo_cancellation_type_set_ = - DiscreteSet<std::string>({blink::kEchoCancellationTypeBrowser}); - } else if (properties.echo_cancellation_type == - EchoCancellationType::kEchoCancellationAec3) { - echo_cancellation_type_set_ = - DiscreteSet<std::string>({blink::kEchoCancellationTypeAec3}); - } else if (system_echo_cancellation_enabled) { - echo_cancellation_type_set_ = - DiscreteSet<std::string>({blink::kEchoCancellationTypeSystem}); - } - - bool_sets_[GOOG_AUDIO_MIRRORING] = - DiscreteSet<bool>({properties.goog_audio_mirroring}); - - for (auto& entry : kAudioPropertyConstraintMap) { - bool_sets_[entry.bool_set_index] = - DiscreteSet<bool>({properties.*entry.audio_property}); - } - -#if DCHECK_IS_ON() - for (const auto& bool_set : bool_sets_) { - DCHECK(!bool_set.is_universal()); - DCHECK(!bool_set.IsEmpty()); - } -#endif + return properties.EchoCancellationIsWebRtcProvided() || + system_echo_cancellation_available || + experimental_system_cancellation_available; } - // Accessors - const char* failed_constraint_name() const { return failed_constraint_name_; } - const DiscreteSet<std::string>& device_id_set() const { - return device_id_set_; + bool ShouldUseEchoCancellation( + const BooleanConstraint& echo_cancellation_constraint, + const BooleanConstraint& goog_echo_cancellation_constraint) const { + base::Optional<bool> ec = + SelectOptionalBool(ec_allowed_values_, echo_cancellation_constraint); + base::Optional<bool> goog_ec = SelectOptionalBool( + goog_ec_allowed_values_, goog_echo_cancellation_constraint); + + if (ec) + return *ec; + if (goog_ec) + return *goog_ec; + + // Echo cancellation is enabled by default for device capture and disabled + // by default for content capture. + return is_device_capture_; } - bool IsEmpty() const { return failed_constraint_name_ != nullptr; } - - void ApplyConstraintSet( - const blink::WebMediaTrackConstraintSet& constraint_set) { - device_id_set_ = device_id_set_.Intersection( - media_constraints::StringSetFromConstraint(constraint_set.device_id)); - if (device_id_set_.IsEmpty()) { - failed_constraint_name_ = constraint_set.device_id.GetName(); - return; - } - - group_id_set_ = group_id_set_.Intersection( - media_constraints::StringSetFromConstraint(constraint_set.group_id)); - if (group_id_set_.IsEmpty()) { - failed_constraint_name_ = constraint_set.group_id.GetName(); - return; - } - - for (size_t i = 0; i < NUM_BOOL_CONSTRAINTS; ++i) { - bool_sets_[i] = - bool_sets_[i].Intersection(media_constraints::BoolSetFromConstraint( - constraint_set.*kBlinkBoolConstraintFields[i])); - if (bool_sets_[i].IsEmpty()) { - failed_constraint_name_ = - (constraint_set.*kBlinkBoolConstraintFields[i]).GetName(); - return; - } - } - - // echoCancellation and googEchoCancellation constraints should not - // contradict each other. Mark the set as empty if they do. - DiscreteSet<bool> echo_cancellation_intersection = - bool_sets_[ECHO_CANCELLATION].Intersection( - bool_sets_[GOOG_ECHO_CANCELLATION]); - if (echo_cancellation_intersection.IsEmpty()) { - failed_constraint_name_ = - blink::WebMediaTrackConstraintSet().echo_cancellation.GetName(); - return; - } - - echo_cancellation_type_set_ = echo_cancellation_type_set_.Intersection( - media_constraints::StringSetFromConstraint( - constraint_set.echo_cancellation_type)); - if (echo_cancellation_type_set_.IsEmpty()) { - failed_constraint_name_ = constraint_set.echo_cancellation_type.GetName(); - return; - } - - // If echo cancellation constraint is not true, the type set should not have - // explicit elements. - if (!bool_sets_[ECHO_CANCELLATION].Contains(true) && - constraint_set.echo_cancellation_type.HasExact()) { - failed_constraint_name_ = constraint_set.echo_cancellation_type.GetName(); - return; - } - } - - // Returns the settings supported by this SingleDeviceCandidateSet that best - // satisfy the ideal values in |basic_constraint_set| as well as the - // associated fitness, which is based on - // https://w3c.github.io/mediacapture-main/#dfn-fitness-distance - std::tuple<AudioCaptureSettings, double> SelectBestSettingsAndFitness( - const blink::WebMediaTrackConstraintSet& constraint_set, - const std::string& default_device_id, - const std::string& media_stream_source, - bool should_disable_hardware_noise_suppression) const { - double fitness = 0.0; - double sub_fitness; - - // Fitness and setting for the device ID. - std::string device_id; - std::tie(device_id, sub_fitness) = SelectStringAndFitness( - device_id_set_, constraint_set.device_id, default_device_id); - fitness += sub_fitness; - - // Fitness for the group ID. - std::tie(std::ignore, sub_fitness) = - SelectStringAndFitness(group_id_set_, constraint_set.group_id, ""); - fitness += sub_fitness; - - // googHotword, disableLocalEcho, and chromeRenderToAssociatedSink cannot - // have ideal values, hence we explicitely ignore the fitness value for all - // three. - bool hotword_enabled; - std::tie(hotword_enabled, std::ignore) = SelectBoolAndFitness( - bool_sets_[HOTWORD_ENABLED], constraint_set.hotword_enabled, false); - - bool disable_local_echo; - std::tie(disable_local_echo, std::ignore) = SelectBoolAndFitness( - bool_sets_[DISABLE_LOCAL_ECHO], constraint_set.disable_local_echo, - media_stream_source != kMediaStreamSourceDesktop); - - bool render_to_associated_sink; - std::tie(render_to_associated_sink, std::ignore) = - SelectBoolAndFitness(bool_sets_[RENDER_TO_ASSOCIATED_SINK], - constraint_set.render_to_associated_sink, false); - - // Fitness and settings for the properties associated to audio processing. - AudioProcessingProperties audio_processing_properties; - std::tie(audio_processing_properties, sub_fitness) = - SelectAudioProcessingPropertiesAndFitness( - constraint_set, media_stream_source.empty(), - should_disable_hardware_noise_suppression); - fitness += sub_fitness; - - auto settings = AudioCaptureSettings( - std::move(device_id), hotword_enabled, disable_local_echo, - render_to_associated_sink, audio_processing_properties); - return std::make_tuple(settings, fitness); - } - - private: std::tuple<EchoCancellationType, double> SelectEchoCancellationTypeAndFitness( - const blink::StringConstraint& echo_cancellation_type, - const media::AudioParameters& audio_parameters) const { + const blink::StringConstraint& echo_cancellation_type) const { double fitness = 0.0; // Try to use an ideal candidate, if supplied. @@ -394,7 +331,7 @@ if (echo_cancellation_type.HasIdeal()) { for (const auto& ideal : echo_cancellation_type.Ideal()) { std::string candidate = ideal.Utf8(); - if (echo_cancellation_type_set_.Contains(candidate)) { + if (ec_type_allowed_values_.Contains(candidate)) { selected_type = candidate; fitness = 1.0; break; @@ -405,13 +342,13 @@ // If no ideal, or none that worked, and the set contains only one value, // pick that. if (!selected_type) { - if (!echo_cancellation_type_set_.is_universal() && - echo_cancellation_type_set_.elements().size() == 1) { - selected_type = echo_cancellation_type_set_.FirstElement(); + if (!ec_type_allowed_values_.is_universal() && + ec_type_allowed_values_.elements().size() == 1) { + selected_type = ec_type_allowed_values_.FirstElement(); } } - // Return type based the selected type. + // Return type based on the selected type. if (selected_type == blink::kEchoCancellationTypeBrowser) { return std::make_tuple(EchoCancellationType::kEchoCancellationAec2, fitness); @@ -426,8 +363,8 @@ // If no type has been selected, choose system if the device has the // ECHO_CANCELLER flag set. Never automatically enable an experimental // system echo canceller. - if (audio_parameters.IsValid() && - audio_parameters.effects() & media::AudioParameters::ECHO_CANCELLER) { + if (parameters_.IsValid() && + parameters_.effects() & media::AudioParameters::ECHO_CANCELLER) { return std::make_tuple(EchoCancellationType::kEchoCancellationSystem, fitness); } @@ -450,185 +387,349 @@ return std::make_tuple(ec_type, fitness); } - // Returns the audio-processing properties supported by this - // SingleDeviceCandidateSet that best satisfy the ideal values in - // |basic_constraint_set| and the associated fitness. - std::tuple<AudioProcessingProperties, double> - SelectAudioProcessingPropertiesAndFitness( - const blink::WebMediaTrackConstraintSet& constraint_set, - bool is_device_capture, - bool should_disable_hardware_noise_suppression) const { - DCHECK(!IsEmpty()); + base::Optional<std::string> ToBlinkEchoCancellationType( + EchoCancellationType type) const { + switch (type) { + case EchoCancellationType::kEchoCancellationAec2: + return blink::kEchoCancellationTypeBrowser; + case EchoCancellationType::kEchoCancellationAec3: + return blink::kEchoCancellationTypeAec3; + case EchoCancellationType::kEchoCancellationSystem: + return blink::kEchoCancellationTypeSystem; + case EchoCancellationType::kEchoCancellationDisabled: + return base::nullopt; + } + } - base::Optional<bool> echo_cancellation = SelectOptionalBool( - bool_sets_[ECHO_CANCELLATION], constraint_set.echo_cancellation); - // Audio-processing properties are disabled by default for content capture, - // or if the |echo_cancellation| constraint is false. - bool default_audio_processing_value = true; - if (!is_device_capture || (echo_cancellation && !*echo_cancellation)) - default_audio_processing_value = false; + DiscreteSet<bool> ec_allowed_values_; + DiscreteSet<bool> goog_ec_allowed_values_; + DiscreteSet<std::string> ec_type_allowed_values_; + media::AudioParameters parameters_; + bool is_device_capture_; +}; - base::Optional<bool> goog_echo_cancellation = - SelectOptionalBool(bool_sets_[GOOG_ECHO_CANCELLATION], - constraint_set.goog_echo_cancellation); +// Container for the constrainable properties of a single audio device. +class DeviceContainer { + public: + DeviceContainer(const AudioDeviceCaptureCapability& capability, + bool is_device_capture) + : parameters_(capability.Parameters()) { + if (!capability.DeviceID().empty()) + device_id_container_ = + StringContainer(DiscreteSet<std::string>({capability.DeviceID()})); - const bool use_echo_cancellation = SelectUseEchoCancellation( - echo_cancellation, goog_echo_cancellation, is_device_capture); + if (!capability.GroupID().empty()) + group_id_container_ = + StringContainer(DiscreteSet<std::string>({capability.GroupID()})); + // If the device is in use, a source will be provided and all containers + // must be initialized such that their only supported values correspond to + // the source settings. Otherwise, the containers are initialized to contain + // all possible values. + SourceType source_type; AudioProcessingProperties properties; - bool fitness = 0; - bool sub_fitness; + std::tie(source_type, properties) = InfoFromSource(capability.source()); - if (use_echo_cancellation) { - std::tie(properties.echo_cancellation_type, sub_fitness) = - SelectEchoCancellationTypeAndFitness( - constraint_set.echo_cancellation_type, parameters_); - fitness += sub_fitness; - } else { - properties.echo_cancellation_type = - EchoCancellationType::kEchoCancellationDisabled; + echo_cancellation_container_ = EchoCancellationContainer( + source_type, is_device_capture, parameters_, properties); + + if (source_type == SourceType::kNoSource) + return; + + MediaStreamAudioSource* source = capability.source(); + boolean_containers_[kHotwordEnabled] = + BooleanContainer(DiscreteSet<bool>({source->hotword_enabled()})); + + boolean_containers_[kDisableLocalEcho] = + BooleanContainer(DiscreteSet<bool>({source->disable_local_echo()})); + + boolean_containers_[kRenderToAssociatedSink] = BooleanContainer( + DiscreteSet<bool>({source->RenderToAssociatedSinkEnabled()})); + + for (size_t i = kGoogAudioMirroring; i < kNumBooleanContainerIds; ++i) { + auto& info = kBooleanPropertyContainerInfoMap[i]; + boolean_containers_[info.index] = BooleanContainer( + DiscreteSet<bool>({properties.*(info.property_member)})); } + DCHECK(echo_cancellation_container_ != base::nullopt); + DCHECK_EQ(boolean_containers_.size(), kNumBooleanContainerIds); +#if DCHECK_IS_ON() + for (const auto& container : boolean_containers_) + DCHECK(!container.IsEmpty()); +#endif + } + + const char* ApplyConstraintSet(const ConstraintSet& constraint_set) { + const char* failed_constraint_name; + + failed_constraint_name = + device_id_container_.ApplyConstraintSet(constraint_set.device_id); + if (failed_constraint_name != nullptr) + return failed_constraint_name; + + failed_constraint_name = + group_id_container_.ApplyConstraintSet(constraint_set.group_id); + if (failed_constraint_name != nullptr) + return failed_constraint_name; + + for (size_t i = 0; i < kNumBooleanContainerIds; ++i) { + auto& info = kBooleanPropertyContainerInfoMap[i]; + failed_constraint_name = + boolean_containers_[info.index].ApplyConstraintSet( + constraint_set.*(info.constraint_member)); + if (failed_constraint_name != nullptr) + return failed_constraint_name; + } + + failed_constraint_name = + echo_cancellation_container_->ApplyConstraintSet(constraint_set); + if (failed_constraint_name != nullptr) + return failed_constraint_name; + + return nullptr; + } + + std::tuple<double, AudioCaptureSettings> SelectSettingsAndScore( + const ConstraintSet& constraint_set, + bool is_destkop_source, + bool should_disable_hardware_noise_suppression, + std::string default_device_id) const { + DCHECK(!IsEmpty()); + double score = 0.0; + double sub_score = 0.0; + + std::string device_id; + std::tie(sub_score, device_id) = + device_id_container_.SelectSettingsAndScore(constraint_set.device_id, + default_device_id); + score += sub_score; + + std::tie(sub_score, std::ignore) = + group_id_container_.SelectSettingsAndScore(constraint_set.group_id, + std::string()); + score += sub_score; + + bool hotword_enabled; + std::tie(sub_score, hotword_enabled) = + boolean_containers_[kHotwordEnabled].SelectSettingsAndScore( + constraint_set.hotword_enabled, false); + score += sub_score; + + bool disable_local_echo; + std::tie(sub_score, disable_local_echo) = + boolean_containers_[kDisableLocalEcho].SelectSettingsAndScore( + constraint_set.disable_local_echo, !is_destkop_source); + score += sub_score; + + bool render_to_associated_sink; + std::tie(sub_score, render_to_associated_sink) = + boolean_containers_[kRenderToAssociatedSink].SelectSettingsAndScore( + constraint_set.render_to_associated_sink, false); + score += sub_score; + + AudioProcessingProperties properties; + std::tie(sub_score, properties.echo_cancellation_type) = + echo_cancellation_container_->SelectSettingsAndScore(constraint_set); + score += sub_score; + + // NOTE: audio-processing properties are disabled by default for content + // capture, or if the |echo_cancellation| constraint is false. This function + // call updates the default settings for such properties according to the + // value obtained for the echo cancellation property. + echo_cancellation_container_->UpdateDefaultValues( + constraint_set.echo_cancellation, &properties); + + for (size_t i = kGoogAudioMirroring; i < kNumBooleanContainerIds; ++i) { + auto& info = kBooleanPropertyContainerInfoMap[i]; + std::tie(sub_score, properties.*(info.property_member)) = + boolean_containers_[info.index].SelectSettingsAndScore( + constraint_set.*(info.constraint_member), + properties.*(info.property_member)); + score += sub_score; + } + + // NOTE: this is a special case required to support for conditional + // constraint for echo cancellation type based on an experiment. properties.disable_hw_noise_suppression = should_disable_hardware_noise_suppression && properties.echo_cancellation_type == - EchoCancellationType::kEchoCancellationSystem; + EchoCancellationType::kEchoCancellationDisabled; - std::tie(properties.goog_audio_mirroring, sub_fitness) = - SelectBoolAndFitness(bool_sets_[GOOG_AUDIO_MIRRORING], - constraint_set.goog_audio_mirroring, - properties.goog_audio_mirroring); - fitness += sub_fitness; + // The score at this point can be considered complete only when the settings + // are compared against the default device id, which is used as arbitrator + // in case multiple candidates are available. + return std::make_tuple( + score, + AudioCaptureSettings(device_id, hotword_enabled, disable_local_echo, + render_to_associated_sink, properties)); + } - for (auto& entry : kAudioPropertyConstraintMap) { - std::tie(properties.*entry.audio_property, sub_fitness) = - SelectBoolAndFitness( - bool_sets_[entry.bool_set_index], - constraint_set.*kBlinkBoolConstraintFields[entry.bool_set_index], - default_audio_processing_value && - properties.*entry.audio_property); - fitness += sub_fitness; + // The DeviceContainer is considered empty if at least one of the + // containers owned is empty. + bool IsEmpty() const { + DCHECK(!boolean_containers_.empty()); + + for (auto& container : boolean_containers_) { + if (container.IsEmpty()) + return true; } - return std::make_tuple(properties, fitness); + return device_id_container_.IsEmpty() || group_id_container_.IsEmpty() || + echo_cancellation_container_->IsEmpty(); } - static constexpr blink::BooleanConstraint - blink::WebMediaTrackConstraintSet::* const - kBlinkBoolConstraintFields[NUM_BOOL_CONSTRAINTS] = { - &blink::WebMediaTrackConstraintSet::hotword_enabled, - &blink::WebMediaTrackConstraintSet::disable_local_echo, - &blink::WebMediaTrackConstraintSet::render_to_associated_sink, - &blink::WebMediaTrackConstraintSet::echo_cancellation, - &blink::WebMediaTrackConstraintSet::goog_echo_cancellation, - &blink::WebMediaTrackConstraintSet::goog_audio_mirroring, - &blink::WebMediaTrackConstraintSet::goog_auto_gain_control, - &blink::WebMediaTrackConstraintSet:: - goog_experimental_echo_cancellation, - &blink::WebMediaTrackConstraintSet::goog_typing_noise_detection, - &blink::WebMediaTrackConstraintSet::goog_noise_suppression, - &blink::WebMediaTrackConstraintSet:: - goog_experimental_noise_suppression, - &blink::WebMediaTrackConstraintSet::goog_highpass_filter, - &blink::WebMediaTrackConstraintSet:: - goog_experimental_auto_gain_control}; + std::tuple<SourceType, AudioProcessingProperties> InfoFromSource( + MediaStreamAudioSource* source) { + AudioProcessingProperties properties; + SourceType source_type; + ProcessedLocalAudioSource* processed_source = + ProcessedLocalAudioSource::From(source); + if (source == nullptr) { + source_type = SourceType::kNoSource; + } else if (processed_source == nullptr) { + source_type = SourceType::kUnprocessedSource; + properties.DisableDefaultProperties(); + } else { + source_type = SourceType::kProcessedSource; + properties = processed_source->audio_processing_properties(); + } - const char* failed_constraint_name_ = nullptr; - DiscreteSet<std::string> device_id_set_; - DiscreteSet<std::string> group_id_set_; - std::array<DiscreteSet<bool>, NUM_BOOL_CONSTRAINTS> bool_sets_; - DiscreteSet<std::string> echo_cancellation_type_set_; + return std::make_tuple(source_type, properties); + } + + private: + enum StringContainerId { kDeviceId, kGroupId, kNumStringContainerIds }; + + enum BooleanContainerId { + kHotwordEnabled, + kDisableLocalEcho, + kRenderToAssociatedSink, + // Audio processing properties indexes. + kGoogAudioMirroring, + kGoogAutoGainControl, + kGoogExperimentalEchoCancellation, + kGoogTypingNoiseDetection, + kGoogNoiseSuppression, + kGoogExperimentalNoiseSuppression, + kGoogHighpassFilter, + kGoogExperimentalAutoGainControl, + kNumBooleanContainerIds + }; + + // This struct groups related fields or entries from + // AudioProcessingProperties, + // SingleDeviceCandidateSet::bool_sets_ and blink::WebMediaTrackConstraintSet. + struct BooleanPropertyContainerInfo { + BooleanContainerId index; + BooleanConstraint ConstraintSet::*constraint_member; + bool AudioProcessingProperties::*property_member; + }; + + static constexpr BooleanPropertyContainerInfo + kBooleanPropertyContainerInfoMap[] = { + {kHotwordEnabled, &ConstraintSet::hotword_enabled, nullptr}, + {kDisableLocalEcho, &ConstraintSet::disable_local_echo, nullptr}, + {kRenderToAssociatedSink, &ConstraintSet::render_to_associated_sink, + nullptr}, + {kGoogAudioMirroring, &ConstraintSet::goog_audio_mirroring, + &AudioProcessingProperties::goog_audio_mirroring}, + {kGoogAutoGainControl, &ConstraintSet::goog_auto_gain_control, + &AudioProcessingProperties::goog_auto_gain_control}, + {kGoogExperimentalEchoCancellation, + &ConstraintSet::goog_experimental_echo_cancellation, + &AudioProcessingProperties::goog_experimental_echo_cancellation}, + {kGoogTypingNoiseDetection, + &ConstraintSet::goog_typing_noise_detection, + &AudioProcessingProperties::goog_typing_noise_detection}, + {kGoogNoiseSuppression, &ConstraintSet::goog_noise_suppression, + &AudioProcessingProperties::goog_noise_suppression}, + {kGoogExperimentalNoiseSuppression, + &ConstraintSet::goog_experimental_noise_suppression, + &AudioProcessingProperties::goog_experimental_noise_suppression}, + {kGoogHighpassFilter, &ConstraintSet::goog_highpass_filter, + &AudioProcessingProperties::goog_highpass_filter}, + {kGoogExperimentalAutoGainControl, + &ConstraintSet::goog_experimental_auto_gain_control, + &AudioProcessingProperties::goog_experimental_auto_gain_control}}; + media::AudioParameters parameters_; + StringContainer device_id_container_; + StringContainer group_id_container_; + std::array<BooleanContainer, kNumBooleanContainerIds> boolean_containers_; + base::Optional<EchoCancellationContainer> echo_cancellation_container_; }; -constexpr blink::BooleanConstraint blink::WebMediaTrackConstraintSet::* const - SingleDeviceCandidateSet::kBlinkBoolConstraintFields[NUM_BOOL_CONSTRAINTS]; +constexpr DeviceContainer::BooleanPropertyContainerInfo + DeviceContainer::kBooleanPropertyContainerInfoMap[]; -// This class represents a set of possible candidate settings. -// The SelectSettings algorithm starts with a set containing all possible -// candidates based on system/hardware capabilities and/or allowed values for -// supported properties. The set is then reduced progressively as the basic and -// advanced constraint sets are applied. In the end, if the set of candidates is -// empty, SelectSettings fails. If not, the ideal values (if any) or tie breaker -// rules are used to select the final settings based on the candidates that -// survived the application of the constraint sets. This class is implemented as -// a collection of more specific sets for the various supported properties. If -// any of the specific sets is empty, the whole AudioCaptureCandidates set is -// considered empty as well. -class AudioCaptureCandidates { +// This class represents a set of possible candidate settings. The +// SelectSettings algorithm starts with a set containing all possible candidates +// based on system/hardware capabilities and/or allowed values for supported +// properties. The set is then reduced progressively as the basic and advanced +// constraint sets are applied. In the end, if the set of candidates is empty, +// SelectSettings fails. If not, the ideal values (if any) or tie breaker rules +// are used to select the final settings based on the candidates that survived +// the application of the constraint sets. This class is implemented as a +// collection of more specific sets for the various supported properties. If any +// of the specific sets is empty, the whole CandidatesContainer is considered +// empty as well. +class CandidatesContainer { public: - AudioCaptureCandidates( - const blink::WebMediaTrackConstraintSet& constraint_set, - const AudioDeviceCaptureCapabilities& capabilities) { - for (const auto& capability : capabilities) - candidate_sets_.emplace_back(capability); - - ApplyConstraintSet(constraint_set); + CandidatesContainer(const AudioDeviceCaptureCapabilities& capabilities, + std::string& media_stream_source, + std::string& default_device_id) + : default_device_id_(default_device_id) { + for (const auto& capability : capabilities) { + devices_.emplace_back(capability, media_stream_source.empty()); + } } - const char* failed_constraint_name() const { return failed_constraint_name_; } - bool IsEmpty() const { return failed_constraint_name_ != nullptr; } - - void ApplyConstraintSet( - const blink::WebMediaTrackConstraintSet& constraint_set) { - for (auto& candidate_set : candidate_sets_) - candidate_set.ApplyConstraintSet(constraint_set); - - const char* failed_constraint_name = nullptr; - for (auto it = candidate_sets_.begin(); it != candidate_sets_.end();) { - if (it->IsEmpty()) { - DCHECK(it->failed_constraint_name()); - failed_constraint_name = it->failed_constraint_name(); - it = candidate_sets_.erase(it); + const char* ApplyConstraintSet(const ConstraintSet& constraint_set) { + const char* latest_failed_constraint_name = nullptr; + for (auto it = devices_.begin(); it != devices_.end();) { + DCHECK(!it->IsEmpty()); + auto* failed_constraint_name = it->ApplyConstraintSet(constraint_set); + if (failed_constraint_name) { + latest_failed_constraint_name = failed_constraint_name; + devices_.erase(it); } else { ++it; } } - - if (candidate_sets_.empty()) - failed_constraint_name_ = failed_constraint_name; + return IsEmpty() ? latest_failed_constraint_name : nullptr; } - // Returns the settings that best satisfy the ideal values in - // |basic_constraint_set| subject to the limitations of this - // AudioCaptureCandidates object. - AudioCaptureSettings SelectBestSettings( - const blink::WebMediaTrackConstraintSet& constraint_set, - const std::string& default_device_id, - const std::string& media_stream_source, + std::tuple<Score, AudioCaptureSettings> SelectSettingsAndScore( + const ConstraintSet& constraint_set, + bool is_desktop_source, bool should_disable_hardware_noise_suppression) const { - DCHECK(!candidate_sets_.empty()); - - auto best_candidate = candidate_sets_.end(); - std::vector<double> best_score({-1, -1}); + DCHECK(!IsEmpty()); + // Make a copy of the settings initially provided, to track the default + // settings. AudioCaptureSettings best_settings; - - for (auto it = candidate_sets_.begin(); it != candidate_sets_.end(); ++it) { - DCHECK(!it->IsEmpty()); - - std::vector<double> score(2); + Score best_score(-1.0); + for (const auto& candidate : devices_) { + double fitness; AudioCaptureSettings settings; + std::tie(fitness, settings) = candidate.SelectSettingsAndScore( + constraint_set, is_desktop_source, + should_disable_hardware_noise_suppression, default_device_id_); - std::tie(settings, score[0]) = it->SelectBestSettingsAndFitness( - constraint_set, default_device_id, media_stream_source, - should_disable_hardware_noise_suppression); - score[1] = it->device_id_set().Contains(default_device_id) ? 1.0 : 0.0; - - if (score > best_score) { + Score score(fitness, default_device_id_ == settings.device_id()); + if (best_score < score) { best_score = score; - best_candidate = it; - best_settings = settings; + best_settings = std::move(settings); } } - - DCHECK(best_candidate != candidate_sets_.end()); - DCHECK(!best_candidate->IsEmpty()); - return best_settings; + return std::make_tuple(best_score, best_settings); } + bool IsEmpty() const { return devices_.empty(); } + private: - const char* failed_constraint_name_ = nullptr; - std::vector<SingleDeviceCandidateSet> candidate_sets_; + std::string default_device_id_; + std::vector<DeviceContainer> devices_; }; } // namespace @@ -670,30 +771,37 @@ const AudioDeviceCaptureCapabilities& capabilities, const blink::WebMediaConstraints& constraints, bool should_disable_hardware_noise_suppression) { - std::string media_stream_source = GetMediaStreamSource(constraints); - bool is_device_capture = media_stream_source.empty(); if (capabilities.empty()) return AudioCaptureSettings(); - AudioCaptureCandidates candidates(constraints.Basic(), capabilities); - if (candidates.IsEmpty()) - return AudioCaptureSettings(candidates.failed_constraint_name()); + std::string media_stream_source = GetMediaStreamSource(constraints); + std::string default_device_id; + bool is_device_capture = media_stream_source.empty(); + if (is_device_capture) + default_device_id = capabilities.begin()->DeviceID(); + + CandidatesContainer candidates(capabilities, media_stream_source, + default_device_id); + auto* failed_constraint_name = + candidates.ApplyConstraintSet(constraints.Basic()); + if (failed_constraint_name) + return AudioCaptureSettings(failed_constraint_name); for (const auto& advanced_set : constraints.Advanced()) { - AudioCaptureCandidates copy = candidates; - candidates.ApplyConstraintSet(advanced_set); - if (candidates.IsEmpty()) + CandidatesContainer copy = candidates; + failed_constraint_name = candidates.ApplyConstraintSet(advanced_set); + if (failed_constraint_name) candidates = std::move(copy); } DCHECK(!candidates.IsEmpty()); - std::string default_device_id; - if (is_device_capture) - default_device_id = capabilities.begin()->DeviceID(); - - return candidates.SelectBestSettings( - constraints.Basic(), default_device_id, media_stream_source, + // Score is ignored as it is no longer needed. + AudioCaptureSettings settings; + std::tie(std::ignore, settings) = candidates.SelectSettingsAndScore( + constraints.Basic(), media_stream_source == kMediaStreamSourceDesktop, should_disable_hardware_noise_suppression); + + return settings; } AudioCaptureSettings CONTENT_EXPORT
diff --git a/content/renderer/media/stream/media_stream_constraints_util_video_device.cc b/content/renderer/media/stream/media_stream_constraints_util_video_device.cc index 7e065c4..7ee2128 100644 --- a/content/renderer/media/stream/media_stream_constraints_util_video_device.cc +++ b/content/renderer/media/stream/media_stream_constraints_util_video_device.cc
@@ -10,6 +10,7 @@ #include <utility> #include <vector> +#include "base/stl_util.h" #include "content/renderer/media/stream/media_stream_constraints_util.h" #include "content/renderer/media/stream/media_stream_constraints_util_sets.h" #include "content/renderer/media/stream/media_stream_video_source.h" @@ -24,6 +25,8 @@ using ResolutionSet = media_constraints::ResolutionSet; using DoubleRangeSet = media_constraints::NumericRangeSet<double>; +using IntRangeSet = media_constraints::NumericRangeSet<int32_t>; +using BoolSet = media_constraints::DiscreteSet<bool>; using DeviceInfo = mojo::StructPtr<blink::mojom::VideoInputDeviceCapabilities>; using DistanceVector = std::vector<double>; @@ -51,18 +54,11 @@ // closest value to it in the range [min, max]. // Based on https://w3c.github.io/mediacapture-main/#dfn-fitness-distance. template <typename NumericConstraint> -double NumericRangeFitness(const NumericConstraint& constraint, - decltype(constraint.Min()) min, - decltype(constraint.Min()) max) { - if (!constraint.HasIdeal()) - return 0.0; - - if (constraint.Ideal() > max) - return NumericConstraintFitnessDistance(max, constraint.Ideal()); - if (constraint.Ideal() < min) - return NumericConstraintFitnessDistance(min, constraint.Ideal()); - - return 0.0; +double NumericValueFitness(const NumericConstraint& constraint, + decltype(constraint.Min()) value) { + return constraint.HasIdeal() + ? NumericConstraintFitnessDistance(value, constraint.Ideal()) + : 0.0; } // Returns a custom distance between |native_value| and the ideal value and @@ -137,6 +133,10 @@ // Convenience accessors for format() fields. int NativeHeight() const { return format_.frame_size.height(); } int NativeWidth() const { return format_.frame_size.width(); } + double NativeAspectRatio() const { + DCHECK(NativeWidth() > 0 || NativeHeight() > 0); + return static_cast<double>(NativeWidth()) / NativeHeight(); + } double NativeFrameRate() const { return format_.frame_rate; } // Convenience accessors for accessors for resolution_set() fields. They @@ -187,8 +187,22 @@ bool ApplyConstraintSet( const blink::WebMediaTrackConstraintSet& constraint_set, const char** failed_constraint_name = nullptr) { + auto rescale_intersection = + rescale_set_.Intersection(media_constraints::RescaleSetFromConstraint( + constraint_set.resize_mode)); + if (rescale_intersection.IsEmpty()) { + UpdateFailedConstraintName(constraint_set.resize_mode, + failed_constraint_name); + return false; + } + auto resolution_intersection = resolution_set_.Intersection( ResolutionSet::FromConstraintSet(constraint_set)); + if (!rescale_intersection.Contains(true)) { + // If rescaling is not allowed, only the native resolution is allowed. + resolution_intersection = resolution_intersection.Intersection( + ResolutionSet::FromExactResolution(NativeWidth(), NativeHeight())); + } if (resolution_intersection.IsWidthEmpty()) { UpdateFailedConstraintName(constraint_set.width, failed_constraint_name); return false; @@ -216,29 +230,107 @@ } resolution_set_ = resolution_intersection; + rescale_set_ = rescale_intersection; constrained_frame_rate_ = constrained_frame_rate_.Intersection( DoubleRangeSet::FromConstraint(constraint_set.frame_rate, 0.0, media::limits::kMaxFramesPerSecond)); + constrained_width_ = + constrained_width_.Intersection(IntRangeSet::FromConstraint( + constraint_set.width, 1L, ResolutionSet::kMaxDimension)); + constrained_height_ = + constrained_height_.Intersection(IntRangeSet::FromConstraint( + constraint_set.height, 1L, ResolutionSet::kMaxDimension)); + constrained_aspect_ratio_ = + constrained_aspect_ratio_.Intersection(DoubleRangeSet::FromConstraint( + constraint_set.aspect_ratio, 0.0, HUGE_VAL)); return true; } - // Returns the fitness distance for this candidate format. - // Since a format can support multiple track settings, this function returns - // the best fitness that can be achieved with this format. - // The fitness function is based on + // Returns the best fitness distance that can be achieved with this candidate + // format based on distance from the ideal values in |basic_constraint_set|. + // The track settings that correspond to this fitness are returned on the + // |track_settings| output parameter. The fitness function is based on // https://w3c.github.io/mediacapture-main/#dfn-fitness-distance. - double Fitness( - const blink::WebMediaTrackConstraintSet& constraint_set) const { - return NumericRangeFitness(constraint_set.aspect_ratio, MinAspectRatio(), - MaxAspectRatio()) + - NumericRangeFitness(constraint_set.height, MinHeight(), - MaxHeight()) + - NumericRangeFitness(constraint_set.width, MinWidth(), MaxWidth()) + - NumericRangeFitness(constraint_set.frame_rate, MinFrameRate(), - MaxFrameRate()) + - StringConstraintFitnessDistance(VideoKind(), - constraint_set.video_kind); + double Fitness(const blink::WebMediaTrackConstraintSet& basic_constraint_set, + VideoTrackAdapterSettings* track_settings) const { + DCHECK(!rescale_set_.IsEmpty()); + double track_fitness_with_rescale = HUGE_VAL; + VideoTrackAdapterSettings track_settings_with_rescale; + if (rescale_set_.Contains(true)) { + track_settings_with_rescale = SelectVideoTrackAdapterSettings( + basic_constraint_set, resolution_set(), constrained_frame_rate(), + format(), true /* enable_rescale */); + DCHECK(track_settings_with_rescale.target_size().has_value()); + double target_aspect_ratio = + static_cast<double>(track_settings_with_rescale.target_width()) / + track_settings_with_rescale.target_height(); + DCHECK(!std::isnan(target_aspect_ratio)); + double target_frame_rate = track_settings_with_rescale.max_frame_rate(); + if (target_frame_rate == 0.0) + target_frame_rate = NativeFrameRate(); + + track_fitness_with_rescale = + NumericValueFitness(basic_constraint_set.aspect_ratio, + target_aspect_ratio) + + NumericValueFitness(basic_constraint_set.height, + track_settings_with_rescale.target_height()) + + NumericValueFitness(basic_constraint_set.width, + track_settings_with_rescale.target_width()) + + NumericValueFitness(basic_constraint_set.frame_rate, + target_frame_rate); + } + + double track_fitness_without_rescale = HUGE_VAL; + VideoTrackAdapterSettings track_settings_without_rescale; + if (rescale_set_.Contains(false)) { + bool can_use_native_resolution = + constrained_width_.Contains(NativeWidth()) && + constrained_height_.Contains(NativeHeight()) && + constrained_aspect_ratio_.Contains(NativeAspectRatio()); + if (can_use_native_resolution) { + track_settings_without_rescale = SelectVideoTrackAdapterSettings( + basic_constraint_set, resolution_set(), constrained_frame_rate(), + format(), false /* enable_rescale */); + DCHECK(!track_settings_without_rescale.target_size().has_value()); + double target_frame_rate = + track_settings_without_rescale.max_frame_rate(); + if (target_frame_rate == 0.0) + target_frame_rate = NativeFrameRate(); + track_fitness_without_rescale = + NumericValueFitness(basic_constraint_set.aspect_ratio, + NativeAspectRatio()) + + NumericValueFitness(basic_constraint_set.height, NativeHeight()) + + NumericValueFitness(basic_constraint_set.width, NativeWidth()) + + NumericValueFitness(basic_constraint_set.frame_rate, + target_frame_rate); + } + } + + if (basic_constraint_set.resize_mode.HasIdeal()) { + if (!base::ContainsValue(basic_constraint_set.resize_mode.Ideal(), + blink::WebMediaStreamTrack::kResizeModeNone)) { + track_fitness_without_rescale += 1.0; + } + if (!base::ContainsValue( + basic_constraint_set.resize_mode.Ideal(), + blink::WebMediaStreamTrack::kResizeModeRescale)) { + track_fitness_with_rescale += 1.0; + } + } + double fitness = StringConstraintFitnessDistance( + VideoKind(), basic_constraint_set.video_kind); + // If rescaling and not rescaling have the same fitness, prefer not + // rescaling. + if (track_fitness_without_rescale <= track_fitness_with_rescale) { + fitness += track_fitness_without_rescale; + *track_settings = track_settings_without_rescale; + } else { + fitness += track_fitness_with_rescale; + *track_settings = track_settings_with_rescale; + } + + return fitness; } // Returns a custom "native" fitness distance that expresses how close the @@ -290,6 +382,12 @@ // range [kMinDeviceCaptureFrameRate, NativeframeRate()] is the set of // frame rates supported by this candidate. DoubleRangeSet constrained_frame_rate_; + IntRangeSet constrained_width_; + IntRangeSet constrained_height_; + DoubleRangeSet constrained_aspect_ratio_; + + // Contains the set of allowed rescale modes subject to applied constraints. + BoolSet rescale_set_; }; // Returns true if the facing mode |value| satisfies |constraints|, false @@ -367,13 +465,15 @@ // Returns the fitness distance between |constraint_set| and |candidate| given // that the configuration is already constrained by |candidate_format|. // Based on https://w3c.github.io/mediacapture-main/#dfn-fitness-distance. -double CandidateFitness( - const DeviceInfo& device, - const CandidateFormat& candidate_format, - const base::Optional<bool>& noise_reduction, - const blink::WebMediaTrackConstraintSet& constraint_set) { +// The track settings for |candidate| that correspond to the returned fitness +// are returned in |track_settings|. +double CandidateFitness(const DeviceInfo& device, + const CandidateFormat& candidate_format, + const base::Optional<bool>& noise_reduction, + const blink::WebMediaTrackConstraintSet& constraint_set, + VideoTrackAdapterSettings* track_settings) { return DeviceFitness(device, constraint_set) + - candidate_format.Fitness(constraint_set) + + candidate_format.Fitness(constraint_set, track_settings) + OptionalBoolFitness(noise_reduction, constraint_set.goog_noise_reduction); } @@ -419,24 +519,6 @@ distance_vector->push_back(frame_rate_distance); } -VideoCaptureSettings ComputeVideoDeviceCaptureSettings( - const DeviceInfo& device, - const base::Optional<bool>& noise_reduction, - const CandidateFormat& candidate_format, - const blink::WebMediaTrackConstraintSet& basic_constraint_set) { - media::VideoCaptureParams capture_params; - capture_params.requested_format = candidate_format.format(); - auto track_adapter_settings = SelectVideoTrackAdapterSettings( - basic_constraint_set, candidate_format.resolution_set(), - candidate_format.constrained_frame_rate(), - capture_params.requested_format, true /* enable_rescale */); - - return VideoCaptureSettings(device->device_id, capture_params, - noise_reduction, track_adapter_settings, - candidate_format.constrained_frame_rate().Min(), - candidate_format.constrained_frame_rate().Max()); -} - } // namespace blink::WebString GetVideoKindForFormat( @@ -565,9 +647,11 @@ satisfies_advanced_set ? 0 : HUGE_VAL); } + VideoTrackAdapterSettings track_settings; // Second criterion is fitness distance. - candidate_distance_vector.push_back(CandidateFitness( - device, candidate_format, noise_reduction, constraints.Basic())); + candidate_distance_vector.push_back( + CandidateFitness(device, candidate_format, noise_reduction, + constraints.Basic(), &track_settings)); // Third criterion is native fitness distance. candidate_distance_vector.push_back( @@ -582,8 +666,13 @@ DCHECK_EQ(best_distance.size(), candidate_distance_vector.size()); if (candidate_distance_vector < best_distance) { best_distance = candidate_distance_vector; - result = ComputeVideoDeviceCaptureSettings( - device, noise_reduction, candidate_format, constraints.Basic()); + + media::VideoCaptureParams capture_params; + capture_params.requested_format = candidate_format.format(); + result = VideoCaptureSettings( + device->device_id, capture_params, noise_reduction, + track_settings, candidate_format.constrained_frame_rate().Min(), + candidate_format.constrained_frame_rate().Max()); } } }
diff --git a/content/renderer/media/stream/media_stream_constraints_util_video_device_unittest.cc b/content/renderer/media/stream/media_stream_constraints_util_video_device_unittest.cc index aeb43820..791af969 100644 --- a/content/renderer/media/stream/media_stream_constraints_util_video_device_unittest.cc +++ b/content/renderer/media/stream/media_stream_constraints_util_video_device_unittest.cc
@@ -33,10 +33,7 @@ void CheckTrackAdapterSettingsEqualsResolution( const VideoCaptureSettings& settings) { - EXPECT_EQ(settings.Format().frame_size.width(), - settings.track_adapter_settings().target_width()); - EXPECT_EQ(settings.Format().frame_size.height(), - settings.track_adapter_settings().target_height()); + EXPECT_FALSE(settings.track_adapter_settings().target_size()); EXPECT_EQ(1.0 / settings.Format().frame_size.height(), settings.track_adapter_settings().min_aspect_ratio()); EXPECT_EQ(settings.Format().frame_size.width(), @@ -264,6 +261,28 @@ result.failed_constraint_name()); } +TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, + OverconstrainedOnInvalidResizeMode) { + constraint_factory_.Reset(); + constraint_factory_.basic().resize_mode.SetExact( + blink::WebString::FromASCII("invalid")); + auto result = SelectSettings(); + EXPECT_FALSE(result.HasValue()); + EXPECT_EQ(constraint_factory_.basic().resize_mode.GetName(), + result.failed_constraint_name()); +} + +TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, + OverconstrainedOnEmptyResizeMode) { + constraint_factory_.Reset(); + constraint_factory_.basic().resize_mode.SetExact( + blink::WebString::FromASCII("")); + auto result = SelectSettings(); + EXPECT_FALSE(result.HasValue()); + EXPECT_EQ(constraint_factory_.basic().resize_mode.GetName(), + result.failed_constraint_name()); +} + TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, OverconstrainedOnVideoKind) { constraint_factory_.Reset(); // No device in |capabilities_| has video kind infrared. @@ -519,7 +538,7 @@ // which is the low-res device. EXPECT_EQ(low_res_device_->device_id, result.device_id()); EXPECT_EQ(kHeight, result.Height()); - EXPECT_EQ(kHeight, result.track_adapter_settings().target_height()); + EXPECT_FALSE(result.track_adapter_settings().target_size().has_value()); const int kLargeHeight = 1500; constraint_factory_.basic().height.SetExact(kLargeHeight); @@ -544,8 +563,7 @@ // algorithm should prefer the default device. EXPECT_EQ(default_device_->device_id, result.device_id()); EXPECT_LE(kHeight, result.Height()); - EXPECT_EQ(result.Height(), result.track_adapter_settings().target_height()); - EXPECT_EQ(result.Width(), result.track_adapter_settings().target_width()); + EXPECT_FALSE(result.track_adapter_settings().target_size().has_value()); EXPECT_EQ(static_cast<double>(result.Width()) / kHeight, result.track_adapter_settings().max_aspect_ratio()); EXPECT_EQ(1.0 / result.Height(), @@ -561,8 +579,7 @@ EXPECT_EQ(high_res_device_->device_id, result.device_id()); EXPECT_EQ(*high_res_highest_format_, result.Format()); EXPECT_LE(kHeight, result.Height()); - EXPECT_EQ(result.Height(), result.track_adapter_settings().target_height()); - EXPECT_EQ(result.Width(), result.track_adapter_settings().target_width()); + EXPECT_FALSE(result.track_adapter_settings().target_size().has_value()); EXPECT_EQ(static_cast<double>(result.Width()) / kLargeHeight, result.track_adapter_settings().max_aspect_ratio()); EXPECT_EQ(1.0 / result.Height(), @@ -608,8 +625,7 @@ // range. EXPECT_EQ(default_device_->device_id, result.device_id()); EXPECT_EQ(*default_closest_format_, result.Format()); - EXPECT_EQ(result.Height(), result.track_adapter_settings().target_height()); - EXPECT_EQ(result.Width(), result.track_adapter_settings().target_width()); + EXPECT_FALSE(result.track_adapter_settings().target_size().has_value()); EXPECT_EQ(static_cast<double>(result.Width()) / kMinHeight, result.track_adapter_settings().max_aspect_ratio()); EXPECT_EQ(1.0 / result.Height(), @@ -632,8 +648,7 @@ EXPECT_EQ(low_res_device_->device_id, result.device_id()); EXPECT_EQ(800, result.Width()); EXPECT_EQ(600, result.Height()); - EXPECT_EQ(result.Height(), result.track_adapter_settings().target_height()); - EXPECT_EQ(result.Width(), result.track_adapter_settings().target_width()); + EXPECT_FALSE(result.track_adapter_settings().target_size().has_value()); EXPECT_EQ(static_cast<double>(result.Width()) / kMinHeight, result.track_adapter_settings().max_aspect_ratio()); EXPECT_EQ(1.0 / result.Height(), @@ -656,8 +671,7 @@ EXPECT_EQ(high_res_device_->device_id, result.device_id()); EXPECT_EQ(1280, result.Width()); EXPECT_EQ(720, result.Height()); - EXPECT_EQ(result.Height(), result.track_adapter_settings().target_height()); - EXPECT_EQ(result.Width(), result.track_adapter_settings().target_width()); + EXPECT_FALSE(result.track_adapter_settings().target_size().has_value()); EXPECT_EQ(static_cast<double>(result.Width()) / kMinHeight, result.track_adapter_settings().max_aspect_ratio()); EXPECT_EQ(1.0 / result.Height(), @@ -755,9 +769,7 @@ // which is the low-res device. EXPECT_EQ(low_res_device_->device_id, result.device_id()); EXPECT_EQ(kWidth, result.Width()); - EXPECT_EQ(std::round(kWidth / AspectRatio(result.Format())), - result.track_adapter_settings().target_height()); - EXPECT_EQ(kWidth, result.track_adapter_settings().target_width()); + EXPECT_FALSE(result.track_adapter_settings().target_size().has_value()); EXPECT_EQ(kWidth, result.track_adapter_settings().max_aspect_ratio()); EXPECT_EQ(static_cast<double>(kWidth) / result.Height(), result.track_adapter_settings().min_aspect_ratio()); @@ -794,8 +806,7 @@ EXPECT_LE(kWidth, result.Width()); EXPECT_EQ(1000, result.Width()); EXPECT_EQ(1000, result.Height()); - EXPECT_EQ(result.Height(), result.track_adapter_settings().target_height()); - EXPECT_EQ(result.Width(), result.track_adapter_settings().target_width()); + EXPECT_FALSE(result.track_adapter_settings().target_size().has_value()); EXPECT_EQ(result.Width(), result.track_adapter_settings().max_aspect_ratio()); EXPECT_EQ(static_cast<double>(kWidth) / result.Height(), result.track_adapter_settings().min_aspect_ratio()); @@ -810,8 +821,7 @@ EXPECT_EQ(high_res_device_->device_id, result.device_id()); EXPECT_LE(kLargeWidth, result.Width()); EXPECT_EQ(*high_res_highest_format_, result.Format()); - EXPECT_EQ(result.Height(), result.track_adapter_settings().target_height()); - EXPECT_EQ(result.Width(), result.track_adapter_settings().target_width()); + EXPECT_FALSE(result.track_adapter_settings().target_size().has_value()); EXPECT_EQ(result.Width(), result.track_adapter_settings().max_aspect_ratio()); EXPECT_EQ(static_cast<double>(kLargeWidth) / result.Height(), result.track_adapter_settings().min_aspect_ratio()); @@ -857,8 +867,7 @@ EXPECT_EQ(default_device_->device_id, result.device_id()); EXPECT_EQ(1000, result.Width()); EXPECT_EQ(1000, result.Height()); - EXPECT_EQ(result.Height(), result.track_adapter_settings().target_height()); - EXPECT_EQ(result.Width(), result.track_adapter_settings().target_width()); + EXPECT_FALSE(result.track_adapter_settings().target_size().has_value()); EXPECT_EQ(result.Width(), result.track_adapter_settings().max_aspect_ratio()); EXPECT_EQ(static_cast<double>(kMinWidth) / result.Height(), @@ -881,8 +890,7 @@ EXPECT_EQ(low_res_device_->device_id, result.device_id()); EXPECT_EQ(800, result.Width()); EXPECT_EQ(600, result.Height()); - EXPECT_EQ(result.Height(), result.track_adapter_settings().target_height()); - EXPECT_EQ(result.Width(), result.track_adapter_settings().target_width()); + EXPECT_FALSE(result.track_adapter_settings().target_size().has_value()); EXPECT_EQ(result.Width(), result.track_adapter_settings().max_aspect_ratio()); EXPECT_EQ(static_cast<double>(kMinWidth) / result.Height(), @@ -905,8 +913,7 @@ EXPECT_EQ(high_res_device_->device_id, result.device_id()); EXPECT_EQ(1920, result.Width()); EXPECT_EQ(1080, result.Height()); - EXPECT_EQ(result.Height(), result.track_adapter_settings().target_height()); - EXPECT_EQ(result.Width(), result.track_adapter_settings().target_width()); + EXPECT_FALSE(result.track_adapter_settings().target_size().has_value()); EXPECT_EQ(result.Width(), result.track_adapter_settings().max_aspect_ratio()); EXPECT_EQ(static_cast<double>(kMinWidth) / result.Height(), @@ -926,9 +933,8 @@ // width natively, which is the low-res device at 320x240. EXPECT_EQ(low_res_device_->device_id, result.device_id()); EXPECT_EQ(kIdealWidth, result.Width()); - EXPECT_EQ(std::round(kIdealWidth / AspectRatio(result.Format())), - result.track_adapter_settings().target_height()); - EXPECT_EQ(kIdealWidth, result.track_adapter_settings().target_width()); + // The ideal value is satisfied with a native resolution, so no rescaling. + EXPECT_FALSE(result.track_adapter_settings().target_size().has_value()); EXPECT_EQ(kIdealWidth, result.track_adapter_settings().max_aspect_ratio()); EXPECT_EQ(1.0 / result.Height(), result.track_adapter_settings().min_aspect_ratio()); @@ -1335,9 +1341,8 @@ // low-res device. EXPECT_EQ(low_res_device_->device_id, result.device_id()); EXPECT_EQ(*low_res_closest_format_, result.Format()); - EXPECT_EQ(std::round(result.Width() / kAspectRatio), - result.track_adapter_settings().target_height()); - EXPECT_EQ(result.Width(), result.track_adapter_settings().target_width()); + // Native resolution, so no rescaling. + EXPECT_FALSE(result.track_adapter_settings().target_size().has_value()); EXPECT_EQ(kAspectRatio, result.track_adapter_settings().min_aspect_ratio()); EXPECT_EQ(kAspectRatio, result.track_adapter_settings().max_aspect_ratio()); CheckTrackAdapterSettingsEqualsFrameRate(result); @@ -1394,9 +1399,8 @@ // constraints than the default native resolution of the low-res device. EXPECT_EQ(low_res_device_->device_id, result.device_id()); EXPECT_EQ(*low_res_closest_format_, result.Format()); + EXPECT_FALSE(result.track_adapter_settings().target_size().has_value()); // The source's native aspect ratio equals the minimum aspect ratio. - EXPECT_EQ(result.Height(), result.track_adapter_settings().target_height()); - EXPECT_EQ(result.Width(), result.track_adapter_settings().target_width()); EXPECT_EQ(kAspectRatio, result.track_adapter_settings().min_aspect_ratio()); EXPECT_EQ(max_aspect_ratio, result.track_adapter_settings().max_aspect_ratio()); @@ -1492,8 +1496,7 @@ EXPECT_EQ(*default_closest_format_, result.Format()); // The source's aspect ratio matches the maximum aspect ratio. No adjustment // is required. - EXPECT_EQ(result.Height(), result.track_adapter_settings().target_height()); - EXPECT_EQ(result.Width(), result.track_adapter_settings().target_width()); + EXPECT_FALSE(result.track_adapter_settings().target_size().has_value()); EXPECT_EQ(kMinAspectRatio, result.track_adapter_settings().min_aspect_ratio()); EXPECT_EQ(kMaxAspectRatio, @@ -1578,13 +1581,16 @@ // The only device that supports the ideal aspect ratio is the high-res // device. EXPECT_EQ(high_res_device_->device_id, result.device_id()); - EXPECT_EQ(1920, result.Width()); - EXPECT_EQ(1080, result.Height()); + EXPECT_EQ(1280, result.Width()); + EXPECT_EQ(720, result.Height()); // The most exact way to support the ideal aspect ratio would be to crop to - // 1500x1. However, the algorithm tries to crop to 1920x1.28 and rounds. + // 1920x1080 to 1500x1. However, with 1920x1080 the algorithm tries to crop + // to 1920x1.28 and rounds to 1920x1. Since the aspect ratio of 1280x1 is + // closer to ideal than 1920x1, 1280x1 is selected instead. // In this case, the effect of rounding is noticeable because of the - // resulting low value for height. For more typical resolution values, - // the at-most 1-pixel error caused by rounding is not an issue. + // resulting low value for height. For more typical aspect-ratio values, + // the 1-pixel error caused by rounding one dimension does not translate to + // a absolute error on the other dimension. EXPECT_EQ(std::round(result.Width() / kIdealAspectRatio), result.track_adapter_settings().target_height()); EXPECT_EQ(result.Width(), result.track_adapter_settings().target_width()); @@ -1600,10 +1606,14 @@ constraint_factory_.basic().aspect_ratio.SetIdeal(kIdealAspectRatio); auto result = SelectSettings(); EXPECT_TRUE(result.HasValue()); - // The only device that supports the ideal aspect ratio is the high-res - // device with its highest resolution. + // The best way to support this ideal aspect ratio would be to rescale + // 2304x1536 to 2000x1, but the algorithm would try to rescale to 2304x1.15 + // and then round. Since 1920x1 has an aspect ratio closer to 2000, it is + // selected over 2304x1. The only device that supports this resolution is + // the high-res device open at 1920x1080. EXPECT_EQ(high_res_device_->device_id, result.device_id()); - EXPECT_EQ(*high_res_highest_format_, result.Format()); + EXPECT_EQ(1920, result.Width()); + EXPECT_EQ(1080, result.Height()); EXPECT_EQ(std::round(result.Width() / kIdealAspectRatio), result.track_adapter_settings().target_height()); EXPECT_EQ(result.Width(), result.track_adapter_settings().target_width()); @@ -1680,6 +1690,178 @@ } } +TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, MandatoryResizeMode) { + const int kIdealWidth = 641; + const int kIdealHeight = 480; + constraint_factory_.Reset(); + constraint_factory_.basic().width.SetIdeal(kIdealWidth); + constraint_factory_.basic().height.SetIdeal(kIdealHeight); + constraint_factory_.basic().resize_mode.SetExact( + blink::WebString::FromASCII("none")); + auto result = SelectSettings(); + EXPECT_TRUE(result.HasValue()); + // A native mode of 640x480 should be selected since it is closest native mode + // to the ideal values. + EXPECT_EQ(result.Width(), 640); + EXPECT_EQ(result.Height(), 480); + EXPECT_FALSE(result.track_adapter_settings().target_size().has_value()); + + constraint_factory_.basic().resize_mode.SetExact( + blink::WebString::FromASCII("crop-and-scale")); + result = SelectSettings(); + EXPECT_TRUE(result.HasValue()); + EXPECT_GE(result.Width(), kIdealWidth); + EXPECT_GE(result.Height(), kIdealHeight); + EXPECT_EQ(result.track_adapter_settings().target_width(), kIdealWidth); + EXPECT_EQ(result.track_adapter_settings().target_height(), kIdealHeight); +} + +TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, IdealResizeMode) { + constraint_factory_.Reset(); + constraint_factory_.basic().resize_mode.SetIdeal( + blink::WebString::FromASCII("crop-and-scale")); + auto result = SelectSettings(); + EXPECT_TRUE(result.HasValue()); + // Since no constraints are given, the default device with resolution closest + // to default is selected. However, rescaling is enabled due to the ideal + // resize mode. + EXPECT_EQ(result.device_id(), default_device_->device_id); + EXPECT_EQ(result.Width(), 500); + EXPECT_EQ(result.Height(), 500); + EXPECT_TRUE(result.track_adapter_settings().target_size().has_value()); + EXPECT_EQ(result.track_adapter_settings().target_width(), 500); + EXPECT_EQ(result.track_adapter_settings().target_height(), 500); +} + +TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, + IdealResizeModeResolutionGreaterThanNative) { + // Ideal resolution is slightly greater than the closest native resolution. + const int kIdealWidth = 641; + const int kIdealHeight = 480; + constraint_factory_.Reset(); + constraint_factory_.basic().width.SetIdeal(kIdealWidth); + constraint_factory_.basic().height.SetIdeal(kIdealHeight); + constraint_factory_.basic().resize_mode.SetIdeal( + blink::WebString::FromASCII("none")); + auto result = SelectSettings(); + EXPECT_TRUE(result.HasValue()); + // A native mode of 640x480 should be selected since it is the closest native + // mode to the ideal resolution values. + EXPECT_EQ(result.Width(), 640); + EXPECT_EQ(result.Height(), 480); + EXPECT_FALSE(result.track_adapter_settings().target_size().has_value()); + + constraint_factory_.basic().resize_mode.SetIdeal( + blink::WebString::FromASCII("crop-and-scale")); + result = SelectSettings(); + EXPECT_TRUE(result.HasValue()); + EXPECT_GE(result.Width(), kIdealWidth); + EXPECT_GE(result.Height(), kIdealHeight); + EXPECT_EQ(result.track_adapter_settings().target_width(), kIdealWidth); + EXPECT_EQ(result.track_adapter_settings().target_height(), kIdealHeight); +} + +TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, + IdealResizeModeResolutionLessThanNative) { + // Ideal resolution is slightly less than the closest native resolution. + const int kIdealWidth = 639; + const int kIdealHeight = 479; + constraint_factory_.Reset(); + constraint_factory_.basic().width.SetIdeal(kIdealWidth); + constraint_factory_.basic().height.SetIdeal(kIdealHeight); + constraint_factory_.basic().resize_mode.SetIdeal( + blink::WebString::FromASCII("none")); + auto result = SelectSettings(); + EXPECT_TRUE(result.HasValue()); + // A native mode of 640x480 should be selected since it is the closest native + // mode to the ideal values. + EXPECT_EQ(result.Width(), 640); + EXPECT_EQ(result.Height(), 480); + EXPECT_FALSE(result.track_adapter_settings().target_size().has_value()); + + constraint_factory_.basic().resize_mode.SetIdeal( + blink::WebString::FromASCII("crop-and-scale")); + result = SelectSettings(); + EXPECT_TRUE(result.HasValue()); + // Rescaling is preferred, therefore a native mode greater than the ideal + // resolution is chosen. + EXPECT_GE(result.Width(), kIdealWidth); + EXPECT_GE(result.Height(), kIdealHeight); + EXPECT_EQ(result.track_adapter_settings().target_width(), kIdealWidth); + EXPECT_EQ(result.track_adapter_settings().target_height(), kIdealHeight); +} + +TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, IdealResizeFarFromNative) { + constraint_factory_.Reset(); + constraint_factory_.basic().width.SetIdeal(1); + constraint_factory_.basic().height.SetIdeal(1); + constraint_factory_.basic().resize_mode.SetIdeal( + blink::WebString::FromASCII("none")); + auto result = SelectSettings(); + EXPECT_TRUE(result.HasValue()); + // The native mode closest to 1x1 is 40x30 with the low-res device. + EXPECT_EQ(result.device_id(), low_res_device_->device_id); + EXPECT_EQ(result.Width(), 40); + EXPECT_EQ(result.Height(), 30); + // Despite resize_mode being ideal "none", SelectSettings opts for rescaling + // since the fitness distance of 40x30 with respect to the ideal 1x1 is larger + // than the fitness distance for resize_mode not being "none" + // (29/30 + 39/40 > 1.0) + EXPECT_TRUE(result.track_adapter_settings().target_size().has_value()); + EXPECT_EQ(result.track_adapter_settings().target_width(), 1); + EXPECT_EQ(result.track_adapter_settings().target_height(), 1); + + constraint_factory_.Reset(); + constraint_factory_.basic().width.SetIdeal(1); + constraint_factory_.basic().resize_mode.SetIdeal( + blink::WebString::FromASCII("none")); + result = SelectSettings(); + EXPECT_TRUE(result.HasValue()); + // The native mode closest to 1x1 is 40x30 with the low-res device. + EXPECT_EQ(result.device_id(), low_res_device_->device_id); + EXPECT_EQ(result.Width(), 40); + EXPECT_EQ(result.Height(), 30); + // In this case, SelectSettings opts for not rescaling since the fitness + // distance of width 40 with respect to the ideal 1 is larger than the + // fitness distance for resize_mode not being "none" (39/40 < 1.0) + EXPECT_FALSE(result.track_adapter_settings().target_size().has_value()); +} + +TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, TwoIdealResizeValues) { + constraint_factory_.Reset(); + constraint_factory_.basic().width.SetIdeal(641); + constraint_factory_.basic().height.SetIdeal(481); + constraint_factory_.basic().resize_mode.SetIdeal( + blink::WebVector<blink::WebString>( + {blink::WebString::FromASCII("none"), + blink::WebString::FromASCII("crop-and-scale")})); + auto result = SelectSettings(); + EXPECT_TRUE(result.HasValue()); + // 800x600 rescaled to 641x481 is closest to the specified ideal values. + EXPECT_EQ(result.device_id(), low_res_device_->device_id); + EXPECT_EQ(result.Width(), 800); + EXPECT_EQ(result.Height(), 600); + // Since both resize modes are considered ideal, rescaling is preferred + // because of the penalty due to deviating from the ideal reo + EXPECT_TRUE(result.track_adapter_settings().target_size().has_value()); + EXPECT_EQ(result.track_adapter_settings().target_width(), 641); + EXPECT_EQ(result.track_adapter_settings().target_height(), 481); + + constraint_factory_.Reset(); + constraint_factory_.basic().resize_mode.SetIdeal( + blink::WebVector<blink::WebString>( + {blink::WebString::FromASCII("none"), + blink::WebString::FromASCII("crop-and-scale")})); + result = SelectSettings(); + EXPECT_TRUE(result.HasValue()); + // Given that both resize modes are ideal, the default device with the + // resolution closest to the default without rescaling is selected. + EXPECT_EQ(result.device_id(), default_device_->device_id); + EXPECT_EQ(result.Width(), 500); + EXPECT_EQ(result.Height(), 500); + EXPECT_FALSE(result.track_adapter_settings().target_size().has_value()); +} + // The "Advanced" tests check selection criteria involving advanced constraint // sets. TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, @@ -1709,8 +1891,7 @@ EXPECT_EQ(low_res_device_->device_id, result.device_id()); EXPECT_EQ(640, result.Width()); EXPECT_EQ(480, result.Height()); - EXPECT_EQ(result.Height(), result.track_adapter_settings().target_height()); - EXPECT_EQ(result.Width(), result.track_adapter_settings().target_width()); + EXPECT_FALSE(result.track_adapter_settings().target_size().has_value()); EXPECT_EQ(320.0 / 480.0, result.track_adapter_settings().min_aspect_ratio()); EXPECT_EQ(640.0 / 240.0, result.track_adapter_settings().max_aspect_ratio()); CheckTrackAdapterSettingsEqualsFrameRate(result); @@ -1725,8 +1906,7 @@ EXPECT_EQ(high_res_device_->device_id, result.device_id()); EXPECT_EQ(640, result.Width()); EXPECT_EQ(480, result.Height()); - EXPECT_EQ(result.Height(), result.track_adapter_settings().target_height()); - EXPECT_EQ(result.Width(), result.track_adapter_settings().target_width()); + EXPECT_FALSE(result.track_adapter_settings().target_size().has_value()); EXPECT_EQ(320.0 / 480.0, result.track_adapter_settings().min_aspect_ratio()); EXPECT_EQ(640.0 / 240.0, result.track_adapter_settings().max_aspect_ratio()); CheckTrackAdapterSettingsEqualsFrameRate(result, 10.0); @@ -1742,8 +1922,7 @@ EXPECT_EQ(high_res_device_->device_id, result.device_id()); EXPECT_EQ(640, result.Width()); EXPECT_EQ(480, result.Height()); - EXPECT_EQ(result.Height(), result.track_adapter_settings().target_height()); - EXPECT_EQ(result.Width(), result.track_adapter_settings().target_width()); + EXPECT_FALSE(result.track_adapter_settings().target_size().has_value()); EXPECT_EQ(320.0 / 480.0, result.track_adapter_settings().min_aspect_ratio()); EXPECT_EQ(640.0 / 240.0, result.track_adapter_settings().max_aspect_ratio()); CheckTrackAdapterSettingsEqualsFrameRate(result, 10.0); @@ -1765,8 +1944,7 @@ EXPECT_EQ(low_res_device_->device_id, result.device_id()); EXPECT_EQ(320, result.Width()); EXPECT_EQ(240, result.Height()); - EXPECT_EQ(320, result.track_adapter_settings().target_width()); - EXPECT_EQ(240, result.track_adapter_settings().target_height()); + EXPECT_FALSE(result.track_adapter_settings().target_size().has_value()); EXPECT_EQ(320.0 / 240.0, result.track_adapter_settings().min_aspect_ratio()); EXPECT_EQ(320.0 / 240.0, result.track_adapter_settings().max_aspect_ratio()); CheckTrackAdapterSettingsEqualsFrameRate(result, 10.0); @@ -1780,8 +1958,7 @@ EXPECT_EQ(high_res_device_->device_id, result.device_id()); EXPECT_EQ(640, result.Width()); EXPECT_EQ(480, result.Height()); - EXPECT_EQ(640, result.track_adapter_settings().target_width()); - EXPECT_EQ(480, result.track_adapter_settings().target_height()); + EXPECT_FALSE(result.track_adapter_settings().target_size().has_value()); EXPECT_EQ(320.0 / 480.0, result.track_adapter_settings().min_aspect_ratio()); EXPECT_EQ(640.0 / 240.0, result.track_adapter_settings().max_aspect_ratio()); CheckTrackAdapterSettingsEqualsFrameRate(result, 10.0); @@ -1811,8 +1988,7 @@ EXPECT_EQ(1920, result.Width()); EXPECT_EQ(1080, result.Height()); EXPECT_EQ(60.0, result.FrameRate()); - EXPECT_EQ(1920, result.track_adapter_settings().target_width()); - EXPECT_EQ(1080, result.track_adapter_settings().target_height()); + EXPECT_FALSE(result.track_adapter_settings().target_size().has_value()); EXPECT_EQ(1920.0 / 1080.0, result.track_adapter_settings().min_aspect_ratio()); EXPECT_EQ(1920.0 / 1080.0, @@ -1837,8 +2013,7 @@ EXPECT_LE(1920, result.Width()); EXPECT_LE(1080, result.Height()); EXPECT_TRUE(result.noise_reduction() && !*result.noise_reduction()); - EXPECT_EQ(result.Width(), result.track_adapter_settings().target_width()); - EXPECT_EQ(result.Height(), result.track_adapter_settings().target_height()); + EXPECT_FALSE(result.track_adapter_settings().target_size().has_value()); EXPECT_EQ(1920.0 / result.Height(), result.track_adapter_settings().min_aspect_ratio()); EXPECT_EQ(result.Width() / 1080.0, @@ -1869,8 +2044,7 @@ EXPECT_LE(640, result.Width()); EXPECT_LE(480, result.Height()); EXPECT_TRUE(result.noise_reduction() && *result.noise_reduction()); - EXPECT_EQ(result.Width(), result.track_adapter_settings().target_width()); - EXPECT_EQ(result.Height(), result.track_adapter_settings().target_height()); + EXPECT_FALSE(result.track_adapter_settings().target_size().has_value()); EXPECT_EQ(640.0 / result.Height(), result.track_adapter_settings().min_aspect_ratio()); EXPECT_EQ(result.Width() / 480.0, @@ -1897,8 +2071,7 @@ EXPECT_LE(1080, result.Height()); // Should select default noise reduction setting. EXPECT_TRUE(!result.noise_reduction()); - EXPECT_EQ(result.Width(), result.track_adapter_settings().target_width()); - EXPECT_EQ(result.Height(), result.track_adapter_settings().target_height()); + EXPECT_FALSE(result.track_adapter_settings().target_size().has_value()); EXPECT_EQ(1920.0 / result.Height(), result.track_adapter_settings().min_aspect_ratio()); EXPECT_EQ(result.Width() / 1080.0, @@ -1926,8 +2099,7 @@ EXPECT_EQ(low_res_device_->device_id, result.device_id()); EXPECT_EQ(640, result.Width()); EXPECT_EQ(480, result.Height()); - EXPECT_EQ(result.Width(), result.track_adapter_settings().target_width()); - EXPECT_EQ(result.Height(), result.track_adapter_settings().target_height()); + EXPECT_FALSE(result.track_adapter_settings().target_size().has_value()); EXPECT_EQ(640.0 / 480.0, result.track_adapter_settings().min_aspect_ratio()); EXPECT_EQ(640.0 / 480.0, result.track_adapter_settings().max_aspect_ratio()); CheckTrackAdapterSettingsEqualsFrameRate(result); @@ -1955,8 +2127,7 @@ EXPECT_EQ(200, result.Width()); EXPECT_EQ(200, result.Height()); EXPECT_EQ(40, result.FrameRate()); - EXPECT_EQ(result.Width(), result.track_adapter_settings().target_width()); - EXPECT_EQ(result.Height(), result.track_adapter_settings().target_height()); + EXPECT_FALSE(result.track_adapter_settings().target_size().has_value()); EXPECT_EQ(1.0 / result.Height(), result.track_adapter_settings().min_aspect_ratio()); EXPECT_EQ(result.Width(), result.track_adapter_settings().max_aspect_ratio()); @@ -1985,8 +2156,7 @@ EXPECT_EQ(1000, result.Width()); EXPECT_EQ(1000, result.Height()); EXPECT_EQ(20, result.FrameRate()); - EXPECT_EQ(result.Width(), result.track_adapter_settings().target_width()); - EXPECT_EQ(result.Height(), result.track_adapter_settings().target_height()); + EXPECT_FALSE(result.track_adapter_settings().target_size().has_value()); EXPECT_EQ(800.0 / result.Height(), result.track_adapter_settings().min_aspect_ratio()); EXPECT_EQ(result.Width() / 600.0, @@ -2222,9 +2392,8 @@ // set, but the third set must be applied. EXPECT_EQ(result.device_id(), low_res_device_->device_id); EXPECT_EQ(result.Width(), 800); - EXPECT_EQ(result.track_adapter_settings().target_width(), 800); EXPECT_EQ(result.Height(), 600); - EXPECT_EQ(result.track_adapter_settings().target_height(), 600); + EXPECT_FALSE(result.track_adapter_settings().target_size().has_value()); } TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, @@ -2277,6 +2446,54 @@ } } +TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, AdvancedResize) { + constraint_factory_.Reset(); + constraint_factory_.basic().width.SetIdeal(1); + constraint_factory_.basic().height.SetIdeal(1); + blink::WebMediaTrackConstraintSet& advanced = + constraint_factory_.AddAdvanced(); + + advanced.resize_mode.SetExact(blink::WebString::FromASCII("none")); + auto result = SelectSettings(); + EXPECT_TRUE(result.HasValue()); + // The native mode closest to 1x1 is 40x30 with the low-res device. + EXPECT_EQ(result.device_id(), low_res_device_->device_id); + EXPECT_EQ(result.Width(), 40); + EXPECT_EQ(result.Height(), 30); + // No rescaling occurs due to the advanced constraint specifying resizeMode + // equal to "none". + EXPECT_FALSE(result.track_adapter_settings().target_size().has_value()); +} + +TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, + AdvancedResolutionResizeFrameRate) { + constraint_factory_.Reset(); + constraint_factory_.basic().width.SetExact(639); + + // This advanced set must be ignored because there are no native resolutions + // with width equal to 639. + blink::WebMediaTrackConstraintSet& advanced = + constraint_factory_.AddAdvanced(); + advanced.resize_mode.SetExact(blink::WebString::FromASCII("none")); + advanced.frame_rate.SetExact(19.0); + + auto result = SelectSettings(); + EXPECT_TRUE(result.HasValue()); + // Rescaling is enabled to satisfy the required resolution. + EXPECT_TRUE(result.track_adapter_settings().target_size().has_value()); + EXPECT_EQ(result.track_adapter_settings().target_width(), 639); + // Height gets adjusted as well to maintain the aspect ratio. + EXPECT_EQ(result.track_adapter_settings().target_height(), 479); + // Using native frame rate because the advanced set is ignored. + EXPECT_EQ(result.track_adapter_settings().max_frame_rate(), 0.0); + + // The low-res device at 640x480@30Hz is the + EXPECT_EQ(result.device_id(), low_res_device_->device_id); + EXPECT_EQ(result.Width(), 640); + EXPECT_EQ(result.Height(), 480); + EXPECT_EQ(result.FrameRate(), 30.0); +} + TEST_F(MediaStreamConstraintsUtilVideoDeviceTest, BasicContradictoryWidth) { constraint_factory_.Reset(); constraint_factory_.basic().width.SetMin(10);
diff --git a/content/renderer/media/stream/media_stream_video_source.cc b/content/renderer/media/stream/media_stream_video_source.cc index c7cbece..e3794679 100644 --- a/content/renderer/media/stream/media_stream_video_source.cc +++ b/content/renderer/media/stream/media_stream_video_source.cc
@@ -405,11 +405,14 @@ // Calculate resulting frame size if the source delivers frames // according to the current format. Note: Format may change later. gfx::Size desired_size; - VideoTrackAdapter::CalculateDesiredSize(false /* is_rotated */, - GetCurrentFormat()->frame_size, - adapter_settings, &desired_size); - track->SetTargetSizeAndFrameRate(desired_size.width(), desired_size.height(), - adapter_settings.max_frame_rate()); + if (VideoTrackAdapter::CalculateDesiredSize( + false /* is_rotated */, GetCurrentFormat()->frame_size, + adapter_settings, &desired_size)) { + track->SetTargetSizeAndFrameRate(desired_size.width(), + desired_size.height(), + adapter_settings.max_frame_rate()); + } + track->SetTrackAdapterSettings(adapter_settings); } MediaStreamVideoSource::PendingTrackInfo::PendingTrackInfo(
diff --git a/content/renderer/media/stream/media_stream_video_track.cc b/content/renderer/media/stream/media_stream_video_track.cc index 99935694..6724e69 100644 --- a/content/renderer/media/stream/media_stream_video_track.cc +++ b/content/renderer/media/stream/media_stream_video_track.cc
@@ -410,4 +410,9 @@ sink->OnReadyStateChanged(state); } +void MediaStreamVideoTrack::SetTrackAdapterSettings( + const VideoTrackAdapterSettings& settings) { + adapter_settings_ = std::make_unique<VideoTrackAdapterSettings>(settings); +} + } // namespace content
diff --git a/content/renderer/media/stream/media_stream_video_track.h b/content/renderer/media/stream/media_stream_video_track.h index 6ad08d29..ad09c365 100644 --- a/content/renderer/media/stream/media_stream_video_track.h +++ b/content/renderer/media/stream/media_stream_video_track.h
@@ -106,6 +106,8 @@ frame_rate_ = frame_rate; } + void SetTrackAdapterSettings(const VideoTrackAdapterSettings& settings); + MediaStreamVideoSource* source() const { return source_.get(); } private:
diff --git a/content/renderer/media/stream/user_media_client_impl_unittest.cc b/content/renderer/media/stream/user_media_client_impl_unittest.cc index a647704b..ff8c5f088 100644 --- a/content/renderer/media/stream/user_media_client_impl_unittest.cc +++ b/content/renderer/media/stream/user_media_client_impl_unittest.cc
@@ -889,10 +889,7 @@ const VideoTrackAdapterSettings& track_settings = video_capture_settings.track_adapter_settings(); - EXPECT_EQ(track_settings.target_width(), - MediaStreamVideoSource::kDefaultWidth); - EXPECT_EQ(track_settings.target_height(), - MediaStreamVideoSource::kDefaultHeight); + EXPECT_FALSE(track_settings.target_size().has_value()); EXPECT_EQ(track_settings.min_aspect_ratio(), 1.0 / MediaStreamVideoSource::kDefaultHeight); EXPECT_EQ(track_settings.max_aspect_ratio(),
diff --git a/content/renderer/media/webrtc/media_stream_remote_video_source.cc b/content/renderer/media/webrtc/media_stream_remote_video_source.cc index a87a956..f00a1d5 100644 --- a/content/renderer/media/webrtc/media_stream_remote_video_source.cc +++ b/content/renderer/media/webrtc/media_stream_remote_video_source.cc
@@ -178,9 +178,9 @@ WebRtcToMediaVideoRotation(incoming_frame.rotation())); } - if (incoming_frame.color_space().has_value()) { + if (incoming_frame.color_space()) { video_frame->set_color_space( - WebRtcToMediaVideoColorSpace(incoming_frame.color_space().value()) + WebRtcToMediaVideoColorSpace(*incoming_frame.color_space()) .ToGfxColorSpace()); }
diff --git a/content/renderer/pepper/pepper_webplugin_impl.h b/content/renderer/pepper/pepper_webplugin_impl.h index 0b192933..f0fc4a3 100644 --- a/content/renderer/pepper/pepper_webplugin_impl.h +++ b/content/renderer/pepper/pepper_webplugin_impl.h
@@ -43,7 +43,8 @@ bool Initialize(blink::WebPluginContainer* container) override; void Destroy() override; v8::Local<v8::Object> V8ScriptableObject(v8::Isolate* isolate) override; - void UpdateAllLifecyclePhases() override {} + void UpdateAllLifecyclePhases( + blink::WebWidget::LifecycleUpdateReason) override {} void Paint(cc::PaintCanvas* canvas, const blink::WebRect& rect) override; void UpdateGeometry(const blink::WebRect& window_rect, const blink::WebRect& clip_rect,
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index c934ddb0..4fef95c 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -6449,6 +6449,8 @@ if (is_history_navigation_in_new_child) params.is_history_navigation_in_new_child = true; + params.href_translate = info->href_translate.Latin1(); + Send(new FrameHostMsg_OpenURL(routing_id_, params)); }
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index 53ae7cb8..29915366 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc
@@ -1876,7 +1876,8 @@ // We need to ensure |UpdatePreferredSize| gets called. If a layout is needed, // force an update here which will call |DidUpdateMainFrameLayout|. webview()->MainFrameWidget()->UpdateLifecycle( - WebWidget::LifecycleUpdate::kLayout); + WebWidget::LifecycleUpdate::kLayout, + WebWidget::LifecycleUpdateReason::kOther); // If a layout was not needed, |DidUpdateMainFrameLayout| will not be called. // We explicitly update the preferred size here to ensure the preferred size
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index 3adeac7..ec352c5 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc
@@ -1051,11 +1051,20 @@ ScheduleAnimation(); } -void RenderWidget::UpdateVisualState() { +void RenderWidget::UpdateVisualState(bool record_main_frame_metrics) { if (!GetWebWidget()) return; - GetWebWidget()->UpdateLifecycle(WebWidget::LifecycleUpdate::kAll); + // When recording main frame metrics set the lifecycle reason to + // kBeginMainFrame, because this is the calller of UpdateLifecycle + // for the main frame. Otherwise, set the reason to kTests, which is + // the oinly other reason this method is called. + WebWidget::LifecycleUpdateReason lifecycle_reason = + record_main_frame_metrics + ? WebWidget::LifecycleUpdateReason::kBeginMainFrame + : WebWidget::LifecycleUpdateReason::kTest; + GetWebWidget()->UpdateLifecycle(WebWidget::LifecycleUpdate::kAll, + lifecycle_reason); GetWebWidget()->SetSuppressFrameRequestsWorkaroundFor704763Only(false); if (first_update_visual_state_after_hidden_) {
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h index 7a6d45a9..e181fd9 100644 --- a/content/renderer/render_widget.h +++ b/content/renderer/render_widget.h
@@ -290,7 +290,7 @@ void DidCompletePageScaleAnimation() override; void RecordEndOfFrameMetrics(base::TimeTicks frame_begin_time) override; void RequestScheduleAnimation() override; - void UpdateVisualState() override; + void UpdateVisualState(bool record_main_frame_metrics) override; void WillBeginCompositorFrame() override; std::unique_ptr<cc::SwapPromise> RequestCopyOfOutputForLayoutTest( std::unique_ptr<viz::CopyOutputRequest> request) override;
diff --git a/content/shell/renderer/layout_test/blink_test_runner.cc b/content/shell/renderer/layout_test/blink_test_runner.cc index e142358..f2970fe 100644 --- a/content/shell/renderer/layout_test/blink_test_runner.cc +++ b/content/shell/renderer/layout_test/blink_test_runner.cc
@@ -444,7 +444,8 @@ // Clean out the lifecycle if needed before capturing the layout tree // dump and pixels from the compositor. auto* web_frame = render_view()->GetWebView()->MainFrame()->ToWebLocalFrame(); - web_frame->FrameWidget()->UpdateAllLifecyclePhases(); + web_frame->FrameWidget()->UpdateAllLifecyclePhases( + blink::WebWidget::LifecycleUpdateReason::kTest); // Initialize a new dump results object which we will populate in the calls // below.
diff --git a/content/shell/test_runner/event_sender.cc b/content/shell/test_runner/event_sender.cc index 8385f5e..04823b5 100644 --- a/content/shell/test_runner/event_sender.cc +++ b/content/shell/test_runner/event_sender.cc
@@ -1412,7 +1412,6 @@ int tiltY) { if (force_layout_on_events_) UpdateLifecycleToPrePaint(); - DCHECK_NE(-1, button_number); WebMouseEvent::Button button_type = @@ -2894,7 +2893,8 @@ } void EventSender::UpdateLifecycleToPrePaint() { - widget()->UpdateLifecycle(blink::WebWidget::LifecycleUpdate::kPrePaint); + widget()->UpdateLifecycle(blink::WebWidget::LifecycleUpdate::kPrePaint, + blink::WebWidget::LifecycleUpdateReason::kTest); } } // namespace test_runner
diff --git a/content/shell/test_runner/pixel_dump.cc b/content/shell/test_runner/pixel_dump.cc index 3cd04de..06a7c527 100644 --- a/content/shell/test_runner/pixel_dump.cc +++ b/content/shell/test_runner/pixel_dump.cc
@@ -69,7 +69,8 @@ blink::WebLocalFrame* web_frame, base::OnceCallback<void(const SkBitmap&)> callback) { auto* frame_widget = web_frame->LocalRoot()->FrameWidget(); - frame_widget->UpdateAllLifecyclePhases(); + frame_widget->UpdateAllLifecyclePhases( + blink::WebWidget::LifecycleUpdateReason::kTest); blink::WebSize page_size_in_pixels = frame_widget->Size();
diff --git a/content/shell/test_runner/test_plugin.h b/content/shell/test_runner/test_plugin.h index 20a4ce8..4449870 100644 --- a/content/shell/test_runner/test_plugin.h +++ b/content/shell/test_runner/test_plugin.h
@@ -74,7 +74,8 @@ blink::WebPluginContainer* Container() const override; bool CanProcessDrag() const override; bool SupportsKeyboardFocus() const override; - void UpdateAllLifecyclePhases() override {} + void UpdateAllLifecyclePhases( + blink::WebWidget::LifecycleUpdateReason) override {} void Paint(cc::PaintCanvas* canvas, const blink::WebRect& rect) override {} void UpdateGeometry(const blink::WebRect& window_rect, const blink::WebRect& clip_rect,
diff --git a/content/test/stub_layer_tree_view_delegate.h b/content/test/stub_layer_tree_view_delegate.h index 026008a..995bcb1d 100644 --- a/content/test/stub_layer_tree_view_delegate.h +++ b/content/test/stub_layer_tree_view_delegate.h
@@ -27,7 +27,7 @@ void DidCommitCompositorFrame() override {} void DidCompletePageScaleAnimation() override {} void RequestScheduleAnimation() override {} - void UpdateVisualState() override {} + void UpdateVisualState(bool record_main_frame_metrics) override {} void WillBeginCompositorFrame() override {} std::unique_ptr<cc::SwapPromise> RequestCopyOfOutputForLayoutTest( std::unique_ptr<viz::CopyOutputRequest> request) override;
diff --git a/ios/chrome/browser/find_in_page/resources/find_in_page.js b/ios/chrome/browser/find_in_page/resources/find_in_page.js index 1b1d60f9..96ead9f 100644 --- a/ios/chrome/browser/find_in_page/resources/find_in_page.js +++ b/ios/chrome/browser/find_in_page/resources/find_in_page.js
@@ -28,6 +28,66 @@ __gCrWeb.findInPage.spans = []; /** + * A replacement represents a DOM operation that swaps |oldNode| with |newNodes| + * under the parent of |oldNode| to highlight the match result inside |oldNode|. + * |newNodes| may contain plain TEXT Nodes for unhighlighted parts and + * <chrome_find> nodes for highlighted parts. This operation will be executed + * reversely when clearing current highlights for next FindInPage action. + */ +class Replacement { + /** + * Contructor for Replacement. + * @param {Node} The HTML Node containing search result. + * @param {Array<Node>} New HTML Nodes created for substitution of |oldNode|. + */ + constructor(oldNode, newNodes) { + this.oldNode = oldNode; + this.newNodes = newNodes; + } + + /** + * Executes the replacement to highlight search result. + * @return {undefined} + */ + doSwap() { + let parentNode = this.oldNode.parentNode; + if (!parentNode) + return; + for (var i = 0; i < this.newNodes.length; ++i) { + parentNode.insertBefore(this.newNodes[i], this.oldNode); + } + parentNode.removeChild(this.oldNode); + } + + /** + * Executes the replacement reversely to clear the highlight. + * @return {undefined} + */ + undoSwap() { + let parentNode = this.newNodes[0].parentNode; + if (!parentNode) + return; + parentNode.insertBefore(this.oldNode, this.newNodes[0]); + for (var i = 0; i < this.newNodes.length; ++i) { + parentNode.removeChild(this.newNodes[i]); + } + } +} + +/** + * The replacements of current FindInPage action. + * @type {Array<Replacement>} + */ +let replacements_ = []; + +/** + * The index of the Replacement from which the highlight process continue when + * pumpSearch is called. + * @type {Number} + */ +let replacementsIndex_ = 0; + +/** * The list of frame documents. * TODO(justincohen): x-domain frames won't work. * @type {Array<Document>} @@ -150,9 +210,6 @@ return NO_RESULTS; } - // Store all DOM modifications to do them in a tight loop at once. - __gCrWeb.findInPage.replacements = []; - // Node is what we are currently looking at. __gCrWeb.findInPage.node = document.body; @@ -170,8 +227,6 @@ // Index tracking variables so search can be broken up into multiple calls. __gCrWeb.findInPage.visibleIndex = 0; - __gCrWeb.findInPage.replacementsIndex = 0; - __gCrWeb.findInPage.replacementNewNodesIndex = 0; __gCrWeb.findInPage.regex = getRegex_(findText); @@ -243,7 +298,7 @@ node.textContent.substring(strIndex, node.textContent.length); nodes.push(node.ownerDocument.createTextNode(substr)); } - __gCrWeb.findInPage.replacements.push({oldNode: node, newNodes: nodes}); + replacements_.push(new Replacement(node, nodes)); regex.lastIndex = 0; } } @@ -258,34 +313,14 @@ } } - // Insert each of the replacement nodes into the old node's parent, then - // remove the old node. - let replacements = __gCrWeb.findInPage.replacements; - - // Last position in replacements array. - let rIndex = __gCrWeb.findInPage.replacementsIndex; - let rMax = replacements.length; - for (; rIndex < rMax; rIndex++) { - let replacement = replacements[rIndex]; - let parent = replacement.oldNode.parentNode; - if (parent == null) - continue; - let rNodesMax = replacement.newNodes.length; - for (let rNodesIndex = __gCrWeb.findInPage.replacementNewNodesIndex; - rNodesIndex < rNodesMax; rNodesIndex++) { - if (__gCrWeb.findInPage.overTime()) { - __gCrWeb.findInPage.replacementsIndex = rIndex; - __gCrWeb.findInPage.replacementNewNodesIndex = rNodesIndex; - return __gCrWeb.stringify([false]); - } - parent.insertBefore( - replacement.newNodes[rNodesIndex], replacement.oldNode); + // Execute replacements to highlight search results. + for (let i = replacementsIndex_; i < replacements_.length; ++i) { + if (__gCrWeb.findInPage.overTime()) { + replacementsIndex_ = i; + return __gCrWeb.stringify([false]); } - parent.removeChild(replacement.oldNode); - __gCrWeb.findInPage.replacementNewNodesIndex = 0; + replacements_[i].doSwap(); } - // Save last position in replacements array. - __gCrWeb.findInPage.replacementsIndex = rIndex; __gCrWeb.findInPage.spans = getAllElementsByClassName_(CSS_CLASS_NAME); @@ -355,64 +390,11 @@ * Note: It does not restore previous state, just removes the class name. */ function clearHighlight_() { - if (__gCrWeb.findInPage.index >= 0) { - removeSelectHighlight_(getCurrentSpan_()); + for (let i = 0; i < replacements_.length; ++i) { + replacements_[i].undoSwap(); } - // Store all DOM modifications to do them in a tight loop. - let modifications = []; - let length = __gCrWeb.findInPage.spans.length; - let prevParent = null; - for (let i = length - 1; i >= 0; i--) { - let elem = __gCrWeb.findInPage.spans[i]; - let parentNode = elem.parentNode; - // Safari has an occasional |elem.innerText| bug that drops the trailing - // space. |elem.innerText| would be more correct in this situation, but - // since we only allow text in this element, grabbing the HTML value should - // not matter. - let nodeText = elem.innerHTML; - // If this element has the same parent as the previous, check if we should - // add this node to the previous one. - if (prevParent && prevParent.isSameNode(parentNode) && - elem.nextSibling.isSameNode( - __gCrWeb.findInPage.spans[i + 1].previousSibling)) { - let prevMod = modifications[modifications.length - 1]; - prevMod.nodesToRemove.push(elem); - let elemText = elem.innerText; - if (elem.previousSibling) { - prevMod.nodesToRemove.push(elem.previousSibling); - elemText = elem.previousSibling.textContent + elemText; - } - prevMod.replacement.textContent = - elemText + prevMod.replacement.textContent; - } else { - // Element isn't attached to previous, so create a new modification. - let nodesToRemove = [elem]; - if (elem.previousSibling && elem.previousSibling.nodeType == 3) { - nodesToRemove.push(elem.previousSibling); - nodeText = elem.previousSibling.textContent + nodeText; - } - if (elem.nextSibling && elem.nextSibling.nodeType == 3) { - nodesToRemove.push(elem.nextSibling); - nodeText = nodeText + elem.nextSibling.textContent; - } - let textNode = elem.ownerDocument.createTextNode(nodeText); - modifications.push({nodesToRemove: nodesToRemove, replacement: textNode}); - } - prevParent = parentNode; - } - let numMods = modifications.length; - for (i = numMods - 1; i >= 0; i--) { - let mod = modifications[i]; - for (let j = 0; j < mod.nodesToRemove.length; j++) { - let existing = mod.nodesToRemove[j]; - if (j == 0) { - existing.parentNode.replaceChild(mod.replacement, existing); - } else { - existing.parentNode.removeChild(existing); - } - } - } - + replacements_ = []; + replacementsIndex_ = 0; __gCrWeb.findInPage.spans = []; __gCrWeb.findInPage.index = -1; };
diff --git a/ios/chrome/browser/infobars/confirm_infobar_controller+protected.h b/ios/chrome/browser/infobars/confirm_infobar_controller+protected.h index 7d9fff96..af13e0e 100644 --- a/ios/chrome/browser/infobars/confirm_infobar_controller+protected.h +++ b/ios/chrome/browser/infobars/confirm_infobar_controller+protected.h
@@ -11,8 +11,8 @@ @interface ConfirmInfoBarController () -// Accesses the view. -- (ConfirmInfoBarView*)view; +// Overrides superclass property. +@property(nonatomic, readwrite) ConfirmInfoBarView* view; // Action for any of the user defined buttons. - (void)infoBarButtonDidPress:(id)sender;
diff --git a/ios/chrome/browser/infobars/infobar_controller.h b/ios/chrome/browser/infobars/infobar_controller.h index fec6cacf..abec3eb 100644 --- a/ios/chrome/browser/infobars/infobar_controller.h +++ b/ios/chrome/browser/infobars/infobar_controller.h
@@ -23,8 +23,8 @@ // Removes the view. - (void)removeView; -// Accesses the view. -- (UIView*)view; +// The view. +@property(nonatomic, readonly) UIView* view; @property(nonatomic, assign) InfoBarControllerDelegate* delegate; // weak
diff --git a/ios/chrome/browser/infobars/infobar_controller.mm b/ios/chrome/browser/infobars/infobar_controller.mm index 1d0a698..75997be 100644 --- a/ios/chrome/browser/infobars/infobar_controller.mm +++ b/ios/chrome/browser/infobars/infobar_controller.mm
@@ -13,13 +13,12 @@ #error "This file requires ARC support." #endif -@interface InfoBarController () { - UIView* _infoBarView; -} +@interface InfoBarController () @end @implementation InfoBarController +@synthesize view = _view; @synthesize delegate = _delegate; @synthesize infoBarDelegate = _infoBarDelegate; @@ -30,21 +29,17 @@ self = [super init]; if (self) { _infoBarDelegate = infoBarDelegate; - _infoBarView = [self infobarView]; + _view = [self infobarView]; } return self; } - (void)dealloc { - [_infoBarView removeFromSuperview]; -} - -- (UIView*)view { - return _infoBarView; + [_view removeFromSuperview]; } - (void)removeView { - [_infoBarView removeFromSuperview]; + [_view removeFromSuperview]; } - (void)detachView { @@ -56,7 +51,7 @@ - (UIView*)infobarView { NOTREACHED() << "Must be overriden in subclasses."; - return _infoBarView; + return _view; } - (BOOL)shouldIgnoreUserInteraction {
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/address_coordinator.mm b/ios/chrome/browser/ui/autofill/manual_fill/address_coordinator.mm index f6a68b4..9e0f015 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/address_coordinator.mm +++ b/ios/chrome/browser/ui/autofill/manual_fill/address_coordinator.mm
@@ -9,6 +9,7 @@ #include "components/autofill/core/browser/autofill_profile.h" #include "components/autofill/core/browser/personal_data_manager.h" #include "components/autofill/ios/browser/autofill_driver_ios.h" +#import "components/autofill/ios/browser/personal_data_manager_observer_bridge.h" #include "components/keyed_service/core/service_access_type.h" #include "ios/chrome/browser/autofill/personal_data_manager_factory.h" #import "ios/chrome/browser/ui/autofill/manual_fill/address_list_delegate.h" @@ -23,7 +24,15 @@ #error "This file requires ARC support." #endif -@interface AddressCoordinator ()<AddressListDelegate> +@interface AddressCoordinator () <AddressListDelegate, + PersonalDataManagerObserver> { + // Personal data manager to be observed. + autofill::PersonalDataManager* _personalDataManager; + + // C++ to ObjC bridge for PersonalDataManagerObserver. + std::unique_ptr<autofill::PersonalDataManagerObserverBridge> + _personalDataManagerObserver; +} // The view controller presented above the keyboard where the user can select // a field from one of their addresses. @@ -52,11 +61,16 @@ _addressViewController = [[AddressViewController alloc] init]; _addressViewController.contentInsetsAlwaysEqualToSafeArea = YES; - autofill::PersonalDataManager* personalDataManager = + _personalDataManager = autofill::PersonalDataManagerFactory::GetForBrowserState(browserState); + DCHECK(_personalDataManager); + + _personalDataManagerObserver.reset( + new autofill::PersonalDataManagerObserverBridge(self)); + _personalDataManager->AddObserver(_personalDataManagerObserver.get()); std::vector<autofill::AutofillProfile*> profiles = - personalDataManager->GetProfilesToSuggest(); + _personalDataManager->GetProfilesToSuggest(); _addressMediator = [[ManualFillAddressMediator alloc] initWithProfiles:profiles]; @@ -67,6 +81,12 @@ return self; } +- (void)dealloc { + if (_personalDataManager) { + _personalDataManager->RemoveObserver(_personalDataManagerObserver.get()); + } +} + #pragma mark - FallbackCoordinator - (UIViewController*)viewController { @@ -82,4 +102,13 @@ }]; } +#pragma mark - PersonalDataManagerObserver + +- (void)onPersonalDataChanged { + std::vector<autofill::AutofillProfile*> profiles = + _personalDataManager->GetProfilesToSuggest(); + + [self.addressMediator reloadWithProfiles:profiles]; +} + @end
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/address_form.h b/ios/chrome/browser/ui/autofill/manual_fill/address_form.h index e62de54..07db77c 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/address_form.h +++ b/ios/chrome/browser/ui/autofill/manual_fill/address_form.h
@@ -7,6 +7,8 @@ #import "ios/chrome/browser/ui/autofill/manual_fill/address.h" +#include <vector> + namespace autofill { class AutofillProfile; } @@ -18,6 +20,11 @@ // Convenience initializer from an autofill::AutofillProfile. - (instancetype)initWithProfile:(const autofill::AutofillProfile&)profile; +// Converts a list of |autofill::AutofillProfile| into a list of +// |ManualFillAddress|. ++ (NSArray<ManualFillAddress*>*)manualFillAddressesFromProfiles: + (std::vector<autofill::AutofillProfile*>)profiles; + @end #endif // IOS_CHROME_BROWSER_UI_AUTOFILL_MANUAL_FILL_ADDRESS_FORM_H_
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/address_form.mm b/ios/chrome/browser/ui/autofill/manual_fill/address_form.mm index 9309cd55..6881579 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/address_form.mm +++ b/ios/chrome/browser/ui/autofill/manual_fill/address_form.mm
@@ -63,4 +63,15 @@ country:country]; } ++ (NSArray<ManualFillAddress*>*)manualFillAddressesFromProfiles: + (std::vector<autofill::AutofillProfile*>)profiles { + NSMutableArray<ManualFillAddress*>* manualFillAddresses = + [[NSMutableArray alloc] initWithCapacity:profiles.size()]; + for (autofill::AutofillProfile* profile : profiles) { + [manualFillAddresses + addObject:[[ManualFillAddress alloc] initWithProfile:*profile]]; + } + return manualFillAddresses; +} + @end
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/address_mediator.h b/ios/chrome/browser/ui/autofill/manual_fill/address_mediator.h index 85d9994..d73d285 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/address_mediator.h +++ b/ios/chrome/browser/ui/autofill/manual_fill/address_mediator.h
@@ -40,6 +40,9 @@ // Unavailable. Use |initWithProfiles:|. - (instancetype)init NS_UNAVAILABLE; +// Updates the |profiles| being presented. +- (void)reloadWithProfiles:(std::vector<autofill::AutofillProfile*>)profiles; + @end #endif // IOS_CHROME_BROWSER_UI_AUTOFILL_MANUAL_FILL_ADDRESS_MEDIATOR_H_
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/address_mediator.mm b/ios/chrome/browser/ui/autofill/manual_fill/address_mediator.mm index bd4b15c..2b87d06a 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/address_mediator.mm +++ b/ios/chrome/browser/ui/autofill/manual_fill/address_mediator.mm
@@ -42,13 +42,7 @@ (std::vector<autofill::AutofillProfile*>)profiles { self = [super init]; if (self) { - NSMutableArray<ManualFillAddress*>* manualFillAddresses = - [[NSMutableArray alloc] initWithCapacity:profiles.size()]; - for (autofill::AutofillProfile* profile : profiles) { - [manualFillAddresses - addObject:[[ManualFillAddress alloc] initWithProfile:*profile]]; - } - _addresses = manualFillAddresses; + _addresses = [ManualFillAddress manualFillAddressesFromProfiles:profiles]; } return self; } @@ -62,6 +56,14 @@ [self postActionsToConsumer]; } +- (void)reloadWithProfiles:(std::vector<autofill::AutofillProfile*>)profiles { + self.addresses = [ManualFillAddress manualFillAddressesFromProfiles:profiles]; + if (self.consumer) { + [self postAddressesToConsumer]; + [self postActionsToConsumer]; + } +} + #pragma mark - Private // Posts the addresses to the consumer.
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/card_coordinator.mm b/ios/chrome/browser/ui/autofill/manual_fill/card_coordinator.mm index c0e4e1b..245af5f 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/card_coordinator.mm +++ b/ios/chrome/browser/ui/autofill/manual_fill/card_coordinator.mm
@@ -8,6 +8,7 @@ #include "components/autofill/core/browser/credit_card.h" #include "components/autofill/core/browser/personal_data_manager.h" #include "components/autofill/ios/browser/autofill_driver_ios.h" +#import "components/autofill/ios/browser/personal_data_manager_observer_bridge.h" #include "ios/chrome/browser/autofill/personal_data_manager_factory.h" #import "ios/chrome/browser/ui/autofill/manual_fill/card_list_delegate.h" #import "ios/chrome/browser/ui/autofill/manual_fill/card_mediator.h" @@ -25,7 +26,14 @@ #error "This file requires ARC support." #endif -@interface CardCoordinator ()<CardListDelegate> +@interface CardCoordinator () <CardListDelegate, PersonalDataManagerObserver> { + // Personal data manager to be observed. + autofill::PersonalDataManager* _personalDataManager; + + // C++ to ObjC bridge for PersonalDataManagerObserver. + std::unique_ptr<autofill::PersonalDataManagerObserverBridge> + _personalDataManagerObserver; +} // The view controller presented above the keyboard where the user can select // one of their cards. @@ -58,15 +66,16 @@ _cardViewController = [[CardViewController alloc] init]; _cardViewController.contentInsetsAlwaysEqualToSafeArea = YES; - autofill::PersonalDataManager* personalDataManager = + _personalDataManager = autofill::PersonalDataManagerFactory::GetForBrowserState(browserState); + DCHECK(_personalDataManager); + + _personalDataManagerObserver.reset( + new autofill::PersonalDataManagerObserverBridge(self)); + _personalDataManager->AddObserver(_personalDataManagerObserver.get()); std::vector<autofill::CreditCard*> cards = - personalDataManager->GetCreditCardsToSuggest(true); - - // TODO(crbug.com/845472): add observer using - // PersonalDataManagerObserverBridge and refresh data when personal data - // changes. Applies to addresses too. + _personalDataManager->GetCreditCardsToSuggest(true); _cardMediator = [[ManualFillCardMediator alloc] initWithCards:cards]; _cardMediator.navigationDelegate = self; @@ -81,6 +90,12 @@ return self; } +- (void)dealloc { + if (_personalDataManager) { + _personalDataManager->RemoveObserver(_personalDataManagerObserver.get()); + } +} + #pragma mark - FallbackCoordinator - (UIViewController*)viewController { @@ -111,4 +126,13 @@ }]; } +#pragma mark - PersonalDataManagerObserver + +- (void)onPersonalDataChanged { + std::vector<autofill::CreditCard*> cards = + _personalDataManager->GetCreditCardsToSuggest(true); + + [self.cardMediator reloadWithCards:cards]; +} + @end
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/card_mediator.h b/ios/chrome/browser/ui/autofill/manual_fill/card_mediator.h index 9d0ca2a..fc6d6614 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/card_mediator.h +++ b/ios/chrome/browser/ui/autofill/manual_fill/card_mediator.h
@@ -48,6 +48,9 @@ // Finds the original autofill::CreditCard from given |GUID|. - (const autofill::CreditCard*)findCreditCardfromGUID:(NSString*)GUID; +// Updates the |cards| being presented. +- (void)reloadWithCards:(std::vector<autofill::CreditCard*>)cards; + @end #endif // IOS_CHROME_BROWSER_UI_AUTOFILL_MANUAL_FILL_CARD_MEDIATOR_H_
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/card_mediator.mm b/ios/chrome/browser/ui/autofill/manual_fill/card_mediator.mm index 8a51be4..8262aa1 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/card_mediator.mm +++ b/ios/chrome/browser/ui/autofill/manual_fill/card_mediator.mm
@@ -78,6 +78,14 @@ return nil; } +- (void)reloadWithCards:(std::vector<autofill::CreditCard*>)cards { + self.cards = cards; + if (self.consumer) { + [self postCardsToConsumer]; + [self postActionsToConsumer]; + } +} + #pragma mark - Private // Posts the cards to the consumer.
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_card_cell.mm b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_card_cell.mm index d0e18ca4..ae83ee96 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_card_cell.mm +++ b/ios/chrome/browser/ui/autofill/manual_fill/manual_fill_card_cell.mm
@@ -210,8 +210,8 @@ VerticalConstraintsSpacingForViewsInContainer( @[ - self.cardLabel, self.cardNumberButton, self.cardholderButton, - self.expirationMonthButton + self.cardLabel, self.cardNumberButton, self.expirationMonthButton, + self.cardholderButton ], self.contentView);
diff --git a/media/webrtc/audio_processor.cc b/media/webrtc/audio_processor.cc index 3ee152d2..097aa753 100644 --- a/media/webrtc/audio_processor.cc +++ b/media/webrtc/audio_processor.cc
@@ -315,6 +315,7 @@ settings_.automatic_gain_control == AutomaticGainControlType::kHybridExperimental; apm_config.gain_controller2.fixed_digital.gain_db = 0.f; + apm_config.gain_controller2.adaptive_digital.enabled = true; const bool use_peaks_not_rms = base::GetFieldTrialParamByFeatureAsBool( features::kWebRtcHybridAgc, "use_peaks_not_rms", false); using Shortcut =
diff --git a/net/base/registry_controlled_domains/effective_tld_names.dat b/net/base/registry_controlled_domains/effective_tld_names.dat index 49df459..69c7888 100644 --- a/net/base/registry_controlled_domains/effective_tld_names.dat +++ b/net/base/registry_controlled_domains/effective_tld_names.dat
@@ -1418,9 +1418,9 @@ tos.it toscana.it trentin-sud-tirol.it -trentin-süd-tirol.it +trentin-süd-tirol.it trentin-sudtirol.it -trentin-südtirol.it +trentin-südtirol.it trentin-sued-tirol.it trentin-suedtirol.it trentino-a-adige.it @@ -1430,9 +1430,9 @@ trentino-s-tirol.it trentino-stirol.it trentino-sud-tirol.it -trentino-süd-tirol.it +trentino-süd-tirol.it trentino-sudtirol.it -trentino-südtirol.it +trentino-südtirol.it trentino-sued-tirol.it trentino-suedtirol.it trentino.it @@ -1443,15 +1443,15 @@ trentinos-tirol.it trentinostirol.it trentinosud-tirol.it -trentinosüd-tirol.it +trentinosüd-tirol.it trentinosudtirol.it -trentinosüdtirol.it +trentinosüdtirol.it trentinosued-tirol.it trentinosuedtirol.it trentinsud-tirol.it -trentinsüd-tirol.it +trentinsüd-tirol.it trentinsudtirol.it -trentinsüdtirol.it +trentinsüdtirol.it trentinsued-tirol.it trentinsuedtirol.it tuscany.it @@ -1468,13 +1468,13 @@ valled-aosta.it valledaosta.it vallee-aoste.it -vallée-aoste.it +vallée-aoste.it vallee-d-aoste.it -vallée-d-aoste.it +vallée-d-aoste.it valleeaoste.it -valléeaoste.it +valléeaoste.it valleedaoste.it -valléedaoste.it +valléedaoste.it vao.it vda.it ven.it @@ -1508,7 +1508,7 @@ avellino.it ba.it balsan-sudtirol.it -balsan-südtirol.it +balsan-südtirol.it balsan-suedtirol.it balsan.it bari.it @@ -1527,7 +1527,7 @@ bolzano-altoadige.it bolzano.it bozen-sudtirol.it -bozen-südtirol.it +bozen-südtirol.it bozen-suedtirol.it bozen.it br.it @@ -1536,7 +1536,7 @@ bs.it bt.it bulsan-sudtirol.it -bulsan-südtirol.it +bulsan-südtirol.it bulsan-suedtirol.it bulsan.it bz.it @@ -1556,9 +1556,9 @@ cb.it ce.it cesena-forli.it -cesena-forlì.it +cesena-forlì.it cesenaforli.it -cesenaforlì.it +cesenaforlì.it ch.it chieti.it ci.it @@ -1589,9 +1589,9 @@ fm.it foggia.it forli-cesena.it -forlì-cesena.it +forlì-cesena.it forlicesena.it -forlìcesena.it +forlìcesena.it fr.it frosinone.it ge.it @@ -1722,7 +1722,7 @@ sr.it ss.it suedtirol.it -südtirol.it +südtirol.it sv.it ta.it taranto.it @@ -3794,10 +3794,18 @@ org.lr net.lr -// ls : https://en.wikipedia.org/wiki/.ls +// ls : http://www.nic.ls/ +// Confirmed by registry <lsadmin@nic.ls> ls +ac.ls +biz.ls co.ls +edu.ls +gov.ls +info.ls +net.ls org.ls +sc.ls // lt : https://en.wikipedia.org/wiki/.lt lt @@ -9878,9 +9886,6 @@ // statefarm : 2015-07-30 State Farm Mutual Automobile Insurance Company statefarm -// statoil : 2014-12-04 Statoil ASA -statoil - // stc : 2014-10-09 Saudi Telecom Company stc @@ -10839,6 +10844,11 @@ // Submitted by Vincent Tseng <vincenttseng@asustor.com> myasustor.com +// Automattic Inc. : https://automattic.com/ +// Submitted by Alex Concha <alex.concha@automattic.com> +go-vip.co +wpcomstaging.com + // AVM : https://avm.de // Submitted by Andreas Weise <a.weise@avm.de> myfritz.net @@ -10885,6 +10895,11 @@ // Submitted by Dave Tharp <browsersafetymark.io@quicinc.com> browsersafetymark.io +// Bytemark Hosting : https://www.bytemark.co.uk +// Submitted by Paul Cammish <paul.cammish@bytemark.co.uk> +dh.bytemark.co.uk +vm.bytemark.co.uk + // callidomus : https://www.callidomus.com/ // Submitted by Marcus Popp <admin@callidomus.com> mycd.eu @@ -11089,6 +11104,11 @@ // Submitted by Norbert Auler <mail@dnshome.de> dnshome.de +// DotArai : https://www.dotarai.com/ +// Submitted by Atsadawat Netcharadsang <atsadawat@dotarai.co.th> +online.th +shop.th + // DrayTek Corp. : https://www.draytek.com/ // Submitted by Paul Fang <mis@draytek.com> drayddns.com @@ -11645,6 +11665,10 @@ app.os.fedoraproject.org app.os.stg.fedoraproject.org +// Fermax : https://fermax.com/ +// submitted by Koen Van Isterdael <k.vanisterdael@fermax.be> +mydobiss.com + // Filegear Inc. : https://www.filegear.com // Submitted by Jason Zhu <jason@owtware.com> filegear.me @@ -11932,6 +11956,15 @@ // Submitted by Victor Velchev <admin@liquidnetlimited.com> we.bs +// LubMAN UMCS Sp. z o.o : https://lubman.pl/ +// Submitted by Ireneusz Maliszewski <ireneusz.maliszewski@lubman.pl> +krasnik.pl +leczna.pl +lubartow.pl +lublin.pl +poniatowa.pl +swidnik.pl + // Lug.org.uk : https://lug.org.uk // Submitted by Jon Spriggs <admin@lug.org.uk> uklugs.org @@ -12320,6 +12353,10 @@ chirurgiens-dentistes-en-france.fr byen.site +// Redstar Consultants : https://www.redstarconsultants.com/ +// Submitted by Jons Slemmer <jons@redstarconsultants.com> +instantcloud.cn + // Russian Academy of Sciences // Submitted by Tech Support <support@rasnet.ru> ras.ru @@ -12348,6 +12385,10 @@ rackmaze.com rackmaze.net +// Read The Docs, Inc : https://www.readthedocs.org +// Submitted by David Fischer <team@readthedocs.org> +readthedocs.io + // Red Hat, Inc. OpenShift : https://openshift.redhat.com/ // Submitted by Tim Kramer <tkramer@rhcloud.com> rhcloud.com @@ -12424,6 +12465,10 @@ sinaapp.com vipsinaapp.com +// Siteleaf : https://www.siteleaf.com/ +// Submitted by Skylar Challand <support@siteleaf.com> +siteleaf.net + // Skyhat : http://www.skyhat.io // Submitted by Shante Adam <shante@skyhat.io> bounty-full.com
diff --git a/net/base/registry_controlled_domains/effective_tld_names.gperf b/net/base/registry_controlled_domains/effective_tld_names.gperf index 79452b7..9443898 100644 --- a/net/base/registry_controlled_domains/effective_tld_names.gperf +++ b/net/base/registry_controlled_domains/effective_tld_names.gperf
@@ -90,6 +90,7 @@ ac.kr, 0 ac.leg.br, 4 ac.lk, 0 +ac.ls, 0 ac.ma, 0 ac.me, 0 ac.mu, 0 @@ -707,6 +708,7 @@ biz.et, 0 biz.id, 0 biz.ki, 0 +biz.ls, 0 biz.mv, 0 biz.mw, 0 biz.ni, 0 @@ -1699,6 +1701,7 @@ df.gov.br, 0 df.leg.br, 4 dgca.aero, 0 +dh.bytemark.co.uk, 4 dhl, 0 diamonds, 0 dielddanuorri.no, 0 @@ -1932,6 +1935,7 @@ edu.lc, 0 edu.lk, 0 edu.lr, 0 +edu.ls, 0 edu.lv, 0 edu.ly, 0 edu.me, 0 @@ -2580,6 +2584,7 @@ gmx, 0 gn, 0 gniezno.pl, 0 +go-vip.co, 4 go.ci, 0 go.cr, 0 go.dyndns.org, 4 @@ -2720,6 +2725,7 @@ gov.lc, 0 gov.lk, 0 gov.lr, 0 +gov.ls, 0 gov.lt, 0 gov.lv, 0 gov.ly, 0 @@ -3322,6 +3328,7 @@ info.ke, 0 info.ki, 0 info.la, 0 +info.ls, 0 info.mv, 0 info.na, 0 info.nf, 0 @@ -3344,6 +3351,7 @@ ingatlan.hu, 0 ink, 0 ino.kochi.jp, 0 +instantcloud.cn, 4 institute, 0 insurance, 0 insurance.aero, 0 @@ -4001,6 +4009,7 @@ kraanghke.no, 0 kragero.no, 0 krakow.pl, 4 +krasnik.pl, 4 krasnodar.su, 4 krd, 0 kred, 0 @@ -4153,6 +4162,7 @@ lecce.it, 0 lecco.it, 0 leclerc, 0 +leczna.pl, 4 lefrak, 0 leg.br, 0 legal, 0 @@ -4332,7 +4342,9 @@ lu, 0 lu.eu.org, 4 lu.it, 0 +lubartow.pl, 4 lubin.pl, 0 +lublin.pl, 4 lucania.it, 0 lucca.it, 0 lucerne.museum, 0 @@ -4888,6 +4900,7 @@ mydatto.net, 4 myddns.rocks, 4 mydissent.net, 4 +mydobiss.com, 4 mydrobo.com, 4 myds.me, 4 myeffect.net, 4 @@ -5151,6 +5164,7 @@ net.lc, 0 net.lk, 0 net.lr, 0 +net.ls, 0 net.lv, 0 net.ly, 0 net.ma, 0 @@ -5611,6 +5625,7 @@ onl, 0 online, 0 online.museum, 0 +online.th, 4 onna.okinawa.jp, 0 ono.fukui.jp, 0 ono.fukushima.jp, 0 @@ -6047,6 +6062,7 @@ poltava.ua, 0 pomorskie.pl, 0 pomorze.pl, 0 +poniatowa.pl, 4 ponpes.id, 0 pordenone.it, 0 porn, 0 @@ -6217,6 +6233,7 @@ read, 0 read-books.org, 4 readmyblog.org, 4 +readthedocs.io, 4 realestate, 0 realestate.pl, 0 realm.cz, 4 @@ -6565,6 +6582,7 @@ sc.ke, 0 sc.kr, 0 sc.leg.br, 4 +sc.ls, 0 sc.tz, 0 sc.ug, 0 sc.us, 0 @@ -6814,6 +6832,7 @@ shop.hu, 0 shop.pl, 0 shop.ro, 4 +shop.th, 4 shopping, 0 shouji, 0 show, 0 @@ -6844,6 +6863,7 @@ siracusa.it, 0 sirdal.no, 0 site, 0 +siteleaf.net, 4 sites.static.land, 4 sj, 0 sjc.br, 0 @@ -7004,7 +7024,6 @@ static.land, 4 statics.cloud, 6 station.museum, 0 -statoil, 0 stavanger.no, 0 stavern.no, 0 stc, 0 @@ -7095,6 +7114,7 @@ sweden.museum, 0 sweetpepper.org, 4 swidnica.pl, 0 +swidnik.pl, 4 swiebodzin.pl, 0 swiftcover, 0 swinoujscie.pl, 0 @@ -7835,6 +7855,7 @@ vladimir.ru, 4 vladimir.su, 4 vlog.br, 0 +vm.bytemark.co.uk, 4 vn, 0 vn.ua, 0 voagat.no, 0 @@ -7983,6 +8004,7 @@ world, 0 worse-than.tv, 4 wow, 0 +wpcomstaging.com, 4 wpdevcloud.com, 4 writesthisblog.com, 4 wroc.pl, 4
diff --git a/printing/backend/cups_jobs.cc b/printing/backend/cups_jobs.cc index 7bf2d20..e696bb0 100644 --- a/printing/backend/cups_jobs.cc +++ b/printing/backend/cups_jobs.cc
@@ -14,7 +14,7 @@ #include "base/stl_util.h" #include "base/strings/string_piece.h" #include "base/strings/stringprintf.h" -#include "base/threading/thread_restrictions.h" +#include "base/threading/scoped_blocking_call.h" #include "base/version.h" #include "printing/backend/cups_deleters.h" #include "printing/backend/cups_ipp_util.h" @@ -380,7 +380,6 @@ int num_attributes, const char* const* attributes, ipp_status_t* status) { - base::AssertBlockingAllowedDeprecated(); DCHECK(http); // CUPS expects a leading slash for resource names. Add one if it's missing. @@ -400,6 +399,7 @@ DCHECK_EQ(ippValidateAttributes(request.get()), 1); + base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::WILL_BLOCK); auto response = WrapIpp(cupsDoRequest(http, request.release(), rp.c_str())); *status = ippGetStatusCode(response.get()); @@ -434,7 +434,6 @@ const std::string& resource, bool encrypted, PrinterInfo* printer_info) { - base::AssertBlockingAllowedDeprecated(); ScopedHttpPtr http = ScopedHttpPtr(httpConnect2( address.c_str(), port, nullptr, AF_INET, @@ -470,7 +469,6 @@ bool GetPrinterStatus(http_t* http, const std::string& printer_id, PrinterStatus* printer_status) { - base::AssertBlockingAllowedDeprecated(); ipp_status_t status; const std::string printer_uri = PrinterUriFromName(printer_id); @@ -492,7 +490,6 @@ int limit, JobCompletionState which, std::vector<CupsJob>* jobs) { - base::AssertBlockingAllowedDeprecated(); DCHECK(http); auto request = WrapIpp(ippNewRequest(IPP_OP_GET_JOBS)); @@ -519,6 +516,7 @@ return false; } + base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK); // cupsDoRequest will delete the request. auto response = WrapIpp(cupsDoRequest(http, request.release(), "/"));
diff --git a/services/identity/identity_manager_impl.cc b/services/identity/identity_manager_impl.cc index 3d8d53a..d3f4bde4 100644 --- a/services/identity/identity_manager_impl.cc +++ b/services/identity/identity_manager_impl.cc
@@ -165,9 +165,9 @@ OnAccountStateChange(account_id); } -void IdentityManagerImpl::GoogleSigninSucceeded(const std::string& account_id, - const std::string& username) { - OnAccountStateChange(account_id); +void IdentityManagerImpl::GoogleSigninSucceeded( + const AccountInfo& account_info) { + OnAccountStateChange(account_info.account_id); } void IdentityManagerImpl::OnAccountStateChange(const std::string& account_id) {
diff --git a/services/identity/identity_manager_impl.h b/services/identity/identity_manager_impl.h index b9097fe..aac08b58 100644 --- a/services/identity/identity_manager_impl.h +++ b/services/identity/identity_manager_impl.h
@@ -85,8 +85,7 @@ void OnRefreshTokenAvailable(const std::string& account_id) override; // SigninManagerBase::Observer: - void GoogleSigninSucceeded(const std::string& account_id, - const std::string& username) override; + void GoogleSigninSucceeded(const AccountInfo& account_info) override; // Notified when there is a change in the state of the account // corresponding to |account_id|.
diff --git a/services/identity/public/cpp/identity_manager.cc b/services/identity/public/cpp/identity_manager.cc index 01ff5ce2..f3a2a989 100644 --- a/services/identity/public/cpp/identity_manager.cc +++ b/services/identity/public/cpp/identity_manager.cc
@@ -281,6 +281,14 @@ } } +void IdentityManager::GoogleSigninSucceededWithPassword( + const AccountInfo& account_info, + const std::string& password) { + for (auto& observer : observer_list_) { + observer.OnPrimaryAccountSetWithPassword(account_info, password); + } +} + void IdentityManager::GoogleSignedOut(const AccountInfo& account_info) { DCHECK(!HasPrimaryAccount()); for (auto& observer : observer_list_) {
diff --git a/services/identity/public/cpp/identity_manager.h b/services/identity/public/cpp/identity_manager.h index 9757a8d..7ab0c6c 100644 --- a/services/identity/public/cpp/identity_manager.h +++ b/services/identity/public/cpp/identity_manager.h
@@ -68,6 +68,14 @@ // This method is not called during a reauth. virtual void OnPrimaryAccountSet(const AccountInfo& primary_account_info) {} + // Called when an account becomes the user's primary account using the + // legacy workflow (non-DICE). If access to the password is not required, + // it is preferred to instead override OnPrimaryAccountSet() which will + // also be called at the same time. + virtual void OnPrimaryAccountSetWithPassword( + const AccountInfo& primary_account_info, + const std::string& password) {} + // Called when when the user moves from having a primary account to no // longer having a primary account. virtual void OnPrimaryAccountCleared( @@ -336,6 +344,8 @@ // SigninManagerBase::Observer: void GoogleSigninSucceeded(const AccountInfo& account_info) override; + void GoogleSigninSucceededWithPassword(const AccountInfo& account_info, + const std::string& password) override; void GoogleSignedOut(const AccountInfo& account_info) override; void GoogleSigninFailed(const GoogleServiceAuthError& error) override;
diff --git a/skia/config/SkUserConfig.h b/skia/config/SkUserConfig.h index fe2bab0..49c1a3f 100644 --- a/skia/config/SkUserConfig.h +++ b/skia/config/SkUserConfig.h
@@ -140,6 +140,10 @@ # define SK_SUPPORT_LEGACY_ANISOTROPIC_MIPMAP_SCALE #endif +#ifndef SK_SUPPORT_LEGACY_TEXTBLOBBUILD_WITH_PAINT +#define SK_SUPPORT_LEGACY_TEXTBLOBBUILD_WITH_PAINT +#endif + // Remove this after we fixed all the issues related to the new SDF algorithm // (https://codereview.chromium.org/1643143002) #ifndef SK_USE_LEGACY_DISTANCE_FIELDS
diff --git a/testing/buildbot/chromium.perf.fyi.json b/testing/buildbot/chromium.perf.fyi.json index dc28d20..17ff1580 100644 --- a/testing/buildbot/chromium.perf.fyi.json +++ b/testing/buildbot/chromium.perf.fyi.json
@@ -88,7 +88,7 @@ { "args": [ "-v", - "--browser=android-webview", + "--browser=android-webview-google", "--upload-results", "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk", "--test-shard-map-filename=android-go_webview-perf_map.json" @@ -225,7 +225,7 @@ { "args": [ "-v", - "--browser=android-webview", + "--browser=android-webview-google", "--upload-results", "--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk", "--test-shard-map-filename=android-pixel2_webview-perf_map.json"
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 7fa94d1..ac5fb35 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -2166,24 +2166,6 @@ ] } ], - "GuestViewCrossProcessFrames": [ - { - "platforms": [ - "chromeos", - "linux", - "mac", - "windows" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "GuestViewCrossProcessFrames" - ] - } - ] - } - ], "HTMLParsingYieldTime": [ { "platforms": [ @@ -4335,6 +4317,24 @@ ] } ], + "ScheduledScriptStreaming": [ + { + "platforms": [ + "android", + "chromeos", + "linux", + "windows" + ], + "experiments": [ + { + "name": "ScheduledScriptStreaming", + "enable_features": [ + "ScheduledScriptStreaming" + ] + } + ] + } + ], "SearchEnginePromo": [ { "platforms": [
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG index 324960b5..140b11a25 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -295,8 +295,8 @@ crbug.com/796943 fast/text/international/shape-across-elements-simple.html [ Pass ] crbug.com/591099 fast/text/whitespace/018.html [ Failure ] crbug.com/591099 fast/writing-mode/auto-sizing-orthogonal-flows.html [ Failure ] -crbug.com/714962 fast/writing-mode/background-vertical-lr.html [ Failure ] -crbug.com/591099 fast/writing-mode/basic-vertical-line.html [ Failure ] +crbug.com/850504 fast/writing-mode/background-vertical-lr.html [ Failure ] +crbug.com/850504 fast/writing-mode/basic-vertical-line.html [ Failure ] crbug.com/591099 fast/writing-mode/fieldsets.html [ Failure ] crbug.com/591099 fast/writing-mode/percentage-height-orthogonal-writing-modes.html [ Failure ] crbug.com/591099 fast/writing-mode/table-percent-width-quirk.html [ Pass ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 6e2e9a2..985240927 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -1814,8 +1814,6 @@ crbug.com/667560 [ Debug ] http/tests/devtools/elements/styles-3/styles-change-node-while-editing.js [ Pass Failure ] crbug.com/778515 http/tests/devtools/elements/styles-3/styles-add-new-rule.js [ Pass Failure ] -crbug.com/667560 http/tests/devtools/console-cross-origin-iframe-logging.js [ Pass Timeout ] - crbug.com/778391 http/tests/devtools/elements/styles-3/styles-add-new-rule-tab.js [ Pass Failure ] crbug.com/778391 http/tests/devtools/elements/styles-3/styles-disable-inherited.js [ Pass Failure ] @@ -2943,8 +2941,6 @@ crbug.com/626703 external/wpt/css/css-text/writing-system/writing-system-text-transform-001.html [ Failure ] crbug.com/626703 [ Win7 ] external/wpt/web-animations/animation-model/animation-types/accumulation-per-property.html [ Failure Timeout ] crbug.com/626703 [ Win7 ] external/wpt/IndexedDB/interleaved-cursors-large.html [ Crash ] -crbug.com/626703 virtual/webrtc-wpt-unified-plan/external/wpt/webrtc/RTCPeerConnection-track-stats.https.html [ Timeout ] -crbug.com/626703 external/wpt/webrtc/RTCPeerConnection-track-stats.https.html [ Timeout ] crbug.com/903383 external/wpt/css/filter-effects/filter-cb-abspos-inline-003.html [ Failure ] crbug.com/903383 external/wpt/css/filter-effects/css-filters-animation-combined-001.html [ Failure ] crbug.com/903383 external/wpt/css/filter-effects/css-filters-animation-blur.html [ Failure ] @@ -3826,14 +3822,12 @@ crbug.com/655458 external/wpt/workers/constructors/SharedWorker/setting-port-members.html [ Failure ] crbug.com/655458 external/wpt/workers/constructors/SharedWorker/connect-event.html [ Failure ] crbug.com/655458 external/wpt/workers/constructors/Worker/unresolvable-url.html [ Failure ] -crbug.com/655458 external/wpt/workers/interfaces/WorkerUtils/importScripts/004.html [ Failure ] crbug.com/655458 external/wpt/workers/semantics/reporting-errors/002.html [ Failure ] crbug.com/655458 external/wpt/workers/semantics/run-a-worker/003.html [ Failure ] crbug.com/655458 external/wpt/workers/Worker_terminate_event_queue.htm [ Pass Timeout ] crbug.com/655458 external/wpt/workers/interfaces/WorkerUtils/navigator/language.html [ Failure ] crbug.com/655458 external/wpt/workers/constructors/SharedWorker/interface-objects.html [ Failure ] crbug.com/655458 external/wpt/workers/constructors/SharedWorker/unresolvable-url.html [ Failure ] -crbug.com/655458 external/wpt/workers/interfaces/WorkerUtils/importScripts/006.html [ Failure Timeout ] crbug.com/655458 external/wpt/workers/semantics/multiple-workers/007.html [ Timeout ] crbug.com/655458 virtual/off-main-thread-worker-script-fetch/external/wpt/workers/constructors/SharedWorker/undefined-arguments.html [ Failure ] @@ -3841,14 +3835,12 @@ crbug.com/655458 virtual/off-main-thread-worker-script-fetch/external/wpt/workers/constructors/SharedWorker/setting-port-members.html [ Failure ] crbug.com/655458 virtual/off-main-thread-worker-script-fetch/external/wpt/workers/constructors/SharedWorker/connect-event.html [ Failure ] crbug.com/655458 virtual/off-main-thread-worker-script-fetch/external/wpt/workers/constructors/Worker/unresolvable-url.html [ Failure ] -crbug.com/655458 virtual/off-main-thread-worker-script-fetch/external/wpt/workers/interfaces/WorkerUtils/importScripts/004.html [ Failure ] crbug.com/655458 virtual/off-main-thread-worker-script-fetch/external/wpt/workers/semantics/reporting-errors/002.html [ Failure ] crbug.com/655458 virtual/off-main-thread-worker-script-fetch/external/wpt/workers/semantics/run-a-worker/003.html [ Failure ] crbug.com/655458 virtual/off-main-thread-worker-script-fetch/external/wpt/workers/Worker_terminate_event_queue.htm [ Pass Timeout ] crbug.com/655458 virtual/off-main-thread-worker-script-fetch/external/wpt/workers/interfaces/WorkerUtils/navigator/language.html [ Failure ] crbug.com/655458 virtual/off-main-thread-worker-script-fetch/external/wpt/workers/constructors/SharedWorker/interface-objects.html [ Failure ] crbug.com/655458 virtual/off-main-thread-worker-script-fetch/external/wpt/workers/constructors/SharedWorker/unresolvable-url.html [ Failure ] -crbug.com/655458 virtual/off-main-thread-worker-script-fetch/external/wpt/workers/interfaces/WorkerUtils/importScripts/006.html [ Failure Timeout ] crbug.com/655458 virtual/off-main-thread-worker-script-fetch/external/wpt/workers/semantics/multiple-workers/007.html [ Timeout ] # Off-the-main-thread classic worker script fetch. @@ -5364,3 +5356,9 @@ crbug.com/906952 editing/pasteboard/file-drag-to-editable.html [ Pass Crash ] crbug.com/906952 fast/events/before-unload-return-value-from-listener.html [ Pass Crash ] +#Sheriff 2018-11-21 + +# See also crbug.com/907150 +crbug.com/667560 http/tests/devtools/console-cross-origin-iframe-logging.js [ Pass Failure Timeout ] +crbug.com/907412 [ Mac10.13 ] external/wpt/domxpath/xml_xpath_runner.html [ Pass Timeout ] +crbug.com/907481 [ Win10 ] virtual/webrtc-wpt-unified-plan/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-nomsid.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST_5.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST_5.json index 98ed10da..a831f1f 100644 --- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST_5.json +++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST_5.json
@@ -50695,6 +50695,18 @@ {} ] ], + "css/css-masking/clip-path/clip-path-filter-order.html": [ + [ + "/css/css-masking/clip-path/clip-path-filter-order.html", + [ + [ + "/css/css-masking/clip-path/clip-path-filter-order-ref.html", + "==" + ] + ], + {} + ] + ], "css/css-masking/clip-path/clip-path-inline-001.html": [ [ "/css/css-masking/clip-path/clip-path-inline-001.html", @@ -50983,6 +50995,30 @@ {} ] ], + "css/css-masking/clip/clip-filter-order.html": [ + [ + "/css/css-masking/clip/clip-filter-order.html", + [ + [ + "/css/css-masking/clip/clip-filter-order-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-masking/clip/clip-fixed-pos-transform-descendant-001.html": [ + [ + "/css/css-masking/clip/clip-fixed-pos-transform-descendant-001.html", + [ + [ + "/css/css-masking/clip/clip-fixed-pos-transform-descendant-001-ref.html", + "==" + ] + ], + {} + ] + ], "css/css-masking/clip/clip-negative-values-001.html": [ [ "/css/css-masking/clip/clip-negative-values-001.html", @@ -104087,6 +104123,18 @@ {} ] ], + "svg/embedded/image-embedding-svg-with-viewport-units-inline-style.svg": [ + [ + "/svg/embedded/image-embedding-svg-with-viewport-units-inline-style.svg", + [ + [ + "/svg/embedded/support/green-rect-100x100.svg", + "==" + ] + ], + {} + ] + ], "svg/embedded/image-embedding-svg-with-viewport-units.svg": [ [ "/svg/embedded/image-embedding-svg-with-viewport-units.svg", @@ -104663,6 +104711,18 @@ {} ] ], + "svg/rendering/order/clip-path-filter-order.svg": [ + [ + "/svg/rendering/order/clip-path-filter-order.svg", + [ + [ + "/svg/rendering/order/clip-path-filter-order-ref.svg", + "==" + ] + ], + {} + ] + ], "svg/rendering/order/z-index.svg": [ [ "/svg/rendering/order/z-index.svg", @@ -117189,16 +117249,6 @@ {} ] ], - "cors/cors-safelisted-request-header.any-expected.txt": [ - [ - {} - ] - ], - "cors/cors-safelisted-request-header.any.worker-expected.txt": [ - [ - {} - ] - ], "cors/origin-expected.txt": [ [ {} @@ -135109,6 +135159,11 @@ {} ] ], + "css/css-masking/clip-path/clip-path-filter-order-ref.html": [ + [ + {} + ] + ], "css/css-masking/clip-path/reference/clip-path-circle-2-ref.html": [ [ {} @@ -135204,6 +135259,16 @@ {} ] ], + "css/css-masking/clip/clip-filter-order-ref.html": [ + [ + {} + ] + ], + "css/css-masking/clip/clip-fixed-pos-transform-descendant-001-ref.html": [ + [ + {} + ] + ], "css/css-masking/clip/reference/clip-absolute-positioned-ref.html": [ [ {} @@ -155439,6 +155504,11 @@ {} ] ], + "fetch/api/response/response-init-001-expected.txt": [ + [ + {} + ] + ], "fetch/api/response/response-trailer-expected.txt": [ [ {} @@ -173124,16 +173194,6 @@ {} ] ], - "referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html.headers": [ - [ - {} - ] - ], - "referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html.headers": [ - [ - {} - ] - ], "referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/insecure-protocol.http.html.headers": [ [ {} @@ -173464,16 +173524,6 @@ {} ] ], - "referrer-policy/no-referrer/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html.headers": [ - [ - {} - ] - ], - "referrer-policy/no-referrer/http-rp/same-origin/http-http/module-worker/no-redirect/generic.http.html.headers": [ - [ - {} - ] - ], "referrer-policy/no-referrer/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html.headers": [ [ {} @@ -173804,16 +173854,6 @@ {} ] ], - "referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/same-origin-insecure.http.html.headers": [ - [ - {} - ] - ], - "referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-http/module-worker/no-redirect/same-origin-insecure.http.html.headers": [ - [ - {} - ] - ], "referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/same-origin-insecure.http.html.headers": [ [ {} @@ -174249,16 +174289,6 @@ {} ] ], - "referrer-policy/origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html.headers": [ - [ - {} - ] - ], - "referrer-policy/origin/http-rp/same-origin/http-http/module-worker/no-redirect/generic.http.html.headers": [ - [ - {} - ] - ], "referrer-policy/origin/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html.headers": [ [ {} @@ -174589,16 +174619,6 @@ {} ] ], - "referrer-policy/same-origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/same-origin-insecure.http.html.headers": [ - [ - {} - ] - ], - "referrer-policy/same-origin/http-rp/same-origin/http-http/module-worker/no-redirect/same-origin-insecure.http.html.headers": [ - [ - {} - ] - ], "referrer-policy/same-origin/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/same-origin-insecure.http.html.headers": [ [ {} @@ -174884,16 +174904,6 @@ {} ] ], - "referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/same-insecure.http.html.headers": [ - [ - {} - ] - ], - "referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-http/module-worker/no-redirect/same-insecure.http.html.headers": [ - [ - {} - ] - ], "referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/same-insecure.http.html.headers": [ [ {} @@ -175224,16 +175234,6 @@ {} ] ], - "referrer-policy/strict-origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html.headers": [ - [ - {} - ] - ], - "referrer-policy/strict-origin/http-rp/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html.headers": [ - [ - {} - ] - ], "referrer-policy/strict-origin/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/insecure-protocol.http.html.headers": [ [ {} @@ -175564,16 +175564,6 @@ {} ] ], - "referrer-policy/unsafe-url/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html.headers": [ - [ - {} - ] - ], - "referrer-policy/unsafe-url/http-rp/same-origin/http-http/module-worker/no-redirect/generic.http.html.headers": [ - [ - {} - ] - ], "referrer-policy/unsafe-url/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html.headers": [ [ {} @@ -180724,6 +180714,11 @@ {} ] ], + "svg/rendering/order/clip-path-filter-order-ref.svg": [ + [ + {} + ] + ], "svg/rendering/order/z-index-ref.svg": [ [ {} @@ -207260,6 +207255,24 @@ {} ] ], + "css/css-tables/percent-width-ignored-001.tentative.html": [ + [ + "/css/css-tables/percent-width-ignored-001.tentative.html", + {} + ] + ], + "css/css-tables/percent-width-ignored-002.tentative.html": [ + [ + "/css/css-tables/percent-width-ignored-002.tentative.html", + {} + ] + ], + "css/css-tables/percent-width-ignored-003.tentative.html": [ + [ + "/css/css-tables/percent-width-ignored-003.tentative.html", + {} + ] + ], "css/css-tables/table-model-fixup-2.html": [ [ "/css/css-tables/table-model-fixup-2.html", @@ -208430,6 +208443,12 @@ {} ] ], + "css/css-text/text-indent/percentage-value-intrinsic-size.html": [ + [ + "/css/css-text/text-indent/percentage-value-intrinsic-size.html", + {} + ] + ], "css/css-text/white-space/seg-break-transformation-000.html": [ [ "/css/css-text/white-space/seg-break-transformation-000.html", @@ -213832,6 +213851,12 @@ {} ] ], + "css/selectors/invalidation/attribute.html": [ + [ + "/css/selectors/invalidation/attribute.html", + {} + ] + ], "css/selectors/invalidation/is.html": [ [ "/css/selectors/invalidation/is.html", @@ -213856,6 +213881,12 @@ {} ] ], + "css/selectors/invalidation/sibling.html": [ + [ + "/css/selectors/invalidation/sibling.html", + {} + ] + ], "css/selectors/invalidation/where.html": [ [ "/css/selectors/invalidation/where.html", @@ -257228,18 +257259,6 @@ {} ] ], - "referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html": [ - [ - "/referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html", - {} - ] - ], - "referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html": [ - [ - "/referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html", - {} - ] - ], "referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/insecure-protocol.http.html": [ [ "/referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/insecure-protocol.http.html", @@ -257636,18 +257655,6 @@ {} ] ], - "referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html": [ - [ - "/referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html", - {} - ] - ], - "referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html": [ - [ - "/referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html", - {} - ] - ], "referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/insecure-protocol.http.html": [ [ "/referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/insecure-protocol.http.html", @@ -258284,18 +258291,6 @@ {} ] ], - "referrer-policy/no-referrer/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html": [ - [ - "/referrer-policy/no-referrer/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html", - {} - ] - ], - "referrer-policy/no-referrer/http-rp/same-origin/http-http/module-worker/no-redirect/generic.http.html": [ - [ - "/referrer-policy/no-referrer/http-rp/same-origin/http-http/module-worker/no-redirect/generic.http.html", - {} - ] - ], "referrer-policy/no-referrer/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html": [ [ "/referrer-policy/no-referrer/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html", @@ -258692,18 +258687,6 @@ {} ] ], - "referrer-policy/no-referrer/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html": [ - [ - "/referrer-policy/no-referrer/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html", - {} - ] - ], - "referrer-policy/no-referrer/meta-referrer/same-origin/http-http/module-worker/no-redirect/generic.http.html": [ - [ - "/referrer-policy/no-referrer/meta-referrer/same-origin/http-http/module-worker/no-redirect/generic.http.html", - {} - ] - ], "referrer-policy/no-referrer/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html": [ [ "/referrer-policy/no-referrer/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html", @@ -259418,18 +259401,6 @@ {} ] ], - "referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/same-origin-insecure.http.html": [ - [ - "/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/same-origin-insecure.http.html", - {} - ] - ], - "referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-http/module-worker/no-redirect/same-origin-insecure.http.html": [ - [ - "/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-http/module-worker/no-redirect/same-origin-insecure.http.html", - {} - ] - ], "referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/same-origin-insecure.http.html": [ [ "/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/same-origin-insecure.http.html", @@ -259952,18 +259923,6 @@ {} ] ], - "referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/same-origin-insecure.http.html": [ - [ - "/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/same-origin-insecure.http.html", - {} - ] - ], - "referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-http/module-worker/no-redirect/same-origin-insecure.http.html": [ - [ - "/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-http/module-worker/no-redirect/same-origin-insecure.http.html", - {} - ] - ], "referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/same-origin-insecure.http.html": [ [ "/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/same-origin-insecure.http.html", @@ -260726,18 +260685,6 @@ {} ] ], - "referrer-policy/origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html": [ - [ - "/referrer-policy/origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html", - {} - ] - ], - "referrer-policy/origin/http-rp/same-origin/http-http/module-worker/no-redirect/generic.http.html": [ - [ - "/referrer-policy/origin/http-rp/same-origin/http-http/module-worker/no-redirect/generic.http.html", - {} - ] - ], "referrer-policy/origin/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html": [ [ "/referrer-policy/origin/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html", @@ -261134,18 +261081,6 @@ {} ] ], - "referrer-policy/origin/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html": [ - [ - "/referrer-policy/origin/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html", - {} - ] - ], - "referrer-policy/origin/meta-referrer/same-origin/http-http/module-worker/no-redirect/generic.http.html": [ - [ - "/referrer-policy/origin/meta-referrer/same-origin/http-http/module-worker/no-redirect/generic.http.html", - {} - ] - ], "referrer-policy/origin/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html": [ [ "/referrer-policy/origin/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html", @@ -261740,18 +261675,6 @@ {} ] ], - "referrer-policy/same-origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/same-origin-insecure.http.html": [ - [ - "/referrer-policy/same-origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/same-origin-insecure.http.html", - {} - ] - ], - "referrer-policy/same-origin/http-rp/same-origin/http-http/module-worker/no-redirect/same-origin-insecure.http.html": [ - [ - "/referrer-policy/same-origin/http-rp/same-origin/http-http/module-worker/no-redirect/same-origin-insecure.http.html", - {} - ] - ], "referrer-policy/same-origin/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/same-origin-insecure.http.html": [ [ "/referrer-policy/same-origin/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/same-origin-insecure.http.html", @@ -262082,18 +262005,6 @@ {} ] ], - "referrer-policy/same-origin/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/same-origin-insecure.http.html": [ - [ - "/referrer-policy/same-origin/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/same-origin-insecure.http.html", - {} - ] - ], - "referrer-policy/same-origin/meta-referrer/same-origin/http-http/module-worker/no-redirect/same-origin-insecure.http.html": [ - [ - "/referrer-policy/same-origin/meta-referrer/same-origin/http-http/module-worker/no-redirect/same-origin-insecure.http.html", - {} - ] - ], "referrer-policy/same-origin/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/same-origin-insecure.http.html": [ [ "/referrer-policy/same-origin/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/same-origin-insecure.http.html", @@ -262664,18 +262575,6 @@ {} ] ], - "referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/same-insecure.http.html": [ - [ - "/referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/same-insecure.http.html", - {} - ] - ], - "referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-http/module-worker/no-redirect/same-insecure.http.html": [ - [ - "/referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-http/module-worker/no-redirect/same-insecure.http.html", - {} - ] - ], "referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/same-insecure.http.html": [ [ "/referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/same-insecure.http.html", @@ -263072,18 +262971,6 @@ {} ] ], - "referrer-policy/strict-origin-when-cross-origin/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/same-insecure.http.html": [ - [ - "/referrer-policy/strict-origin-when-cross-origin/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/same-insecure.http.html", - {} - ] - ], - "referrer-policy/strict-origin-when-cross-origin/meta-referrer/same-origin/http-http/module-worker/no-redirect/same-insecure.http.html": [ - [ - "/referrer-policy/strict-origin-when-cross-origin/meta-referrer/same-origin/http-http/module-worker/no-redirect/same-insecure.http.html", - {} - ] - ], "referrer-policy/strict-origin-when-cross-origin/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/same-insecure.http.html": [ [ "/referrer-policy/strict-origin-when-cross-origin/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/same-insecure.http.html", @@ -263720,18 +263607,6 @@ {} ] ], - "referrer-policy/strict-origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html": [ - [ - "/referrer-policy/strict-origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html", - {} - ] - ], - "referrer-policy/strict-origin/http-rp/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html": [ - [ - "/referrer-policy/strict-origin/http-rp/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html", - {} - ] - ], "referrer-policy/strict-origin/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/insecure-protocol.http.html": [ [ "/referrer-policy/strict-origin/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/insecure-protocol.http.html", @@ -264128,18 +264003,6 @@ {} ] ], - "referrer-policy/strict-origin/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html": [ - [ - "/referrer-policy/strict-origin/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html", - {} - ] - ], - "referrer-policy/strict-origin/meta-referrer/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html": [ - [ - "/referrer-policy/strict-origin/meta-referrer/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html", - {} - ] - ], "referrer-policy/strict-origin/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/insecure-protocol.http.html": [ [ "/referrer-policy/strict-origin/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/insecure-protocol.http.html", @@ -264776,18 +264639,6 @@ {} ] ], - "referrer-policy/unsafe-url/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html": [ - [ - "/referrer-policy/unsafe-url/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html", - {} - ] - ], - "referrer-policy/unsafe-url/http-rp/same-origin/http-http/module-worker/no-redirect/generic.http.html": [ - [ - "/referrer-policy/unsafe-url/http-rp/same-origin/http-http/module-worker/no-redirect/generic.http.html", - {} - ] - ], "referrer-policy/unsafe-url/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html": [ [ "/referrer-policy/unsafe-url/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html", @@ -265184,18 +265035,6 @@ {} ] ], - "referrer-policy/unsafe-url/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html": [ - [ - "/referrer-policy/unsafe-url/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html", - {} - ] - ], - "referrer-policy/unsafe-url/meta-referrer/same-origin/http-http/module-worker/no-redirect/generic.http.html": [ - [ - "/referrer-policy/unsafe-url/meta-referrer/same-origin/http-http/module-worker/no-redirect/generic.http.html", - {} - ] - ], "referrer-policy/unsafe-url/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html": [ [ "/referrer-policy/unsafe-url/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html", @@ -265832,18 +265671,6 @@ {} ] ], - "referrer-policy/unset-referrer-policy/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html": [ - [ - "/referrer-policy/unset-referrer-policy/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html", - {} - ] - ], - "referrer-policy/unset-referrer-policy/http-rp/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html": [ - [ - "/referrer-policy/unset-referrer-policy/http-rp/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html", - {} - ] - ], "referrer-policy/unset-referrer-policy/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/insecure-protocol.http.html": [ [ "/referrer-policy/unset-referrer-policy/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/insecure-protocol.http.html", @@ -266240,18 +266067,6 @@ {} ] ], - "referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html": [ - [ - "/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html", - {} - ] - ], - "referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html": [ - [ - "/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html", - {} - ] - ], "referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/insecure-protocol.http.html": [ [ "/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/insecure-protocol.http.html", @@ -276162,6 +275977,12 @@ {} ] ], + "webrtc/RTCPeerConnection-setRemoteDescription-nomsid.html": [ + [ + "/webrtc/RTCPeerConnection-setRemoteDescription-nomsid.html", + {} + ] + ], "webrtc/RTCPeerConnection-setRemoteDescription-offer.html": [ [ "/webrtc/RTCPeerConnection-setRemoteDescription-offer.html", @@ -304277,18 +304098,10 @@ "ee6c7ea7e86f032e3da96e99747c743a16ba44e2", "testharness" ], - "cors/cors-safelisted-request-header.any-expected.txt": [ - "a098d0780da2e08b68becc0f8beb15d08af1633e", - "support" - ], "cors/cors-safelisted-request-header.any.js": [ "d7bb5e70b8e739dbdd57b0bf61d50dd62d4d3765", "testharness" ], - "cors/cors-safelisted-request-header.any.worker-expected.txt": [ - "a098d0780da2e08b68becc0f8beb15d08af1633e", - "support" - ], "cors/credentials-flag.htm": [ "45a714368560936439889855c36453463295ae51", "testharness" @@ -340529,6 +340342,14 @@ "12df558fd2c2fa64783720cb9d1be07fa7f85572", "reftest" ], + "css/css-masking/clip-path/clip-path-filter-order-ref.html": [ + "5fdef1e3007ab77cd5b03814419890ec69b91970", + "support" + ], + "css/css-masking/clip-path/clip-path-filter-order.html": [ + "5806e75d536cc34a4610630782e5cdfd4b5e552d", + "reftest" + ], "css/css-masking/clip-path/clip-path-inline-001.html": [ "21acae0ee7e06da76a6b5830e5aaa6b5e0d2e6a6", "reftest" @@ -340701,6 +340522,22 @@ "53b2517a2726166fecc3f274760724b9962ac746", "reftest" ], + "css/css-masking/clip/clip-filter-order-ref.html": [ + "e5763bfdf707fc7219bb0f7431e5c48a2b45952a", + "support" + ], + "css/css-masking/clip/clip-filter-order.html": [ + "79f2f71488d31185cbf1011db9e4d2e489d0377c", + "reftest" + ], + "css/css-masking/clip/clip-fixed-pos-transform-descendant-001-ref.html": [ + "ed78cb7338c8dc9f24afb04870e3fbb1fb1c107e", + "support" + ], + "css/css-masking/clip/clip-fixed-pos-transform-descendant-001.html": [ + "395b0bc96456080f4216cf4fd556ddfef1fd3e75", + "reftest" + ], "css/css-masking/clip/clip-negative-values-001.html": [ "b295c89ba37b11e9f6fd814ac0bfcea04d2312e5", "reftest" @@ -346193,6 +346030,18 @@ "a8745487b6702b8b8e8ac85bd843014dc296b717", "reftest" ], + "css/css-tables/percent-width-ignored-001.tentative.html": [ + "214eee7152b66a4198a2e81d7d62da9a295b5d98", + "testharness" + ], + "css/css-tables/percent-width-ignored-002.tentative.html": [ + "97f6f4904c159983de44020c9d8998fdfedf023b", + "testharness" + ], + "css/css-tables/percent-width-ignored-003.tentative.html": [ + "3df8548ce2f9e346e83aaa617b3d36839c24e4b6", + "testharness" + ], "css/css-tables/percentages-grandchildren-quirks-mode-001.html": [ "b6b6d245ab2f2c56ae5ac51c96a771e5acd5f084", "reftest" @@ -349809,6 +349658,10 @@ "1b8d9728b6738022ba5762e49e8fc8f54ace2ef5", "visual" ], + "css/css-text/text-indent/percentage-value-intrinsic-size.html": [ + "d63a9f1ba25f31dec6c719b35c19eae7b380e695", + "testharness" + ], "css/css-text/text-indent/reference/text-indent-percentage-001-ref.xht": [ "b8e8d62a08acca9f38a3ec54e2bba4d7793666b9", "support" @@ -371533,6 +371386,10 @@ "9792fd0ebe1c77307ec1cfb6f572fc5d8e139e6a", "testharness" ], + "css/selectors/invalidation/attribute.html": [ + "3bda52c91db1c088cfb8a98d417d80bf1c2a2e59", + "testharness" + ], "css/selectors/invalidation/is-expected.txt": [ "bfffd7473bb1eb5c2624f91dae96b49c6e1269ad", "support" @@ -371561,6 +371418,10 @@ "41778239518d4d9b602f7fc18ee3ea5c910da85b", "reftest" ], + "css/selectors/invalidation/sibling.html": [ + "c0e04fb8b3a048a42e3ea9afdb2a70423245ba24", + "testharness" + ], "css/selectors/invalidation/where.html": [ "170398300f0b4359139c597937f84e69e774a71e", "testharness" @@ -384929,8 +384790,12 @@ "81ae70ea0cfc04c5d8398d575bf251c499cbdeff", "support" ], + "fetch/api/response/response-init-001-expected.txt": [ + "07ed8a6d181f40e6c96c20ecf0bb1722bedb8e83", + "support" + ], "fetch/api/response/response-init-001.html": [ - "cd89448bbbef388e69a2ef4b2aecf04bafb728f2", + "7af23d310f1ace9ad9827b8dd4e9e5ca17d26b5e", "testharness" ], "fetch/api/response/response-init-002.html": [ @@ -385322,7 +385187,7 @@ "support" ], "fetch/data-urls/processing.any-expected.txt": [ - "645f1166842bd6b88092026de608cf69ef9c26f2", + "a0a3296b6cff0e1cadcabeeb582501c1897a26d5", "support" ], "fetch/data-urls/processing.any.js": [ @@ -385330,7 +385195,7 @@ "testharness" ], "fetch/data-urls/processing.any.worker-expected.txt": [ - "645f1166842bd6b88092026de608cf69ef9c26f2", + "a0a3296b6cff0e1cadcabeeb582501c1897a26d5", "support" ], "fetch/data-urls/resources/base64.json": [ @@ -385642,7 +385507,7 @@ "support" ], "fetch/sec-metadata/resources/record-header.py": [ - "b81e93ec3c09a4bbfae7190e39508b31b68edfd7", + "adf9a53fa17024537b8fce48023a52b62d853a12", "support" ], "fetch/sec-metadata/resources/sharedWorker.js": [ @@ -419118,7 +418983,7 @@ "testharness" ], "picture-in-picture/mediastream.html": [ - "7a2cc958eacdd7e7bd2d074fcc909813fdeeeaa3", + "e187de3d4b6c7d5d30ae1cec690b08dbf3f3b673", "testharness" ], "picture-in-picture/picture-in-picture-element.html": [ @@ -420298,7 +420163,7 @@ "testharness" ], "referrer-policy/generic/common.js": [ - "4a3befefc590353906b690d62ff130f3302b86eb", + "c98056f680b49b7d765064e9c6d5403ed0cfd21b", "support" ], "referrer-policy/generic/iframe-inheritance.html": [ @@ -420350,7 +420215,7 @@ "support" ], "referrer-policy/generic/referrer-policy-test-case.js": [ - "f19407157d6125642da948ebe7bd1c80c4418777", + "14ccd4e2de171e5c8b284e2ced552024b28d345d", "support" ], "referrer-policy/generic/sandboxed-iframe-with-opaque-origin.html": [ @@ -421013,22 +420878,6 @@ "f2152da955f3295aec2ac05adc2357ac7629cf7b", "support" ], - "referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html": [ - "6cc76f7583b2f1bcdff27ee6e2fdba8634d26afb", - "testharness" - ], - "referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html.headers": [ - "f2152da955f3295aec2ac05adc2357ac7629cf7b", - "support" - ], - "referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html": [ - "7eb7b813825853a2207d5016fcd1fd017c71c903", - "testharness" - ], - "referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html.headers": [ - "f2152da955f3295aec2ac05adc2357ac7629cf7b", - "support" - ], "referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/insecure-protocol.http.html": [ "c0fe57edd2661e8ae300b6b07f81abe43a0103d7", "testharness" @@ -421389,14 +421238,6 @@ "ce744e0093b15d266dacd23992ae2201f0436987", "testharness" ], - "referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html": [ - "574cdccc9b6dc4f06fa5193088361069c1fb4f56", - "testharness" - ], - "referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html": [ - "f452387ad236f0b0486bc017d63f92880a9cd6f9", - "testharness" - ], "referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/insecure-protocol.http.html": [ "a70858c0585033e2f46fb80175b6b912aa1d2ede", "testharness" @@ -421989,22 +421830,6 @@ "9b531426e5ab952b03e88b378feb5672a1e5eb4e", "support" ], - "referrer-policy/no-referrer/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html": [ - "b18fbef56a84c969c71e014e28d7cd4e8e984a0b", - "testharness" - ], - "referrer-policy/no-referrer/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html.headers": [ - "9b531426e5ab952b03e88b378feb5672a1e5eb4e", - "support" - ], - "referrer-policy/no-referrer/http-rp/same-origin/http-http/module-worker/no-redirect/generic.http.html": [ - "3edc386aaa29596a1d61b9f37b6ec03a5cf990f4", - "testharness" - ], - "referrer-policy/no-referrer/http-rp/same-origin/http-http/module-worker/no-redirect/generic.http.html.headers": [ - "9b531426e5ab952b03e88b378feb5672a1e5eb4e", - "support" - ], "referrer-policy/no-referrer/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html": [ "4f12853c0fcb909db6e403deb430e835cf229b38", "testharness" @@ -422365,14 +422190,6 @@ "ea981ad14d08b7fde416e46ee26258ee80f566cb", "testharness" ], - "referrer-policy/no-referrer/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html": [ - "ea935b1d542aae46f105f6be8eff04d448a868db", - "testharness" - ], - "referrer-policy/no-referrer/meta-referrer/same-origin/http-http/module-worker/no-redirect/generic.http.html": [ - "e22b638b5d16c44b9c5d58ad72e7e3ab29124079", - "testharness" - ], "referrer-policy/no-referrer/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html": [ "222b078cc664e0472642788c35238e6d29ef2b1e", "testharness" @@ -423017,22 +422834,6 @@ "9ce1de38843b358434a917f1c992c99d0c7fd9fb", "support" ], - "referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/same-origin-insecure.http.html": [ - "291f4928bad916933a32c2e50f1cfd649c70d52d", - "testharness" - ], - "referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/same-origin-insecure.http.html.headers": [ - "9ce1de38843b358434a917f1c992c99d0c7fd9fb", - "support" - ], - "referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-http/module-worker/no-redirect/same-origin-insecure.http.html": [ - "f4006d10ac47f7f3d026326026352f5da09fb495", - "testharness" - ], - "referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-http/module-worker/no-redirect/same-origin-insecure.http.html.headers": [ - "9ce1de38843b358434a917f1c992c99d0c7fd9fb", - "support" - ], "referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/same-origin-insecure.http.html": [ "61669344ddd77739934d94de3d0cd4afdac7b2c2", "testharness" @@ -423561,14 +423362,6 @@ "0245434f37cc429db0c28948169f4af353cfb2e7", "testharness" ], - "referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/same-origin-insecure.http.html": [ - "12b857b64dcfd55e208c7082b19af53338599105", - "testharness" - ], - "referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-http/module-worker/no-redirect/same-origin-insecure.http.html": [ - "056ff4efbf29acf8372713dce4ed5f7fc018da7a", - "testharness" - ], "referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/same-origin-insecure.http.html": [ "969d7e8dd4c9b634b5233859e1a11d93fb33239b", "testharness" @@ -424245,22 +424038,6 @@ "306a53536ac57625957da5cf4ff55e4124276617", "support" ], - "referrer-policy/origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html": [ - "db8e7be2376b0119fb9f4ce37a72df943bf51507", - "testharness" - ], - "referrer-policy/origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html.headers": [ - "306a53536ac57625957da5cf4ff55e4124276617", - "support" - ], - "referrer-policy/origin/http-rp/same-origin/http-http/module-worker/no-redirect/generic.http.html": [ - "5a335d0863cafbfd15e95b6b1fcb7cde9b14663a", - "testharness" - ], - "referrer-policy/origin/http-rp/same-origin/http-http/module-worker/no-redirect/generic.http.html.headers": [ - "306a53536ac57625957da5cf4ff55e4124276617", - "support" - ], "referrer-policy/origin/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html": [ "04027e95f075c85d94be9a973c85081fc9b70f71", "testharness" @@ -424621,14 +424398,6 @@ "65ed223f1ec81b5f5257a37f77bab0ba640de725", "testharness" ], - "referrer-policy/origin/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html": [ - "87ebfbfa0b0ae7854dd5747c073ca39b68e50d5b", - "testharness" - ], - "referrer-policy/origin/meta-referrer/same-origin/http-http/module-worker/no-redirect/generic.http.html": [ - "0cf72a93e9e9f89628be50a54b6920e3eeae12dd", - "testharness" - ], "referrer-policy/origin/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html": [ "96e7d4e7bf935bc23118970f04c719a60cca465f", "testharness" @@ -425193,22 +424962,6 @@ "309da8091a927735fec71fbd4af9acb39eb3a964", "support" ], - "referrer-policy/same-origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/same-origin-insecure.http.html": [ - "8da4f3b3be0d75ddb57d280e2b9de46c0479c607", - "testharness" - ], - "referrer-policy/same-origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/same-origin-insecure.http.html.headers": [ - "309da8091a927735fec71fbd4af9acb39eb3a964", - "support" - ], - "referrer-policy/same-origin/http-rp/same-origin/http-http/module-worker/no-redirect/same-origin-insecure.http.html": [ - "424221d94140ef5b31500f0f3e4fcf0cd5e4047f", - "testharness" - ], - "referrer-policy/same-origin/http-rp/same-origin/http-http/module-worker/no-redirect/same-origin-insecure.http.html.headers": [ - "309da8091a927735fec71fbd4af9acb39eb3a964", - "support" - ], "referrer-policy/same-origin/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/same-origin-insecure.http.html": [ "bbc8f26a58338d88d412759d3dc8d212fe36c6a8", "testharness" @@ -425481,14 +425234,6 @@ "fe2b40c58d48dad8df2d4ed9dd54fbeb1ba59389", "testharness" ], - "referrer-policy/same-origin/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/same-origin-insecure.http.html": [ - "c0d87fa32023fd8914ff1e0a1b438e6cd4ec0617", - "testharness" - ], - "referrer-policy/same-origin/meta-referrer/same-origin/http-http/module-worker/no-redirect/same-origin-insecure.http.html": [ - "8586b96fe8b0e66ebfc6fa9c8bf4911d8500a50b", - "testharness" - ], "referrer-policy/same-origin/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/same-origin-insecure.http.html": [ "18f3dbc804e5d2ba22a8df980744f01ffd8c1399", "testharness" @@ -425542,11 +425287,11 @@ "testharness" ], "referrer-policy/spec.src.json": [ - "e67b8c53a94bb227f09f19ea21f588f086e01975", + "1ee2b70ee020f7535ab0753626c6863bb085d9c7", "support" ], "referrer-policy/spec_json.js": [ - "5377df740f757bd8ebfe3a4e893afc8edfe193a6", + "dd1962dbe0c756077e10aca280c4c4dbfda84fc1", "support" ], "referrer-policy/strict-origin-when-cross-origin/attr-referrer/cross-origin/http-http/a-tag/no-redirect/cross-insecure.http.html": [ @@ -426045,22 +425790,6 @@ "d74467b0af6f7dda8bee9107a37e9c14661a9054", "support" ], - "referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/same-insecure.http.html": [ - "80d2dcd0787beeed2e906f31d1f562f1b83d2c26", - "testharness" - ], - "referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/same-insecure.http.html.headers": [ - "d74467b0af6f7dda8bee9107a37e9c14661a9054", - "support" - ], - "referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-http/module-worker/no-redirect/same-insecure.http.html": [ - "695afae60374a9604c9314701a0fe5193b26c48f", - "testharness" - ], - "referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-http/module-worker/no-redirect/same-insecure.http.html.headers": [ - "d74467b0af6f7dda8bee9107a37e9c14661a9054", - "support" - ], "referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/same-insecure.http.html": [ "16c752ce04c794227da700bb8f588aefea4e4f6b", "testharness" @@ -426421,14 +426150,6 @@ "28a143047e54ff10c972fd052d8be01186da4504", "testharness" ], - "referrer-policy/strict-origin-when-cross-origin/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/same-insecure.http.html": [ - "a74c968cd6f62a03a210ce28cf9070ada039cff8", - "testharness" - ], - "referrer-policy/strict-origin-when-cross-origin/meta-referrer/same-origin/http-http/module-worker/no-redirect/same-insecure.http.html": [ - "e75274330b59cd092fedf6a8c00a2c7552105273", - "testharness" - ], "referrer-policy/strict-origin-when-cross-origin/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/same-insecure.http.html": [ "06e0cf6ccb57eefa6e13c117fa7a1ce5d6da7cd8", "testharness" @@ -427021,22 +426742,6 @@ "07af8e286fd7431890f78f10b9e8a0f4b106b5cc", "support" ], - "referrer-policy/strict-origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html": [ - "82b67545c48b83ef16fbad140020ac89513b91fe", - "testharness" - ], - "referrer-policy/strict-origin/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html.headers": [ - "07af8e286fd7431890f78f10b9e8a0f4b106b5cc", - "support" - ], - "referrer-policy/strict-origin/http-rp/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html": [ - "bb8d797d0cb21555280f569442230882ff3898e2", - "testharness" - ], - "referrer-policy/strict-origin/http-rp/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html.headers": [ - "07af8e286fd7431890f78f10b9e8a0f4b106b5cc", - "support" - ], "referrer-policy/strict-origin/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/insecure-protocol.http.html": [ "56fdc7923fd4fe507f9ddaf81da6f56b20f4210a", "testharness" @@ -427397,14 +427102,6 @@ "46a7a33c3ff1bf81d4bc97e1e9fa1ee3c496397d", "testharness" ], - "referrer-policy/strict-origin/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html": [ - "f60cef60c73b7d6abce9d6474a11928f2b2202c7", - "testharness" - ], - "referrer-policy/strict-origin/meta-referrer/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html": [ - "3ee6b651a90dfcc0356fb8db435a04cad7a46c89", - "testharness" - ], "referrer-policy/strict-origin/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/insecure-protocol.http.html": [ "6186d57f3f85397c8a057a71ca1769b54aadcfd8", "testharness" @@ -427997,22 +427694,6 @@ "c67e521584390fb6c068bcb1a814d73ed9543570", "support" ], - "referrer-policy/unsafe-url/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html": [ - "8d97cd77bfd1b348322f9bd5e21c26bc005d9833", - "testharness" - ], - "referrer-policy/unsafe-url/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html.headers": [ - "c67e521584390fb6c068bcb1a814d73ed9543570", - "support" - ], - "referrer-policy/unsafe-url/http-rp/same-origin/http-http/module-worker/no-redirect/generic.http.html": [ - "a3291b0ca86e9595880c80032db774885d2f0cbe", - "testharness" - ], - "referrer-policy/unsafe-url/http-rp/same-origin/http-http/module-worker/no-redirect/generic.http.html.headers": [ - "c67e521584390fb6c068bcb1a814d73ed9543570", - "support" - ], "referrer-policy/unsafe-url/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html": [ "435281a74c99e98b5e4ec8143cd6d7c82f7dc269", "testharness" @@ -428373,14 +428054,6 @@ "7fe2baacff826cc8b3c13e4a81f60e3897df4332", "testharness" ], - "referrer-policy/unsafe-url/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/generic.http.html": [ - "c33155b299903c196404e8a09ac8114b011640f7", - "testharness" - ], - "referrer-policy/unsafe-url/meta-referrer/same-origin/http-http/module-worker/no-redirect/generic.http.html": [ - "eae3381ae927126b06371038823c423585e6b8ab", - "testharness" - ], "referrer-policy/unsafe-url/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/generic.http.html": [ "e1db3d1e59e260c85aa36b3d01efe592513d5e1f", "testharness" @@ -428805,14 +428478,6 @@ "621aaf86a285df38b4298ec486e25016d968f004", "testharness" ], - "referrer-policy/unset-referrer-policy/http-rp/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html": [ - "aa5a9ac86bb5bc899ad21444c9591c33273ea09a", - "testharness" - ], - "referrer-policy/unset-referrer-policy/http-rp/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html": [ - "c2201e9c4e210fb68f52b924d96ed0268c09ffa7", - "testharness" - ], "referrer-policy/unset-referrer-policy/http-rp/same-origin/http-http/script-tag/keep-origin-redirect/insecure-protocol.http.html": [ "2c16b549ae919f7f4524d0f455434df0456f1e34", "testharness" @@ -429077,14 +428742,6 @@ "842e32d571fe2af5253a171eae12bdf8c3f39848", "testharness" ], - "referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-http/module-worker/keep-origin-redirect/insecure-protocol.http.html": [ - "15103438ba6853acb9b111fa6b3bf883d46bdaf7", - "testharness" - ], - "referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-http/module-worker/no-redirect/insecure-protocol.http.html": [ - "37e4203474d4189565b237457ee29fbfcfc12278", - "testharness" - ], "referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-http/script-tag/keep-origin-redirect/insecure-protocol.http.html": [ "39410f46c6538378abba4e442e7b8cf92c5daf97", "testharness" @@ -431542,7 +431199,7 @@ "support" ], "service-workers/service-worker/clients-get-client-types.https.html": [ - "897e3689ed34f1f2abafffb6e4a6e47408bd1f03", + "63e3e51b3202de927d89833b31035792369aec39", "testharness" ], "service-workers/service-worker/clients-get-cross-origin.https.html": [ @@ -431550,7 +431207,7 @@ "testharness" ], "service-workers/service-worker/clients-get.https.html": [ - "b05274039082a8b25384a87dceb46a005f95fd89", + "4cfbf595cadeeea5fc8a5089127c5687ec174f53", "testharness" ], "service-workers/service-worker/clients-matchall-client-types.https-expected.txt": [ @@ -432382,7 +432039,7 @@ "support" ], "service-workers/service-worker/resources/clients-get-cross-origin-frame.html": [ - "eaade327bc59d8f2e38c56766c39973f1ec41426", + "e16bb1116dc810d275073e363fa0d7b4ffa46629", "support" ], "service-workers/service-worker/resources/clients-get-frame.html": [ @@ -432394,11 +432051,11 @@ "support" ], "service-workers/service-worker/resources/clients-get-resultingClientId-worker.js": [ - "153a8e3f5b94059e643daa30b1eb4a821ef886f3", + "5a46ff9cf44010c5f9375bbb7b284932bd21cca7", "support" ], "service-workers/service-worker/resources/clients-get-worker.js": [ - "87368ae7617575da4281aff678c27c2d37118966", + "8effa56c98c9f921201553121308591e7431a201", "support" ], "service-workers/service-worker/resources/clients-matchall-client-types-dedicated-worker.js": [ @@ -436185,6 +435842,10 @@ "ee86b537ae987483687cc8ba6181db82f99ab162", "support" ], + "svg/embedded/image-embedding-svg-with-viewport-units-inline-style.svg": [ + "7880fcf501c032965814e383a93d89a31edda3c5", + "reftest" + ], "svg/embedded/image-embedding-svg-with-viewport-units.svg": [ "6feb54b392f452071f8f4e2d470befee76c03ee6", "reftest" @@ -436773,6 +436434,14 @@ "1894bf8cc3b1c51f7bebd334ca422e9c75d5c3dd", "reftest" ], + "svg/rendering/order/clip-path-filter-order-ref.svg": [ + "ea42d9eb02a5f23fadc062c41cfa513979764aef", + "support" + ], + "svg/rendering/order/clip-path-filter-order.svg": [ + "22cda52d68145da9482abea0da2bedbf3691e82d", + "reftest" + ], "svg/rendering/order/z-index-ref.svg": [ "ff7f9156682b6436ea8d0e4ab805b7c0f0d0fd5a", "support" @@ -441898,7 +441567,7 @@ "testharness" ], "webrtc/RTCPeerConnection-helper.js": [ - "df277ff6d35585452a3a4c2af8dbde5542971794", + "9baf840df213213ef7ef6ce679bfa4ff94f5fb35", "support" ], "webrtc/RTCPeerConnection-iceConnectionState-expected.txt": [ @@ -441930,7 +441599,7 @@ "support" ], "webrtc/RTCPeerConnection-onnegotiationneeded.html": [ - "7e55ac3fadd046f8805174c3d9b1de92f704ca12", + "ac9d70c43eff1ddd0995dcea741f3b6ea850464b", "testharness" ], "webrtc/RTCPeerConnection-ontrack.https-expected.txt": [ @@ -442009,6 +441678,10 @@ "1145fa6292808655b0b2f77585a8183d2b3a8d27", "support" ], + "webrtc/RTCPeerConnection-setRemoteDescription-nomsid.html": [ + "8a86bb0c8e87ba922f535ed2bc7f2aa15a005f6e", + "testharness" + ], "webrtc/RTCPeerConnection-setRemoteDescription-offer-expected.txt": [ "667000f267a693ad81504ac06f1167030f35b808", "support" @@ -442738,11 +442411,11 @@ "testharness" ], "websockets/binary/002.html": [ - "f2fa16a61a18041d2294dc857a1ffd52621cf98b", + "313f6d219c0ae22df7bc75d54cc1dc98c0bf6919", "testharness" ], "websockets/binary/004.html": [ - "59b06d700ab519d7b7c6d9b9bc218704e699ff00", + "2c4e46a2d380dc3e2b8ecebfdbc4a2311c95836c", "testharness" ], "websockets/binary/005.html": [ @@ -442834,7 +442507,7 @@ "testharness" ], "websockets/constructor/013.html": [ - "fe777af1966093b06d2636f4ea0df524b601e161", + "a581bc15131302522e22197b053696f86b688f85", "testharness" ], "websockets/constructor/014.html": [ @@ -442878,11 +442551,11 @@ "testharness" ], "websockets/cookies/003.html": [ - "62c9a27c1dfe2def41a37d98878e0ce8fd0dca20", + "219f05f193af60dd4bcb619e2d0dd97c81037d38", "testharness" ], "websockets/cookies/004.html": [ - "558d56c838e5b690483df99b40ee93356f95a1c7", + "b4d05fbec13e5c139f870be5b431571af1f121d4", "testharness" ], "websockets/cookies/005.html": [ @@ -442902,7 +442575,7 @@ "support" ], "websockets/cookies/007.html": [ - "dd47ffc5b798d939b0ef46e57f8a9b221f2803ca", + "b1654f5b3cadf5db13746e55a7ca2d979149f42e", "testharness" ], "websockets/cookies/007_wss-expected.txt": [ @@ -442918,7 +442591,7 @@ "testharness" ], "websockets/extended-payload-length.html": [ - "9e586a98d7657474ebd84248b2b94e6c9f2c94c3", + "a5ea78fa5daba9d35b358062ec98f01942821649", "testharness" ], "websockets/handlers/basic_auth_wsh.py": [ @@ -443018,7 +442691,7 @@ "support" ], "websockets/interfaces/CloseEvent/clean-close.html": [ - "acc7185167823022df805ff1ea7cb9ba0afbb54e", + "ad22107287a07014666c05d64434b0066c4a5de4", "testharness" ], "websockets/interfaces/CloseEvent/constructor.html": [ @@ -443058,7 +442731,7 @@ "testharness" ], "websockets/interfaces/WebSocket/bufferedAmount/bufferedAmount-large.html": [ - "677423736efa96e8c660e544c79330caef2605b8", + "c9f15b082c79b43de3ed8f02389049253a2d9df6", "testharness" ], "websockets/interfaces/WebSocket/bufferedAmount/bufferedAmount-readonly.html": [ @@ -443070,7 +442743,7 @@ "testharness" ], "websockets/interfaces/WebSocket/close/close-basic.html": [ - "ab6c93b6173a088b0b1089e284312221f80d2fa1", + "673f730cfaee082c33bfc4083e474876fa3db7a7", "testharness" ], "websockets/interfaces/WebSocket/close/close-connecting-expected.txt": [ @@ -443078,7 +442751,7 @@ "support" ], "websockets/interfaces/WebSocket/close/close-connecting.html": [ - "009d6b066f38226a79a77f9a55d105bcc9a9b4e5", + "3e9e51b319e5273025dc17c339991d1ba47705cd", "testharness" ], "websockets/interfaces/WebSocket/close/close-connecting_wss-expected.txt": [ @@ -443094,7 +442767,7 @@ "support" ], "websockets/interfaces/WebSocket/close/close-nested.html": [ - "fa30c8384c1b3f01a08ab2cad5626abd71359a4a", + "3ba99af966f407a428b61880125d75ea0343755a", "testharness" ], "websockets/interfaces/WebSocket/close/close-nested_wss-expected.txt": [ @@ -443142,7 +442815,7 @@ "testharness" ], "websockets/interfaces/WebSocket/events/003.html": [ - "a9b76d84f3d536b475bdf40a2eea8d7503e62fd9", + "430ea14f6775be3189f3a44fe7d1cd1b8274d13c", "testharness" ], "websockets/interfaces/WebSocket/events/004.html": [ @@ -443154,7 +442827,7 @@ "testharness" ], "websockets/interfaces/WebSocket/events/007.html": [ - "4305097d125d41240e7d781250ef4318516aa2d6", + "1e4f2361c5a08f2e1220b31716d5739d6222046e", "testharness" ], "websockets/interfaces/WebSocket/events/008.html": [ @@ -443162,7 +442835,7 @@ "testharness" ], "websockets/interfaces/WebSocket/events/009.html": [ - "dc25884ce0e0d1cb793a4fd2e42d82a7b76a15f0", + "58df1d618172b95558880a7f5f43eaa816c16c65", "testharness" ], "websockets/interfaces/WebSocket/events/010.html": [ @@ -443334,7 +443007,7 @@ "testharness" ], "websockets/keeping-connection-open/001.html": [ - "2e5423c609dcba47ae717d3ef944868bdfd88bf1", + "f6d77a65ee8e60f9442eeeb70f9596c614a9b4a9", "testharness" ], "websockets/multi-globals/message-received.html": [ @@ -443350,11 +443023,11 @@ "support" ], "websockets/opening-handshake/001.html": [ - "727415062a052417eb02e35766e51499f0c9228d", + "e0e9b4e2eab47e48ae2f27a71e216c57955ec25a", "testharness" ], "websockets/opening-handshake/002.html": [ - "052e6445da3412a572f0d44d4ac8d13970aced05", + "95139e199eb9dc330784ce86aa8aeb60da266137", "testharness" ], "websockets/opening-handshake/003-sets-origin.worker.js": [ @@ -443410,7 +443083,7 @@ "support" ], "websockets/unload-a-document/002.html": [ - "03764c345e9a12cb4d917b94f34cafd69bab236c", + "94028e703863132a131f8153e3efe762a1fe8905", "testharness" ], "websockets/unload-a-document/002_wss-expected.txt": [ @@ -443426,7 +443099,7 @@ "support" ], "websockets/unload-a-document/004.html": [ - "0ef4fbc9f81673e4a39dbf2a6ad5c53162006d18", + "bb15cd8ef9244a0e9e49d73bb4c8a405ee1a6841", "testharness" ], "websockets/unload-a-document/005-1.html": [ @@ -443434,7 +443107,7 @@ "support" ], "websockets/unload-a-document/005.html": [ - "4bafe8b603ad818337cf8bd5bf846bc74108d82a", + "81a05f48ead2dea99489ea11f8bfb91b83696733", "testharness" ], "websockets/websocket.sub.js": [
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/grid-model/grid-container-sizing-constraints-001.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/grid-model/grid-container-sizing-constraints-001.html new file mode 100644 index 0000000..38759c2c --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-grid/grid-model/grid-container-sizing-constraints-001.html
@@ -0,0 +1,110 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Grid Layout Test: min|max-content sizing constraints on grid containers</title> +<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com"> +<link rel="help" href="https://www.w3.org/TR/css-grid-1/#intrinsic-sizes"> +<link rel="help" href="https://www.w3.org/TR/css-sizing-3/#sizing-values"> +<meta name="assert" content="The test checks the intrinsic size of a grid container when sized under different constraints. In inline axis min|max-content have some effect, however in block axis they behave as auto."> +<style> + .grid { + display: grid; + float: left; + background: lime; + } + + .grid-columns-minmax-50-100 { + grid-template-columns: minmax(50px, 100px); + } + + .grid-columns-minmax-100-200 { + grid-template-columns: minmax(100px, 200px); + } + + .grid-rows-minmax-50-100 { + grid-template-rows: minmax(50px, 100px); + } + + .min-content { + width: min-content; + height: min-content; + } + + .max-content { + width: max-content; + height: max-content; + } +</style> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/check-layout-th.js"></script> + +<body onload="checkLayout('.grid');"> + + <div id="log"></div> + + <div class="grid grid-columns-minmax-50-100 grid-rows-minmax-50-100" + data-expected-width="100" data-expected-height="100"></div> + + <div class="grid min-content grid-columns-minmax-100-200 grid-rows-minmax-50-100" + data-expected-width="100" data-expected-height="100"></div> + + <div class="grid max-content grid-columns-minmax-50-100 grid-rows-minmax-50-100" + data-expected-width="100" data-expected-height="100"></div> + + <div class="min-content"> + <div class="grid grid-columns-minmax-100-200 grid-rows-minmax-50-100" + data-expected-width="100" data-expected-height="100"></div> + </div> + + <div class="max-content"> + <div class="grid grid-columns-minmax-50-100 grid-rows-minmax-50-100" + data-expected-width="100" data-expected-height="100"></div> + </div> + + <div style="writing-mode: vertical-lr;"> + + <div class="grid grid-columns-minmax-50-100 grid-rows-minmax-50-100" + data-expected-width="100" data-expected-height="100"></div> + + <div class="grid min-content grid-columns-minmax-100-200 grid-rows-minmax-50-100" + data-expected-width="100" data-expected-height="100"></div> + + <div class="grid max-content grid-columns-minmax-50-100 grid-rows-minmax-50-100" + data-expected-width="100" data-expected-height="100"></div> + + <div class="min-content"> + <div class="grid grid-columns-minmax-100-200 grid-rows-minmax-50-100" + data-expected-width="100" data-expected-height="100"></div> + </div> + + <div class="max-content"> + <div class="grid grid-columns-minmax-50-100 grid-rows-minmax-50-100" + data-expected-width="100" data-expected-height="100"></div> + </div> + + </div> + + <div style="writing-mode: vertical-rl;"> + + <div class="grid grid-columns-minmax-50-100 grid-rows-minmax-50-100" + data-expected-width="100" data-expected-height="100"></div> + + <div class="grid min-content grid-columns-minmax-100-200 grid-rows-minmax-50-100" + data-expected-width="100" data-expected-height="100"></div> + + <div class="grid max-content grid-columns-minmax-50-100 grid-rows-minmax-50-100" + data-expected-width="100" data-expected-height="100"></div> + + <div class="min-content"> + <div class="grid grid-columns-minmax-100-200 grid-rows-minmax-50-100" + data-expected-width="100" data-expected-height="100"></div> + </div> + + <div class="max-content"> + <div class="grid grid-columns-minmax-50-100 grid-rows-minmax-50-100" + data-expected-width="100" data-expected-height="100"></div> + </div> + + </div> + +</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-masking/clip/clip-fixed-pos-transform-descendant-001-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-masking/clip/clip-fixed-pos-transform-descendant-001-ref.html new file mode 100644 index 0000000..ed78cb7 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-masking/clip/clip-fixed-pos-transform-descendant-001-ref.html
@@ -0,0 +1,11 @@ +<!doctype html> +<title>CSS Test Reference</title> +<style> + html, body { margin: 0 } + div { + width: 100px; + height: 100px; + background: lime; + } +</style> +<div></div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-masking/clip/clip-fixed-pos-transform-descendant-001.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-masking/clip/clip-fixed-pos-transform-descendant-001.html new file mode 100644 index 0000000..395b0bc9 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-masking/clip/clip-fixed-pos-transform-descendant-001.html
@@ -0,0 +1,38 @@ +<!doctype html> +<title>CSS Masking: Transformed descendants of a fixed pos element under a clipped element get properly clipped</title> +<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io"> +<link rel="author" title="Mozilla" href="https://mozilla.org"> +<link rel="match" href="clip-fixed-pos-transform-descendant-001-ref.html"> +<link rel="help" href="https://drafts.fxtf.org/css-masking/#clip-property"> +<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1495791"> +<style> +html, body { margin: 0; } + +#clip { + height: 100px; + width: 100px; + background: lime; + clip: rect(0, auto, auto, 0); + position: absolute; +} + +#fixed { + position: fixed; + top: 0; + left: 0; + width: 100px; + height: 100px; +} + +#clipped { + height: 100px; + width: 100px; + background: red; + transform: translateY(100px); +} +</style> +<div id="clip"> + <div id="fixed"> + <div id="clipped"></div> + </div> +</div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/response/response-init-001-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/fetch/api/response/response-init-001-expected.txt new file mode 100644 index 0000000..07ed8a6 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/fetch/api/response/response-init-001-expected.txt
@@ -0,0 +1,12 @@ +This is a testharness.js-based test. +PASS Check default value for type attribute +PASS Check default value for url attribute +PASS Check default value for ok attribute +PASS Check default value for status attribute +FAIL Check default value for statusText attribute assert_equals: Expect default response.statusText is expected "" but got "OK" +PASS Check default value for body attribute +PASS Check status init values and associated getter +PASS Check statusText init values and associated getter +PASS Test that Response.headers has the [SameObject] extended attribute +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/response/response-init-001.html b/third_party/WebKit/LayoutTests/external/wpt/fetch/api/response/response-init-001.html index cd89448..7af23d3 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/response/response-init-001.html +++ b/third_party/WebKit/LayoutTests/external/wpt/fetch/api/response/response-init-001.html
@@ -15,15 +15,15 @@ "url" : "", "ok" : true, "status" : 200, - "statusText" : "OK", + "statusText" : "", "body" : null }; var statusCodes = { "givenValues" : [200, 300, 400, 500, 599], - "expectedValues" : [200, 300, 400, 500, 599] + "expectedValues" : [200, 300, 400, 500, 599] }; - var statusTexts = { "givenValues" : ["OK", "with space", String.fromCharCode(0x80)], - "expectedValues" : ["OK", "with space", String.fromCharCode(0x80)] + var statusTexts = { "givenValues" : ["", "OK", "with space", String.fromCharCode(0x80)], + "expectedValues" : ["", "OK", "with space", String.fromCharCode(0x80)] }; var initValuesDict = { "status" : statusCodes, "statusText" : statusTexts @@ -42,7 +42,7 @@ }, "Check default value for " + attributeName + " attribute"); } - for (var attributeName in initValuesDict) + for (var attributeName in initValuesDict) { test(function() { var valuesToTest = initValuesDict[attributeName]; for (var valueIdx in valuesToTest["givenValues"]) { @@ -58,19 +58,20 @@ "Expect response.ok is " + isOkStatus(response.status)); } }, "Check " + attributeName + " init values and associated getter"); + } - test(function() { - const response1 = new Response(""); - assert_equals(response1.headers, response1.headers); + test(function() { + const response1 = new Response(""); + assert_equals(response1.headers, response1.headers); - const response2 = new Response("", {"headers": {"X-Foo": "bar"}}); - assert_equals(response2.headers, response2.headers); - const headers = response2.headers; - response2.headers.set("X-Foo", "quux"); - assert_equals(headers, response2.headers); - headers.set("X-Other-Header", "baz"); - assert_equals(headers, response2.headers); - }, "Test that Response.headers has the [SameObject] extended attribute"); + const response2 = new Response("", {"headers": {"X-Foo": "bar"}}); + assert_equals(response2.headers, response2.headers); + const headers = response2.headers; + response2.headers.set("X-Foo", "quux"); + assert_equals(headers, response2.headers); + headers.set("X-Other-Header", "baz"); + assert_equals(headers, response2.headers); + }, "Test that Response.headers has the [SameObject] extended attribute"); </script> </body> </html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/fetch/sec-metadata/resources/record-header.py b/third_party/WebKit/LayoutTests/external/wpt/fetch/sec-metadata/resources/record-header.py index b81e93e..adf9a53f 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/fetch/sec-metadata/resources/record-header.py +++ b/third_party/WebKit/LayoutTests/external/wpt/fetch/sec-metadata/resources/record-header.py
@@ -63,7 +63,7 @@ ## Return a valid font content and Content-Type ## if key.startswith("font"): response.headers.set("Content-Type", "application/x-font-ttf") - file = open("fonts/Ahem.ttf", "r") + file = open(os.path.join(request.doc_root, "fonts", "Ahem.ttf"), "r") font = file.read() file.close() return font @@ -71,7 +71,7 @@ ## Return a valid audio content and Content-Type ## if key.startswith("audio"): response.headers.set("Content-Type", "audio/mpeg") - file = open("media/sound_5.mp3", "r") + file = open(os.path.join(request.doc_root, "media", "sound_5.mp3"), "r") audio = file.read() file.close() return audio @@ -79,7 +79,7 @@ ## Return a valid video content and Content-Type ## if key.startswith("video"): response.headers.set("Content-Type", "video/mp4") - file = open("media/A4.mp4", "r") + file = open(os.path.join(request.doc_root, "media", "A4.mp4"), "r") video = file.read() file.close() return video @@ -92,7 +92,7 @@ ## Return a valid image content and Content-Type for redirect requests ## if key.startswith("redirect"): response.headers.set("Content-Type", "image/jpeg") - file = open("media/1x1-green.png", "r") + file = open(os.path.join(request.doc_root, "media", "1x1-green.png"), "r") image = file.read() file.close() return image
diff --git a/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/MediaDevices-enumerateDevices.https.html b/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/MediaDevices-enumerateDevices.https.html index c66251a..76ca435 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/MediaDevices-enumerateDevices.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/MediaDevices-enumerateDevices.https.html
@@ -16,65 +16,30 @@ <script> "use strict"; //NOTE ALEX: for completion, a test for ondevicechange event is missing. -promise_test(function() { +promise_test(async () => { assert_true(undefined !== navigator.mediaDevices.enumerateDevices, "navigator.mediaDevices.enumerateDevices exists"); - return navigator.mediaDevices.enumerateDevices().then(function(list) { - for (let mediainfo of list) { - assert_true(undefined !== mediainfo.deviceId, "mediaInfo's deviceId should exist."); - assert_true(undefined !== mediainfo.kind, "mediaInfo's kind should exist."); - assert_true(undefined !== mediainfo.label, "mediaInfo's label should exist."); - assert_true(undefined !== mediainfo.groupId, "mediaInfo's groupId should exist."); - // TODO the values of some of those fields should be empty string by default if no permission has been requested. - if ( mediainfo.kind == "audioinput" || mediainfo.kind == "videoinput") { - assert_true(mediainfo instanceof InputDeviceInfo); - var capabilities = mediainfo.getCapabilities(); - assert_equals(typeof capabilities, "object", "capabilities must be an object."); - assert_equals(typeof capabilities.deviceId, "string", "deviceId must be a string."); - assert_equals(typeof capabilities.groupId, "string", "groupId must be a string."); - if (mediainfo.kind == "audioinput") { - assert_equals(typeof capabilities.echoCancellation, "object", "echoCancellation must be an object."); - assert_equals(typeof capabilities.autoGainControl, "object", "autoGainControl must be an object."); - assert_equals(typeof capabilities.noiseSuppression, "object", "noiseSuppression must be an object."); - } - if (mediainfo.kind == "videoinput") { - assert_equals(typeof capabilities.facingMode, "object", "facingMode must be an object."); - verifyVideoRangeProperties(capabilities); - } - } else if ( mediainfo.kind == "audiooutput" ) { - assert_true(mediainfo instanceof MediaDeviceInfo); - } else { - assert_unreached("mediainfo.kind should be one of 'audioinput', 'videoinput', or 'audiooutput'.") - } - } - }); -}, "mediaDevices.enumerateDevices() is present and working on navigator"); + const device_list = await navigator.mediaDevices.enumerateDevices(); + for (const mediainfo of device_list) { + assert_true(undefined !== mediainfo.deviceId, "mediaInfo's deviceId should exist."); + assert_true(undefined !== mediainfo.kind, "mediaInfo's kind should exist."); + assert_in_array(mediainfo.kind, ["videoinput", "audioinput", "audiooutput"]); + assert_true(undefined !== mediainfo.label, "mediaInfo's label should exist."); + assert_true(undefined !== mediainfo.groupId, "mediaInfo's groupId should exist."); + } +}, "mediaDevices.enumerateDevices() is present and working"); -function verifyVideoRangeProperties(capabilities) { - if (capabilities.hasOwnProperty('width')) { - assert_equals(Object.keys(capabilities.width).length, 2); - assert_true(capabilities.width.hasOwnProperty('min')); - assert_true(capabilities.width.hasOwnProperty('max')); - assert_less_than_equal(capabilities.width.min, capabilities.width.max); +promise_test(async () => { + const device_list = await navigator.mediaDevices.enumerateDevices(); + for (const mediainfo of device_list) { + if (mediainfo.kind == "audioinput" || mediainfo.kind == "videoinput") { + assert_true(mediainfo instanceof InputDeviceInfo); + } else if ( mediainfo.kind == "audiooutput" ) { + assert_true(mediainfo instanceof MediaDeviceInfo); + } else { + assert_unreached("mediainfo.kind should be one of 'audioinput', 'videoinput', or 'audiooutput'.") + } } - if (capabilities.hasOwnProperty('height')) { - assert_equals(Object.keys(capabilities.height).length, 2); - assert_true(capabilities.height.hasOwnProperty('min')); - assert_true(capabilities.height.hasOwnProperty('max')); - assert_less_than_equal(capabilities.height.min, capabilities.height.max); - } - if (capabilities.hasOwnProperty('aspectRatio')) { - assert_equals(Object.keys(capabilities.aspectRatio).length, 2); - assert_true(capabilities.aspectRatio.hasOwnProperty('min')); - assert_true(capabilities.aspectRatio.hasOwnProperty('max')); - assert_less_than_equal(capabilities.aspectRatio.min, capabilities.aspectRatio.max); - } - if (capabilities.hasOwnProperty('frameRate')) { - assert_equals(Object.keys(capabilities.frameRate).length, 2); - assert_true(capabilities.frameRate.hasOwnProperty('min')); - assert_true(capabilities.frameRate.hasOwnProperty('max')); - assert_less_than_equal(capabilities.frameRate.min, capabilities.frameRate.max); - } -} +}, "InputDeviceInfo is supported"); </script> </body> </html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/MediaDevices-getUserMedia.https.html b/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/MediaDevices-getUserMedia.https.html index afa3abe..f1e2d560 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/MediaDevices-getUserMedia.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/MediaDevices-getUserMedia.https.html
@@ -92,6 +92,34 @@ } })); }, 'groupId is correctly supported by getUserMedia() for audio devices'); + +promise_test(async t => { + const stream = await navigator.mediaDevices.getUserMedia( + { video: {resizeMode: {exact: 'none'}}}); + const [track] = stream.getVideoTracks(); + t.add_cleanup(() => track.stop()); + assert_equals(track.getSettings().resizeMode, 'none'); +}, 'getUserMedia() supports setting none as resizeMode.'); + +promise_test(async t => { + const stream = await navigator.mediaDevices.getUserMedia( + { video: {resizeMode: {exact: 'crop-and-scale'}}}); + const [track] = stream.getVideoTracks(); + t.add_cleanup(() => track.stop()); + assert_equals(track.getSettings().resizeMode, 'crop-and-scale'); +}, 'getUserMedia() supports setting crop-and-scale as resizeMode.'); + +promise_test(async t => { + try { + let stream = await navigator.mediaDevices.getUserMedia( + { video: {resizeMode: {exact: 'INVALID'}}}); + t.add_cleanup(() => stream.getVideoTracks()[0].stop()); + t.unreached_func('getUserMedia() should fail with invalid resizeMode')(); + } catch (e) { + assert_equals(e.name, 'OverconstrainedError'); + assert_equals(e.constraint, 'resizeMode'); + } +}, 'getUserMedia() fails with exact invalid resizeMode.'); </script> </body> </html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/MediaStreamTrack-applyConstraints.https.html b/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/MediaStreamTrack-applyConstraints.https.html index 00566950..025f827 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/MediaStreamTrack-applyConstraints.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/MediaStreamTrack-applyConstraints.https.html
@@ -54,4 +54,26 @@ }); })); }, 'applyConstraints rejects attempt to switch device using groupId'); + + promise_test(async t => { + const stream = await navigator.mediaDevices.getUserMedia({ video: true }); + const [track] = stream.getVideoTracks(); + t.add_cleanup(() => track.stop()); + try { + await track.applyConstraints({ resizeMode: { exact: "INVALID" } }); + t.unreached_func('applyConstraints() must fail with invalid resizeMode')(); + } catch (e) { + assert_equals(e.name, 'OverconstrainedError'); + assert_equals(e.constraint, 'resizeMode'); + } + }, 'applyConstraints rejects invalid resizeMode'); + + promise_test(async t => { + const stream = await navigator.mediaDevices.getUserMedia({ video: true }); + const [track] = stream.getVideoTracks(); + t.add_cleanup(() => track.stop()); + const resizeMode = track.getSettings().resizeMode; + await track.applyConstraints({ resizeMode: "INVALID" }); + assert_equals(track.getSettings().resizeMode, resizeMode); + }, 'applyConstraints accepts invalid ideal resizeMode, does not change setting'); </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/MediaStreamTrack-getCapabilities.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/MediaStreamTrack-getCapabilities.https-expected.txt new file mode 100644 index 0000000..2a1a683 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/MediaStreamTrack-getCapabilities.https-expected.txt
@@ -0,0 +1,115 @@ +This is a testharness.js-based test. +PASS Setup audio MediaStreamTrack getCapabilities() test for volume +PASS Setup audio MediaStreamTrack getCapabilities() test for sampleRate +PASS Setup audio MediaStreamTrack getCapabilities() test for sampleSize +PASS Setup audio MediaStreamTrack getCapabilities() test for echoCancellation +PASS Setup audio MediaStreamTrack getCapabilities() test for autoGainControl +PASS Setup audio MediaStreamTrack getCapabilities() test for noiseSuppression +PASS Setup audio MediaStreamTrack getCapabilities() test for latency +PASS Setup audio MediaStreamTrack getCapabilities() test for channelCount +PASS Setup audio MediaStreamTrack getCapabilities() test for deviceId +PASS Setup audio MediaStreamTrack getCapabilities() test for groupId +PASS Setup video MediaStreamTrack getCapabilities() test for width +PASS Setup video MediaStreamTrack getCapabilities() test for height +PASS Setup video MediaStreamTrack getCapabilities() test for aspectRatio +PASS Setup video MediaStreamTrack getCapabilities() test for frameRate +PASS Setup video MediaStreamTrack getCapabilities() test for facingMode +PASS Setup video MediaStreamTrack getCapabilities() test for resizeMode +PASS Setup video MediaStreamTrack getCapabilities() test for deviceId +PASS Setup video MediaStreamTrack getCapabilities() test for groupId +PASS Setup audio InputDeviceInfo getCapabilities() test for volume +PASS Setup audio InputDeviceInfo getCapabilities() test for sampleRate +PASS Setup audio InputDeviceInfo getCapabilities() test for sampleSize +PASS Setup audio InputDeviceInfo getCapabilities() test for echoCancellation +PASS Setup audio InputDeviceInfo getCapabilities() test for autoGainControl +PASS Setup audio InputDeviceInfo getCapabilities() test for noiseSuppression +PASS Setup audio InputDeviceInfo getCapabilities() test for latency +PASS Setup audio InputDeviceInfo getCapabilities() test for channelCount +PASS Setup audio InputDeviceInfo getCapabilities() test for deviceId +PASS Setup audio InputDeviceInfo getCapabilities() test for groupId +PASS Setup video InputDeviceInfo getCapabilities() test for width +PASS Setup video InputDeviceInfo getCapabilities() test for height +PASS Setup video InputDeviceInfo getCapabilities() test for aspectRatio +PASS Setup video InputDeviceInfo getCapabilities() test for frameRate +PASS Setup video InputDeviceInfo getCapabilities() test for facingMode +PASS Setup video InputDeviceInfo getCapabilities() test for resizeMode +PASS Setup video InputDeviceInfo getCapabilities() test for deviceId +PASS Setup video InputDeviceInfo getCapabilities() test for groupId +FAIL Audio track getCapabilities() volume property present. assert_true: expected true got false +FAIL Audio track getCapabilities() volume properly supported. assert_equals: expected "object" but got "undefined" +FAIL Audio track getCapabilities() sampleRate property present. assert_true: expected true got false +FAIL Audio track getCapabilities() sampleRate properly supported. assert_equals: expected "object" but got "undefined" +FAIL Audio track getCapabilities() sampleSize property present. assert_true: expected true got false +FAIL Audio track getCapabilities() sampleSize properly supported. assert_equals: expected "object" but got "undefined" +PASS Audio track getCapabilities() echoCancellation property present. +PASS Audio track getCapabilities() echoCancellation properly supported. +PASS Audio track getCapabilities() autoGainControl property present. +PASS Audio track getCapabilities() autoGainControl properly supported. +PASS Audio track getCapabilities() noiseSuppression property present. +PASS Audio track getCapabilities() noiseSuppression properly supported. +FAIL Audio track getCapabilities() latency property present. assert_true: expected true got false +FAIL Audio track getCapabilities() latency properly supported. assert_equals: expected "object" but got "undefined" +FAIL Audio track getCapabilities() channelCount property present. assert_true: expected true got false +FAIL Audio track getCapabilities() channelCount properly supported. assert_equals: expected "object" but got "undefined" +PASS Audio track getCapabilities() deviceId property present. +PASS Audio track getCapabilities() deviceId properly supported. +PASS Audio track getCapabilities() groupId property present. +PASS Audio track getCapabilities() groupId properly supported. +PASS Video track getCapabilities() width property present. +PASS Video track getCapabilities() width properly supported. +PASS Video track getCapabilities() height property present. +PASS Video track getCapabilities() height properly supported. +PASS Video track getCapabilities() aspectRatio property present. +PASS Video track getCapabilities() aspectRatio properly supported. +PASS Video track getCapabilities() frameRate property present. +PASS Video track getCapabilities() frameRate properly supported. +PASS Video track getCapabilities() facingMode property present. +PASS Video track getCapabilities() facingMode properly supported. +PASS Video track getCapabilities() resizeMode property present. +PASS Video track getCapabilities() resizeMode properly supported. +PASS Video track getCapabilities() resizeMode properly supported. Value: none +PASS Video track getCapabilities() resizeMode properly supported. Value: crop-and-scale +PASS Video track getCapabilities() deviceId property present. +PASS Video track getCapabilities() deviceId properly supported. +PASS Video track getCapabilities() groupId property present. +PASS Video track getCapabilities() groupId properly supported. +FAIL Audio device getCapabilities() volume property present. assert_true: expected true got false +FAIL Audio device getCapabilities() volume properly supported. assert_equals: expected "object" but got "undefined" +FAIL Audio device getCapabilities() sampleRate property present. assert_true: expected true got false +FAIL Audio device getCapabilities() sampleRate properly supported. assert_equals: expected "object" but got "undefined" +FAIL Audio device getCapabilities() sampleSize property present. assert_true: expected true got false +FAIL Audio device getCapabilities() sampleSize properly supported. assert_equals: expected "object" but got "undefined" +PASS Audio device getCapabilities() echoCancellation property present. +PASS Audio device getCapabilities() echoCancellation properly supported. +PASS Audio device getCapabilities() autoGainControl property present. +PASS Audio device getCapabilities() autoGainControl properly supported. +PASS Audio device getCapabilities() noiseSuppression property present. +PASS Audio device getCapabilities() noiseSuppression properly supported. +FAIL Audio device getCapabilities() latency property present. assert_true: expected true got false +FAIL Audio device getCapabilities() latency properly supported. assert_equals: expected "object" but got "undefined" +FAIL Audio device getCapabilities() channelCount property present. assert_true: expected true got false +FAIL Audio device getCapabilities() channelCount properly supported. assert_equals: expected "object" but got "undefined" +PASS Audio device getCapabilities() deviceId property present. +PASS Audio device getCapabilities() deviceId properly supported. +PASS Audio device getCapabilities() groupId property present. +PASS Audio device getCapabilities() groupId properly supported. +PASS Video device getCapabilities() width property present. +PASS Video device getCapabilities() width properly supported. +PASS Video device getCapabilities() height property present. +PASS Video device getCapabilities() height properly supported. +PASS Video device getCapabilities() aspectRatio property present. +PASS Video device getCapabilities() aspectRatio properly supported. +PASS Video device getCapabilities() frameRate property present. +PASS Video device getCapabilities() frameRate properly supported. +PASS Video device getCapabilities() facingMode property present. +PASS Video device getCapabilities() facingMode properly supported. +PASS Video device getCapabilities() resizeMode property present. +PASS Video device getCapabilities() resizeMode properly supported. +PASS Video device getCapabilities() resizeMode properly supported. Value: none +PASS Video device getCapabilities() resizeMode properly supported. Value: crop-and-scale +PASS Video device getCapabilities() deviceId property present. +PASS Video device getCapabilities() deviceId properly supported. +PASS Video device getCapabilities() groupId property present. +PASS Video device getCapabilities() groupId properly supported. +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/MediaStreamTrack-getCapabilities.https.html b/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/MediaStreamTrack-getCapabilities.https.html index 6eea9994..aeb79b5 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/MediaStreamTrack-getCapabilities.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/mediacapture-streams/MediaStreamTrack-getCapabilities.https.html
@@ -1,22 +1,150 @@ <!doctype html> -<title>MediaStreamTrack GetCapabilities</title> -<p class="instructions">This test checks for the presence of audio and video properties in -<code>MediaStreamTrack.getCapabilities()</code> method.</p> +<title>MediaStreamTrack and InputDeviceInfo GetCapabilities</title> <script src=/resources/testharness.js></script> <script src=/resources/testharnessreport.js></script> <script> - promise_test(() => { - return navigator.mediaDevices.getUserMedia({audio: true, video: true}) - .then(stream => { - var audioCapabilities = stream.getAudioTracks()[0].getCapabilities(); - var videoCapabilities = stream.getVideoTracks()[0].getCapabilities(); - assert_true(undefined !== audioCapabilities.deviceId, "MediaTrackCapabilities's deviceId should exist for an audio track."); - assert_true(undefined !== audioCapabilities.groupId, "MediaTrackCapabilities's groupId should exist for an audio track."); - assert_true(undefined !== audioCapabilities.echoCancellation, "MediaTrackCapabilities's echoCancellation should exist for an audio track."); - assert_true(undefined !== audioCapabilities.autoGainControl, "MediaTrackCapabilities's autoGainControl should exist for an audio track."); - assert_true(undefined !== audioCapabilities.noiseSuppression, "MediaTrackCapabilities's noiseSuppression should exist for an audio track."); - assert_true(undefined !== videoCapabilities.deviceId, "MediaTrackCapabilities's deviceId should exist for a video track."); - assert_true(undefined !== videoCapabilities.groupId, "MediaTrackCapabilities's groupId should exist for a video track."); - }); + +const audioProperties = [ + {name: "volume", type: "number"}, + {name: "sampleRate", type: "number"}, + {name: "sampleSize", type: "number"}, + {name: "echoCancellation", type: "boolean"}, + {name: "autoGainControl", type: "boolean"}, + {name: "noiseSuppression", type: "boolean"}, + {name: "latency", type: "number"}, + {name: "channelCount", type: "number"}, + {name: "deviceId", type: "string"}, + {name: "groupId", type: "string"} +]; + +const videoProperties = [ + {name: "width", type: "number"}, + {name: "height", type: "number"}, + {name: "aspectRatio", type: "number"}, + {name: "frameRate", type: "number"}, + {name: "facingMode", type: "enum-any", validValues: ["user", "environment", "left", "right"]}, + {name: "resizeMode", type: "enum-all", validValues: ["none", "crop-and-scale"]}, + {name: "deviceId", type: "string"}, + {name: "groupId", type: "string"}, +]; + +function verifyBooleanCapability(capability) { + assert_less_than_equal(capability.length, 2); + capability.forEach(c => assert_equals(typeof c, "boolean")); +} + +function verifyNumberCapability(capability) { + assert_equals(typeof capability, "object"); + assert_equals(Object.keys(capability).length, 2); + assert_true(capability.hasOwnProperty('min')); + assert_true(capability.hasOwnProperty('max')); + assert_less_than_equal(capability.min, capability.max); +} + +// Verify that any value provided by an enum capability is in the set of valid +// values. +function verifyEnumAnyCapability(capability, enumMembers) { + capability.forEach(c => { + assert_equals(typeof c, "string"); + assert_in_array(c, enumMembers); }); +} + +// Verify that all required values are supported by a capability. +function verifyEnumAllCapability(capability, enumMembers, testNamePrefix) { + enumMembers.forEach(member => { + test(() => { + assert_in_array(member, capability); + }, testNamePrefix + " Value: " + member); + }); +} + +function testCapabilities(capabilities, property, testNamePrefix) { + let testName = testNamePrefix + " " + property.name; + test(() => { + assert_true(capabilities.hasOwnProperty(property.name)); + }, testName + " property present."); + + const capability = capabilities[property.name]; + testName += " properly supported."; + if (property.type == "string") { + test(() => { + assert_equals(typeof capability, "string"); + }, testName); + } + + if (property.type == "boolean") { + test(() => { + verifyBooleanCapability(capability); + }, testName); + } + + if (property.type == "number") { + test(() => { + verifyNumberCapability(capability); + }, testName); + } + + if (property.type.startsWith("enum")) { + test(() => { + verifyEnumAnyCapability(capability, property.validValues); + }, testName); + + if (property.type == "enum-all") { + verifyEnumAllCapability(capability, property.validValues, testName); + } + } +} + +{ + audioProperties.forEach(property => { + promise_test(async t => { + const stream = await navigator.mediaDevices.getUserMedia({audio: true}); + t.add_cleanup(() => stream.getAudioTracks()[0].stop()); + const audioCapabilities = stream.getAudioTracks()[0].getCapabilities(); + testCapabilities(audioCapabilities, property, "Audio track getCapabilities()"); + }, "Setup audio MediaStreamTrack getCapabilities() test for " + property.name); + }); + + videoProperties.forEach(property => { + promise_test(async t => { + const stream = await navigator.mediaDevices.getUserMedia({video: true}); + t.add_cleanup(() => stream.getVideoTracks()[0].stop()); + const audioCapabilities = stream.getVideoTracks()[0].getCapabilities(); + testCapabilities(audioCapabilities, property, "Video track getCapabilities()"); + }, "Setup video MediaStreamTrack getCapabilities() test for " + property.name); + }); +} + +{ + audioProperties.forEach(property => { + promise_test(async t => { + const devices = await navigator.mediaDevices.enumerateDevices(); + for (const device of devices) { + // Test only one device. + if (device.kind == "audioinput") { + assert_inherits(device, "getCapabilities"); + const capabilities = device.getCapabilities(); + testCapabilities(capabilities, property, "Audio device getCapabilities()"); + break; + } + } + }, "Setup audio InputDeviceInfo getCapabilities() test for " + property.name); + }); + + videoProperties.forEach(property => { + promise_test(async t => { + const devices = await navigator.mediaDevices.enumerateDevices(); + for (const device of devices) { + // Test only one device. + if (device.kind == "videoinput") { + assert_inherits(device, "getCapabilities"); + const capabilities = device.getCapabilities(); + testCapabilities(capabilities, property, "Video device getCapabilities()"); + break; + } + } + }, "Setup video InputDeviceInfo getCapabilities() test for " + property.name); + }); +} </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/payment-request/payment-response/retry-method-manual.https.html b/third_party/WebKit/LayoutTests/external/wpt/payment-request/payment-response/retry-method-manual.https.html index 69bda5e..25d82a0 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/payment-request/payment-response/retry-method-manual.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/payment-request/payment-response/retry-method-manual.https.html
@@ -56,7 +56,7 @@ const { response } = await getPaymentRequestResponse(); const retryPromise = response.retry(); const completePromise1 = response.complete("success"); - const completePromise2 = response.complete("failure"); + const completePromise2 = response.complete("fail"); assert_not_equals( completePromise1, completePromise2,
diff --git a/third_party/WebKit/LayoutTests/external/wpt/picture-in-picture/mediastream.html b/third_party/WebKit/LayoutTests/external/wpt/picture-in-picture/mediastream.html index 7a2cc95..e187de3d 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/picture-in-picture/mediastream.html +++ b/third_party/WebKit/LayoutTests/external/wpt/picture-in-picture/mediastream.html
@@ -11,6 +11,7 @@ const canvas = document.createElement('canvas'); const video = document.createElement('video'); const mediastreamVideoLoadedPromise = new Promise((resolve, reject) => { + canvas.getContext('2d').fillRect(0, 0, canvas.width, canvas.height); video.autoplay = true; video.srcObject = canvas.captureStream(60 /* fps */); video.onloadedmetadata = () => {
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-helper.js b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-helper.js index df277ff6..9baf840 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-helper.js +++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-helper.js
@@ -251,6 +251,8 @@ // Wait for RTP and RTCP stats to arrive async function waitForRtpAndRtcpStats(pc) { + // If remote stats are never reported, return after 5 seconds. + const startTime = performance.now(); while (true) { const report = await pc.getStats(); const stats = [...report.values()].filter(({type}) => type.endsWith("bound-rtp")); @@ -259,6 +261,9 @@ if (stats.length && stats.every(({localId, remoteId}) => localId || remoteId)) { break; } + if (performance.now() > startTime + 5000) { + break; + } } }
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-onnegotiationneeded.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-onnegotiationneeded.html index 7e55ac3..ac9d70c 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-onnegotiationneeded.html +++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-onnegotiationneeded.html
@@ -164,10 +164,13 @@ */ test_never_resolve(t => { const pc = new RTCPeerConnection(); - const negotiated = awaitNegotiation(pc); + let negotiated; return generateAudioReceiveOnlyOffer(pc) - .then(offer => pc.setLocalDescription(offer)) + .then(offer => { + pc.setLocalDescription(offer); + negotiated = awaitNegotiation(pc); + }) .then(() => negotiated) .then(({nextPromise}) => { assert_equals(pc.signalingState, 'have-local-offer');
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-nomsid.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-nomsid.html new file mode 100644 index 0000000..8a86bb0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-nomsid.html
@@ -0,0 +1,40 @@ +<!doctype html> +<meta charset=utf-8> +<title>RTCPeerConnection.prototype.setRemoteDescription - legacy streams without a=msid lines</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +'use strict'; + +const FINGERPRINT_SHA256 = '00:00:00:00:00:00:00:00:00:00:00:00:00' + + ':00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00'; +const ICEUFRAG = 'someufrag'; +const ICEPWD = 'somelongpwdwithenoughrandomness'; +const SDP_BOILERPLATE = 'v=0\r\n' + + 'o=- 166855176514521964 2 IN IP4 127.0.0.1\r\n' + + 's=-\r\n' + + 't=0 0\r\n'; +const MINIMAL_AUDIO_MLINE = + 'm=audio 9 UDP/TLS/RTP/SAVPF 111\r\n' + + 'c=IN IP4 0.0.0.0\r\n' + + 'a=rtcp:9 IN IP4 0.0.0.0\r\n' + + 'a=ice-ufrag:' + ICEUFRAG + '\r\n' + + 'a=ice-pwd:' + ICEPWD + '\r\n' + + 'a=fingerprint:sha-256 ' + FINGERPRINT_SHA256 + '\r\n' + + 'a=setup:actpass\r\n' + + 'a=mid:0\r\n' + + 'a=sendrecv\r\n' + + 'a=rtcp-mux\r\n' + + 'a=rtcp-rsize\r\n' + + 'a=rtpmap:111 opus/48000/2\r\n'; + + promise_test(async t => { + const pc = new RTCPeerConnection(); + t.add_cleanup(() => pc.close()); + + const haveOntrack = new Promise(r => pc.ontrack = r); + await pc.setRemoteDescription({type: 'offer', sdp: SDP_BOILERPLATE + MINIMAL_AUDIO_MLINE}); + assert_equals((await haveOntrack).streams.length, 1); + }, 'setRemoteDescription with an SDP without a=msid lines triggers ontrack with a default stream.'); + +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/websockets/binary/002.html b/third_party/WebKit/LayoutTests/external/wpt/websockets/binary/002.html index f2fa16a..313f6d21 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/websockets/binary/002.html +++ b/third_party/WebKit/LayoutTests/external/wpt/websockets/binary/002.html
@@ -23,5 +23,5 @@ t.done(); }); -}, null, {timeout:20000}); +}); </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/websockets/binary/004.html b/third_party/WebKit/LayoutTests/external/wpt/websockets/binary/004.html index 59b06d7..2c4e46a 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/websockets/binary/004.html +++ b/third_party/WebKit/LayoutTests/external/wpt/websockets/binary/004.html
@@ -22,5 +22,5 @@ t.done(); }) -}, null, {timeout:20000}); +}); </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/websockets/constructor/013.html b/third_party/WebKit/LayoutTests/external/wpt/websockets/constructor/013.html index fe777af..a581bc1 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/websockets/constructor/013.html +++ b/third_party/WebKit/LayoutTests/external/wpt/websockets/constructor/013.html
@@ -36,6 +36,6 @@ }, ws[i]); ws[i].onerror = t.step_func(function() {assert_unreached()}); } -}, null, {timeout:25000}); +}); </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/websockets/cookies/003.html b/third_party/WebKit/LayoutTests/external/wpt/websockets/cookies/003.html index 62c9a27c..219f05f1 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/websockets/cookies/003.html +++ b/third_party/WebKit/LayoutTests/external/wpt/websockets/cookies/003.html
@@ -29,5 +29,5 @@ ws.onerror = ws.onclose = t.step_func(function(e) {assert_unreached(e.type)}); }); document.body.appendChild(iframe); -}, null, {timeout:9900}); +}); </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/websockets/cookies/004.html b/third_party/WebKit/LayoutTests/external/wpt/websockets/cookies/004.html index 558d56c..b4d05fbe 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/websockets/cookies/004.html +++ b/third_party/WebKit/LayoutTests/external/wpt/websockets/cookies/004.html
@@ -27,5 +27,5 @@ }); ws.onerror = ws.onclose = t.step_func(function(e) {assert_unreached(e.type)}); document.body.appendChild(iframe); -}, null, {timeout:9900}) +}); </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/websockets/cookies/007.html b/third_party/WebKit/LayoutTests/external/wpt/websockets/cookies/007.html index dd47ffc5..b1654f5 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/websockets/cookies/007.html +++ b/third_party/WebKit/LayoutTests/external/wpt/websockets/cookies/007.html
@@ -31,5 +31,5 @@ if (new RegExp('ws_test_'+cookie_id+'=test').test(document.cookie)) { assert_unreached('cookie was set during script execution'); } -}, null, {timeout:12000}); +}); </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/websockets/extended-payload-length.html b/third_party/WebKit/LayoutTests/external/wpt/websockets/extended-payload-length.html index 9e586a98..a5ea78f 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/websockets/extended-payload-length.html +++ b/third_party/WebKit/LayoutTests/external/wpt/websockets/extended-payload-length.html
@@ -20,7 +20,7 @@ assert_equals(e.data, data); t.done(); }); -}, "Application data is 125 byte which means any 'Extended payload length' field isn't used at all.", {timeout:20000}); +}, "Application data is 125 byte which means any 'Extended payload length' field isn't used at all."); async_test(function(t){ var ws = new WebSocket(SCHEME_DOMAIN_PORT+'/echo'); @@ -34,7 +34,7 @@ assert_equals(e.data, data); t.done(); }); -}, "Application data is 126 byte which starts to use the 16 bit 'Extended payload length' field.", {timeout:20000}); +}, "Application data is 126 byte which starts to use the 16 bit 'Extended payload length' field."); async_test(function(t){ var ws = new WebSocket(SCHEME_DOMAIN_PORT+'/echo'); @@ -48,7 +48,7 @@ assert_equals(e.data, data); t.done(); }); -}, "Application data is 0xFFFF byte which means the upper bound of the 16 bit 'Extended payload length' field.", {timeout:20000}); +}, "Application data is 0xFFFF byte which means the upper bound of the 16 bit 'Extended payload length' field."); async_test(function(t){ var ws = new WebSocket(SCHEME_DOMAIN_PORT+'/echo'); @@ -62,6 +62,6 @@ assert_equals(e.data, data); t.done(); }); -}, "Application data is (0xFFFF + 1) byte which starts to use the 64 bit 'Extended payload length' field", {timeout:20000}); +}, "Application data is (0xFFFF + 1) byte which starts to use the 64 bit 'Extended payload length' field"); </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/websockets/interfaces/CloseEvent/clean-close.html b/third_party/WebKit/LayoutTests/external/wpt/websockets/interfaces/CloseEvent/clean-close.html index acc71851..ad22107 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/websockets/interfaces/CloseEvent/clean-close.html +++ b/third_party/WebKit/LayoutTests/external/wpt/websockets/interfaces/CloseEvent/clean-close.html
@@ -19,5 +19,5 @@ assert_equals(e.wasClean,true); t.done(); }); -}, null, {timeout:2000}); +}); </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/websockets/interfaces/WebSocket/bufferedAmount/bufferedAmount-large.html b/third_party/WebKit/LayoutTests/external/wpt/websockets/interfaces/WebSocket/bufferedAmount/bufferedAmount-large.html index 6774237..c9f15b0 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/websockets/interfaces/WebSocket/bufferedAmount/bufferedAmount-large.html +++ b/third_party/WebKit/LayoutTests/external/wpt/websockets/interfaces/WebSocket/bufferedAmount/bufferedAmount-large.html
@@ -23,5 +23,5 @@ assert_equals(e.data, data); t.done(); }) -}, null, {timeout:20000}); +}); </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/websockets/interfaces/WebSocket/close/close-basic.html b/third_party/WebKit/LayoutTests/external/wpt/websockets/interfaces/WebSocket/close/close-basic.html index ab6c93b..673f730 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/websockets/interfaces/WebSocket/close/close-basic.html +++ b/third_party/WebKit/LayoutTests/external/wpt/websockets/interfaces/WebSocket/close/close-basic.html
@@ -22,5 +22,5 @@ }); ws.close(); assert_equals(ws.readyState, ws.CLOSING); -}, undefined, {timeout:9900}); +}); </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/websockets/interfaces/WebSocket/close/close-connecting.html b/third_party/WebKit/LayoutTests/external/wpt/websockets/interfaces/WebSocket/close/close-connecting.html index 009d6b06..3e9e51b3 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/websockets/interfaces/WebSocket/close/close-connecting.html +++ b/third_party/WebKit/LayoutTests/external/wpt/websockets/interfaces/WebSocket/close/close-connecting.html
@@ -21,5 +21,5 @@ }); }, 1000); ws.onopen = ws.onclose = t.unreached_func(); -}, undefined, {timeout:12000}); +}); </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/websockets/interfaces/WebSocket/close/close-nested.html b/third_party/WebKit/LayoutTests/external/wpt/websockets/interfaces/WebSocket/close/close-nested.html index fa30c83..3ba99af9 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/websockets/interfaces/WebSocket/close/close-nested.html +++ b/third_party/WebKit/LayoutTests/external/wpt/websockets/interfaces/WebSocket/close/close-nested.html
@@ -24,5 +24,5 @@ }); ws.close(); assert_equals(ws.readyState, ws.CLOSING); -}, undefined, {timeout:9900}); +}); </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/websockets/interfaces/WebSocket/events/003.html b/third_party/WebKit/LayoutTests/external/wpt/websockets/interfaces/WebSocket/events/003.html index a9b76d8..430ea14f 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/websockets/interfaces/WebSocket/events/003.html +++ b/third_party/WebKit/LayoutTests/external/wpt/websockets/interfaces/WebSocket/events/003.html
@@ -17,5 +17,5 @@ var ev = document.createEvent('UIEvents'); ev.initUIEvent('open', false, false, window, 5); ws.dispatchEvent(ev); -}, null, {timeout:2000}); +}); </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/websockets/interfaces/WebSocket/events/007.html b/third_party/WebKit/LayoutTests/external/wpt/websockets/interfaces/WebSocket/events/007.html index 4305097d..1e4f236 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/websockets/interfaces/WebSocket/events/007.html +++ b/third_party/WebKit/LayoutTests/external/wpt/websockets/interfaces/WebSocket/events/007.html
@@ -17,5 +17,5 @@ var ev = document.createEvent('UIEvents'); ev.initUIEvent('message', false, false, window, 5); ws.dispatchEvent(ev); -}, null, {timeout:2000}); +}); </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/websockets/interfaces/WebSocket/events/009.html b/third_party/WebKit/LayoutTests/external/wpt/websockets/interfaces/WebSocket/events/009.html index dc25884ce..58df1d6 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/websockets/interfaces/WebSocket/events/009.html +++ b/third_party/WebKit/LayoutTests/external/wpt/websockets/interfaces/WebSocket/events/009.html
@@ -17,5 +17,5 @@ var ev = document.createEvent('UIEvents'); ev.initUIEvent('close', false, false, window, 5); ws.dispatchEvent(ev); -}, null, {timeout:2000}); +}); </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/websockets/keeping-connection-open/001.html b/third_party/WebKit/LayoutTests/external/wpt/websockets/keeping-connection-open/001.html index 2e5423c..f6d77a6 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/websockets/keeping-connection-open/001.html +++ b/third_party/WebKit/LayoutTests/external/wpt/websockets/keeping-connection-open/001.html
@@ -24,5 +24,5 @@ }); }, 20000); }) -}, null, {timeout:30000}); +}); </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/websockets/opening-handshake/001.html b/third_party/WebKit/LayoutTests/external/wpt/websockets/opening-handshake/001.html index 7274150..e0e9b4e2 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/websockets/opening-handshake/001.html +++ b/third_party/WebKit/LayoutTests/external/wpt/websockets/opening-handshake/001.html
@@ -15,5 +15,5 @@ t.step_timeout(() => t.done(), 50); }); ws.onmessage = ws.onopen = t.unreached_func(); -}, null, {timeout:9900}); +}); </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/websockets/opening-handshake/002.html b/third_party/WebKit/LayoutTests/external/wpt/websockets/opening-handshake/002.html index 052e6445..95139e19 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/websockets/opening-handshake/002.html +++ b/third_party/WebKit/LayoutTests/external/wpt/websockets/opening-handshake/002.html
@@ -19,5 +19,5 @@ ws.close(); }); ws.onerror = ws.onmessage = ws.onclose = t.unreached_func(); -}, null, {timeout:9900}); +}); </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/websockets/unload-a-document/002.html b/third_party/WebKit/LayoutTests/external/wpt/websockets/unload-a-document/002.html index 03764c3..94028e7 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/websockets/unload-a-document/002.html +++ b/third_party/WebKit/LayoutTests/external/wpt/websockets/unload-a-document/002.html
@@ -10,7 +10,7 @@ <p>Test requires popup blocker disabled</p> <div id=log></div> <script> -var t = async_test(null, {timeout:15000}); +var t = async_test(); var w; var uuid; t.step(function() {
diff --git a/third_party/WebKit/LayoutTests/external/wpt/websockets/unload-a-document/004.html b/third_party/WebKit/LayoutTests/external/wpt/websockets/unload-a-document/004.html index 0ef4fbc..bb15cd8 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/websockets/unload-a-document/004.html +++ b/third_party/WebKit/LayoutTests/external/wpt/websockets/unload-a-document/004.html
@@ -7,7 +7,7 @@ <div id=log></div> <script> var uuid; -var t = async_test(null, {timeout:15000}) +var t = async_test(); t.step(function() {uuid = token()}); var navigate = t.step_func(function() { document.getElementsByTagName("iframe")[0].src = 'data:text/html,<body onload="history.back()">';
diff --git a/third_party/WebKit/LayoutTests/external/wpt/websockets/unload-a-document/005.html b/third_party/WebKit/LayoutTests/external/wpt/websockets/unload-a-document/005.html index 4bafe8b..81a05f4 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/websockets/unload-a-document/005.html +++ b/third_party/WebKit/LayoutTests/external/wpt/websockets/unload-a-document/005.html
@@ -10,7 +10,7 @@ <p>Test requires popup blocker disabled</p> <div id=log></div> <script> -var t = async_test(null, {timeout:15000}); +var t = async_test(); t.step(function() { var w = window.open("005-1.html"); add_result_callback(function() {
diff --git a/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-track-sizing-with-orthogonal-flows.html b/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-track-sizing-with-orthogonal-flows.html index ffe0530d..3426cf5 100644 --- a/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-track-sizing-with-orthogonal-flows.html +++ b/third_party/WebKit/LayoutTests/fast/css-grid-layout/grid-track-sizing-with-orthogonal-flows.html
@@ -76,10 +76,10 @@ <div class="container"> <p>Grid with <b>fixed</b> width and height under <b>min-content</b> constrain.<br >All grid items sized with <b>min-{width, height} auto</b>.</p> - <div class="grid itemsStart contentStart min-content width300" data-expected-width="300" data-expected-height="90"> + <div class="grid itemsStart contentStart min-content width300" data-expected-width="300" data-expected-height="490"> <div class="firstRowFirstColumn" data-offset-x="0" data-offset-y="0" data-expected-width="150" data-expected-height="10">XX XXX X XXX XX</div> - <div class="verticalLR firstRowSecondColumn" data-offset-x="150" data-offset-y="0" data-expected-width="70" data-expected-height="50">X XXX XX XXXXX XX XXX X XXXX X XX</div> - <div class="verticalLR secondRowFirstColumn" data-offset-x="0" data-offset-y="50" data-expected-width="40" data-expected-height="40">XXXX XX X XX XXX</div> + <div class="verticalLR firstRowSecondColumn" data-offset-x="150" data-offset-y="0" data-expected-width="10" data-expected-height="330">X XXX XX XXXXX XX XXX X XXXX X XX</div> + <div class="verticalLR secondRowFirstColumn" data-offset-x="0" data-offset-y="330" data-expected-width="10" data-expected-height="160">XXXX XX X XX XXX</div> </div> </div> @@ -132,10 +132,10 @@ <div class="container"> <p>Grid with <b>fixed</b> width and height under <b>min-content</b> constrain.<br> All grid items sized with <b>min-width: auto, min-height: 0px</b>.</p> - <div class="grid itemsStart contentStart min-content width300 " data-expected-width="300" data-expected-height="0"> + <div class="grid itemsStart contentStart min-content width300 " data-expected-width="300" data-expected-height="490"> <div class="minHeightZero firstRowFirstColumn" data-offset-x="0" data-offset-y="0" data-expected-width="150" data-expected-height="10">XX XXX X XXX XX</div> - <div class="minHeightZero verticalLR firstRowSecondColumn" data-offset-x="150" data-offset-y="0" data-expected-width="70" data-expected-height="50">X XXX XX XXXXX XX XXX X XXXX X XX</div> - <div class="minHeightZero verticalLR secondRowFirstColumn" data-offset-x="0" data-offset-y="0" data-expected-width="40" data-expected-height="40">XXXX XX X XX XXX</div> + <div class="minHeightZero verticalLR firstRowSecondColumn" data-offset-x="150" data-offset-y="0" data-expected-width="10" data-expected-height="330">X XXX XX XXXXX XX XXX X XXXX X XX</div> + <div class="minHeightZero verticalLR secondRowFirstColumn" data-offset-x="0" data-offset-y="330" data-expected-width="10" data-expected-height="160">XXXX XX X XX XXX</div> </div> </div> @@ -177,10 +177,10 @@ <div class="container"> <p>Grid with <b>fixed</b> width and height under <b>min-content</b> constrain.<br> All grid items sized with <b>min-width: auto, min-height: 50px</b>.</p> - <div class="grid itemsStart contentStart min-content width300" data-expected-width="300" data-expected-height="100"> + <div class="grid itemsStart contentStart min-content width300" data-expected-width="300" data-expected-height="490"> <div class="minHeightFixed firstRowFirstColumn" data-offset-x="0" data-offset-y="0" data-expected-width="150" data-expected-height="50">XX XXX X XXX XX</div> - <div class="minHeightFixed verticalLR firstRowSecondColumn" data-offset-x="150" data-offset-y="0" data-expected-width="70" data-expected-height="50">X XXX XX XXXXX XX XXX X XXXX X XX</div> - <div class="minHeightFixed verticalLR secondRowFirstColumn" data-offset-x="0" data-offset-y="50" data-expected-width="40" data-expected-height="50">XXXX XX X XX XXX</div> + <div class="minHeightFixed verticalLR firstRowSecondColumn" data-offset-x="150" data-offset-y="0" data-expected-width="10" data-expected-height="330">X XXX XX XXXXX XX XXX X XXXX X XX</div> + <div class="minHeightFixed verticalLR secondRowFirstColumn" data-offset-x="0" data-offset-y="330" data-expected-width="10" data-expected-height="160">XXXX XX X XX XXX</div> </div> </div>
diff --git a/third_party/WebKit/LayoutTests/fast/css-grid-layout/maximize-tracks-definite-indefinite-height.html b/third_party/WebKit/LayoutTests/fast/css-grid-layout/maximize-tracks-definite-indefinite-height.html index 846071b..ecb95dc 100644 --- a/third_party/WebKit/LayoutTests/fast/css-grid-layout/maximize-tracks-definite-indefinite-height.html +++ b/third_party/WebKit/LayoutTests/fast/css-grid-layout/maximize-tracks-definite-indefinite-height.html
@@ -55,11 +55,11 @@ <div class="sizedToGridArea" data-expected-width="40" data-expected-height="100">XX XXX XX XXX</div> </div> -<div class="grid max-content max-height-min-content" data-expected-width="40" data-expected-height="0"> +<div class="grid max-content max-height-min-content" data-expected-width="40" data-expected-height="100"> <div class="sizedToGridArea" data-expected-width="40" data-expected-height="100">XX XXX X</div> </div> -<div class="grid max-height-min-content" data-expected-width="40" data-expected-height="0"> +<div class="grid max-height-min-content" data-expected-width="40" data-expected-height="100"> <div class="sizedToGridArea" data-expected-width="40" data-expected-height="100">XX XXX</div> </div> @@ -129,11 +129,11 @@ </div> </div> -<div class="grid itemsStart min-content" data-expected-width="40" data-expected-height="0"> +<div class="grid itemsStart min-content" data-expected-width="40" data-expected-height="100"> <div class="sizedToGridArea" data-expected-width="40" data-expected-height="100">XX XX XX</div> </div> -<div class="grid itemsStart min-content min-height-50" data-expected-width="40" data-expected-height="50"> +<div class="grid itemsStart min-content min-height-50" data-expected-width="40" data-expected-height="100"> <div class="sizedToGridArea" data-expected-width="40" data-expected-height="100">XX X</div> </div> @@ -147,11 +147,11 @@ </div> </div> -<div class="grid itemsStart min-content min-height-min-content" data-expected-width="40" data-expected-height="0"> +<div class="grid itemsStart min-content min-height-min-content" data-expected-width="40" data-expected-height="100"> <div class="sizedToGridArea" data-expected-width="40" data-expected-height="100">XX XXX</div> </div> -<div class="grid itemsStart min-content min-height-35" data-expected-width="40" data-expected-height="35"> +<div class="grid itemsStart min-content min-height-35" data-expected-width="40" data-expected-height="100"> <div class="sizedToGridArea" data-expected-width="40" data-expected-height="100">XX XX</div> </div> @@ -159,11 +159,11 @@ <div class="sizedToGridArea" data-expected-width="40" data-expected-height="100">X XXX X</div> </div> -<div class="grid itemsStart min-content min-height-50" data-expected-width="40" data-expected-height="50"> +<div class="grid itemsStart min-content min-height-50" data-expected-width="40" data-expected-height="100"> <div class="sizedToGridArea" data-expected-width="40" data-expected-height="100">XXXX XXXX XXXX XXXX</div> </div> -<div class="grid itemsStart min-content max-height-50" data-expected-width="40" data-expected-height="0"> +<div class="grid itemsStart min-content max-height-50" data-expected-width="40" data-expected-height="50"> <div class="sizedToGridArea min-height-fill-available" data-expected-width="40" data-expected-height="100">XXXX X X XXXX</div> </div> @@ -206,7 +206,7 @@ <div class="grid itemsStart min-height-35" data-expected-width="40" data-expected-height="100"> <div class="sizedToGridArea" data-expected-width="40" data-expected-height="100">X XXXX X</div> </div> - <div class="grid itemsStart max-height-min-content" data-expected-width="40" data-expected-height="0"> + <div class="grid itemsStart max-height-min-content" data-expected-width="40" data-expected-height="100"> <div class="sizedToGridArea" data-expected-width="40" data-expected-height="100">XX XX XX</div> </div> <div class="grid itemsStart fit-content" data-expected-width="40" data-expected-height="100"> @@ -227,7 +227,7 @@ <div class="grid itemsStart min-height-35" data-expected-width="40" data-expected-height="100"> <div class="sizedToGridArea" data-expected-width="40" data-expected-height="100">XXXX X X</div> </div> - <div class="grid itemsStart max-height-min-content" data-expected-width="40" data-expected-height="0"> + <div class="grid itemsStart max-height-min-content" data-expected-width="40" data-expected-height="100"> <div class="sizedToGridArea" data-expected-width="40" data-expected-height="100">X XXX XX</div> </div> <div class="grid itemsStart fit-content" data-expected-width="40" data-expected-height="100"> @@ -242,16 +242,16 @@ </div> <div style="height: 25px;"> - <div class="grid itemsStart fit-content" data-expected-width="40" data-expected-height="25"> + <div class="grid itemsStart fit-content" data-expected-width="40" data-expected-height="100"> <div class="sizedToGridArea" data-expected-width="40" data-expected-height="100">XX X</div> </div> <div class="grid itemsStart fill-available" data-expected-width="40" data-expected-height="25"> <div class="sizedToGridArea" data-expected-width="40" data-expected-height="100">XX X</div> </div> - <div class="grid itemsStart fit-content min-height-35" data-expected-width="40" data-expected-height="35"> + <div class="grid itemsStart fit-content min-height-35" data-expected-width="40" data-expected-height="100"> <div class="sizedToGridArea" data-expected-width="40" data-expected-height="100">XX X</div> </div> - <div class="grid itemsStart fit-content max-height-min-content" data-expected-width="40" data-expected-height="0"> + <div class="grid itemsStart fit-content max-height-min-content" data-expected-width="40" data-expected-height="100"> <div class="sizedToGridArea" data-expected-width="40" data-expected-height="100">XX X</div> </div> </div>
diff --git a/third_party/WebKit/LayoutTests/fast/dnd/dragtriggerdommove/drag-trigger-dom-move-iframe.html b/third_party/WebKit/LayoutTests/fast/dnd/dragtriggerdommove/drag-trigger-dom-move-iframe.html new file mode 100644 index 0000000..81014a6 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/dnd/dragtriggerdommove/drag-trigger-dom-move-iframe.html
@@ -0,0 +1,55 @@ +<!doctype html> +<meta charset="utf-8"> +<!-- This test will check whether an iframe that doesn't contain the drag + source, moving via DOM manipulation, will reset the drag source and + potentially cancel dragend event emission. --> +<title>Drag and Drop: Iframe DOM Move</title> +<link rel="help" href="https://html.spec.whatwg.org/multipage/interaction.html#drag-and-drop-processing-model"> + +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<script src="../resources/drag-trigger-dom-move.js"></script> + +<style> + .box { + display: block; + border: 1px solid black; + width: 350px; + height: 200px; + text-align: center; + } +</style> + +<p> + Please drag the "Drag Me" box into the "Drop Here" box. +</p> + +<div id="drag-box" class="dragged box" draggable="true"> + Drag me +</div> + +<div id="drop-box" class="dropzone box"> + Drop Here +</div> + +<div id="moved-item-source" class="box"> + <iframe id="outer-iframe" data-source="iframe-srcdoc"></iframe> +</div> +<div id="moved-item-destination" class="box"></div> + +<script id="iframe-srcdoc" language="text/html"> + <!doctype html> + <meta charset="utf-8"> + <div/> +</script> + +<p> + Current test: <code id="test-description"></code> +</p> + +<script> + dragDomMoveTests([ + { load: 'iframe', expectDragEnd: true, action: 'appendChild' }, + { load: 'iframe', expectDragEnd: true, action: 'removeChild' }, + ]); +</script> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/fast/dnd/dragtriggerdommove/drag-trigger-dom-move-image.html b/third_party/WebKit/LayoutTests/fast/dnd/dragtriggerdommove/drag-trigger-dom-move-image.html new file mode 100644 index 0000000..b2082fc1 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/dnd/dragtriggerdommove/drag-trigger-dom-move-image.html
@@ -0,0 +1,46 @@ +<!doctype html> +<meta charset="utf-8"> +<!-- This test will check whether an image moving via DOM manipulation will + reset the drag source and potentially cancel dragend event emission. --> +<title>Drag and Drop: Image DOM Move</title> +<link rel="help" href="https://html.spec.whatwg.org/multipage/interaction.html#drag-and-drop-processing-model"> + +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<script src="../resources/drag-trigger-dom-move.js"></script> + +<style> + .box { + display: block; + border: 1px solid black; + width: 350px; + height: 200px; + text-align: center; + } +</style> + +<p> + Please drag the "Drag Me" box into the "Drop Here" box. +</p> + +<div id="drag-box" class="dragged box" draggable="true"> + Drag me +</div> + +<div id="drop-box" class="dropzone box"> + Drop Here +</div> + +<div id="moved-item-source" class="box"></div> +<div id="moved-item-destination" class="box"></div> + +<p> + Current test: <code id="test-description"></code> +</p> + +<script> + dragDomMoveTests([ + { load: 'image', expectDragEnd: true, action: 'removeChild' }, + { load: 'image', expectDragEnd: true, action: 'appendChild' }, + ]); +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/dnd/dragtriggerdommove/drag-trigger-dom-move-nested-iframe.html b/third_party/WebKit/LayoutTests/fast/dnd/dragtriggerdommove/drag-trigger-dom-move-nested-iframe.html new file mode 100644 index 0000000..90691cfb --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/dnd/dragtriggerdommove/drag-trigger-dom-move-nested-iframe.html
@@ -0,0 +1,66 @@ +<!doctype html> +<meta charset="utf-8"> +<!-- This test will check whether an iframe that contains the drag source, + moving via DOM manipulation, will reset the drag source and potentially + cancel dragend event emission. --> +<title>Drag and Drop: Nested Iframe DOM Move</title> +<link rel="help" href="https://html.spec.whatwg.org/multipage/interaction.html#drag-and-drop-processing-model"> + +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<script src="../resources/drag-trigger-dom-move.js"></script> + +<style> + .box { + display: block; + border: 1px solid black; + width: 350px; + height: 200px; + text-align: center; + } +</style> + +<div id="moved-item-source" class="dragged box"> + <iframe id="outer-iframe" data-source="iframe-srcdoc"></iframe> +</div> + +<div id="drop-box" class="dropzone box"> + Drop Here +</div> + +<p> + Please drag the "Drag Me" into the "Drop Here" box. +</p> + +<div id="moved-item-destination" class="box"></div> + +<script id="iframe-srcdoc" language="text/html"> + <!doctype html> + <meta charset="utf-8"> + + <style> + .box { + display: block; + border: 1px solid black; + width: 250px; + height: 100px; + text-align: center; + } + </style> + <div id="drag-box" class="box" draggable="true"> + <p>Drag me!</p> + </div> +</script> + +<p> + Current test: <code id="test-description"></code> +</p> + +<script> + dragDomMoveTests([ + { load: 'nested iframe', expectDragEnd: false, + action: 'appendChild' }, + { load: 'nested iframe', expectDragEnd: false, + action: 'removeChild' }, + ]); +</script> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/fast/dnd/dragtriggerdommove/drag-trigger-dom-move-nested-iframes.html b/third_party/WebKit/LayoutTests/fast/dnd/dragtriggerdommove/drag-trigger-dom-move-nested-iframes.html new file mode 100644 index 0000000..52623b8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/dnd/dragtriggerdommove/drag-trigger-dom-move-nested-iframes.html
@@ -0,0 +1,73 @@ +<!doctype html> +<meta charset="utf-8"> +<!-- This test will check whether an iframe that contains an iframe containing + the drag source, moving via DOM manipulation, will reset the drag source + and potentially cancel dragend event emission. --> +<title>Drag and Drop: Nested Iframe DOM Move</title> +<link rel="help" href="https://html.spec.whatwg.org/multipage/interaction.html#drag-and-drop-processing-model"> + +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<script src="../resources/drag-trigger-dom-move.js"></script> + +<style> + .box { + display: block; + border: 1px solid black; + width: 350px; + height: 200px; + text-align: center; + } +</style> + +<div id="moved-item-source" class="dragged box"> + <iframe id="outer-iframe" data-source="iframe-srcdoc"></iframe> +</div> + +<div id="drop-box" class="dropzone box"> + Drop Here +</div> + +<p> + Please drag the "Drag Me" into the "Drop Here" box. +</p> + +<div id="moved-item-destination" class="box"></div> + +<script id="iframe-srcdoc" language="text/html"> + <!doctype html> + <meta charset="utf-8"> + + <iframe id="inner-iframe" data-source="inner-iframe-srcdoc"/> +</script> + +<script id="inner-iframe-srcdoc" language="text/html"> + <!doctype html> + <meta charset="utf-8"> + + <style> + .box { + display: block; + border: 1px solid black; + width: 250px; + height: 100px; + text-align: center; + } + </style> + <div id="drag-box" class="box" draggable="true"> + <p>Drag me!</p> + </div> +</script> + +<p> + Current test: <code id="test-description"></code> +</p> + +<script> + dragDomMoveTests([ + { load: 'doubly nested iframe', expectDragEnd: false, + action: 'appendChild' }, + { load: 'doubly nested iframe', expectDragEnd: false, + action: 'removeChild' }, + ]); +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/dnd/resources/drag-trigger-dom-move.js b/third_party/WebKit/LayoutTests/fast/dnd/resources/drag-trigger-dom-move.js new file mode 100644 index 0000000..2693529 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/dnd/resources/drag-trigger-dom-move.js
@@ -0,0 +1,175 @@ +'use strict' + +/** Moves the mouse to the center of |element|. */ +const mouseMoveToCenter = element => { + const clientRect = element.getBoundingClientRect(); + const centerX = (clientRect.left + clientRect.right) / 2; + const centerY = (clientRect.top + clientRect.bottom) / 2; + if (window.eventSender) + eventSender.mouseMoveTo(centerX, centerY); +}; + +/** + * Recursively loads content into a series of nested iframes. + * Returns a Promise that resolves with the HTMLDocument of the innermost frame. + */ +const loadNestedFrames = async domRoot => { + const frame = domRoot.querySelector('iframe'); + if (!frame) + return domRoot; + + const htmlSourceId = frame.getAttribute('data-source'); + frame.srcdoc = document.getElementById(htmlSourceId).textContent; + const frameLoaded = new Promise(resolve => { frame.onload = resolve; }); + await frameLoaded; + + return await loadNestedFrames(frame.contentDocument); +}; + +/** Retrieves an element with id in an arbitrarily deep nesting of iframes. */ +const getElementByIdAcrossIframes = (domRoot, id) => { + if (!domRoot) + return null; + + const dragBox = domRoot.getElementById(id); + if (dragBox) + return dragBox; + + return getElementByIdAcrossIframes( + domRoot.querySelector('iframe').contentDocument, id); +}; + +const loadIframe = async () => { + await loadNestedFrames(document); + return document.getElementById('outer-iframe'); +}; + +const loadImage = async () => { + const image = document.createElement('img'); + image.src = '../resources/greenbox.png'; + + const imageLoaded = new Promise(resolve => { + image.onload = resolve(image); + document.getElementById('moved-item-source').appendChild(image); + }); + return await imageLoaded; +}; + +const loadMovedItem = async loadItem => { + if (loadItem.includes('iframe')) + return await loadIframe(); + else if (loadItem.includes('image')) + return await loadImage(); +}; + +/** + * Test if moving an element (iframe or image) will cancel dragging by + * resetting drag source. + * testCase: a testCase to test, containing a specified type to load and + * whether or not dragend is expected to fire, as well as the action + * to attempt. + */ +const dragDomMoveTest = testCase => { + promise_test(async t => { + document.querySelector('#test-description').textContent = + JSON.stringify(testCase); + + const gotEvent = { + dragStart: false, + dragOver: false, + drop: false, + dragEnd: false, + }; + + let movedItem = await loadMovedItem(testCase.load); + const dragBox = getElementByIdAcrossIframes(document, 'drag-box'); + const dropBox = document.getElementById('drop-box'); + const doneButton = document.createElement('button'); + + dragBox.ondragstart = t.step_func(e => { + gotEvent.dragStart = true; + e.dataTransfer.setData('text/plain', 'Needed to work in Firefox'); + }); + dropBox.ondragover = t.step_func(e => { + gotEvent.dragOver = true; + e.preventDefault(); + }); + + const dndTest = new Promise(resolve => { + dragBox.ondragend = t.step_func(e => { + gotEvent.dragEnd = true; + return resolve(); + }); + dropBox.ondrop = t.step_func(async e => { + gotEvent.drop = true; + e.preventDefault(); + + const movedItemDestination = + document.getElementById('moved-item-destination'); + const movedItemSource = + document.getElementById('moved-item-source'); + + // Test whether dragging away or detaching movedItem + // will disable dragging. + if (testCase.action == 'removeChild') + movedItem = movedItem.parentNode.removeChild(movedItem); + else if (testCase.action == 'appendChild') + movedItemDestination.appendChild(movedItem); + else + return reject("Error: Invalid testCase.action. Please make sure the testCase is spelled correctly"); + + // Click to resolve test as backup in case dragend never triggers to + // end the test. + setTimeout(() => { + const clickEvent = new Event('click'); + doneButton.dispatchEvent(clickEvent); + }, 100); + + // Reset iframe location to teardown and prep for next test. + if (testCase.load.includes('iframe')) { + const movedItemLoaded = new Promise(resolve => { + movedItem.onload = resolve; + setTimeout(() => { movedItemSource.appendChild(movedItem); }, 100); + }); + + await movedItemLoaded; + } + }); + + doneButton.onclick = t.step_func(() => { + return resolve(); + }) + + // Do drag and drop. + if (window.eventSender) { + mouseMoveToCenter(dragBox); + eventSender.mouseDown(); + setTimeout(() => { + mouseMoveToCenter(dropBox); + eventSender.mouseUp(); + }, 100); + } + }); + await dndTest; + + assert_true(gotEvent.dragStart, + 'drag-box should have gotten a dragstart event'); + assert_true(gotEvent.dragOver, + 'drop-box should have gotten a dragover event'); + assert_true(gotEvent.drop, + 'drop-box should have gotten a drop event'); + assert_equals(gotEvent.dragEnd, testCase.expectDragEnd, + 'drag-box should have gotten a dragEnd event'); + }, `tested with input: ${testCase.load}, ${testCase.action}`); +}; + +const dragDomMoveTests = testCases => { + for (let testCase of testCases) + dragDomMoveTest(testCase); + + promise_test(() => { + return Promise.resolve().then(() => { + document.querySelector('#test-description').textContent = 'done'; + }); + }, 'all tests complete'); +}
diff --git a/third_party/WebKit/LayoutTests/fast/mediacapturefromelement/CanvasCaptureMediaStream-applyConstraints.html b/third_party/WebKit/LayoutTests/fast/mediacapturefromelement/CanvasCaptureMediaStream-applyConstraints.html new file mode 100644 index 0000000..277ebda7 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/mediacapturefromelement/CanvasCaptureMediaStream-applyConstraints.html
@@ -0,0 +1,44 @@ +<!doctype html> +<title>CanvasCapture applyConstraints</title> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script> + +promise_test(async t => { + let canvas = document.createElement('canvas'); + canvas.width = canvas.height = 64; + + let stream = canvas.captureStream(); + let track = stream.getVideoTracks()[0]; + t.add_cleanup(() => track.stop()); + + let settings = track.getSettings(); + assert_equals(settings.width, canvas.width); + assert_equals(settings.height, canvas.height); + assert_equals(settings.resizeMode, 'none'); + + await track.applyConstraints({width: 63, height: 63}); + settings = track.getSettings(); + assert_equals(settings.width, 63); + assert_equals(settings.height, 63); + assert_equals(settings.resizeMode, 'crop-and-scale'); + + await track.applyConstraints({resizeMode: {exact: 'none'}}); + settings = track.getSettings(); + assert_equals(settings.width, canvas.width); + assert_equals(settings.height, canvas.height); + assert_equals(settings.resizeMode, 'none'); + + try { + await track.applyConstraints( + {width: {exact: 63}, resizeMode: {exact: 'none'}}); + t.step(()=>assert_unreached('applyConstraints should not have succeeded')); + } catch(e) { + assert_equals(e.name, 'OverconstrainedError'); + assert_equals(e.constraint, 'width'); + } + +}, "Canvas capture resizeMode"); +</script> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack-applyConstraints.html b/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack-applyConstraints.html index 66f08c38..a14f38d 100644 --- a/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack-applyConstraints.html +++ b/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack-applyConstraints.html
@@ -191,6 +191,32 @@ constraintSyntaxTestWithChange('noiseSuppression with exact unwrapped boolean value', { noiseSuppression: { exact: true } }, { noiseSuppression: true }); +promise_test(async t => { + let stream = await navigator.mediaDevices.getUserMedia( + {video: {width: 639, height: 479}}); + let track = stream.getVideoTracks()[0]; + t.add_cleanup(()=>track.stop()); + let settings = track.getSettings(); + assert_equals(settings.width, 639); + assert_equals(settings.height, 479); + assert_equals(settings.resizeMode, "crop-and-scale"); + + await track.applyConstraints({resizeMode: {exact: "none"}}); + settings = track.getSettings(); + assert_equals(settings.width, 640); + assert_equals(settings.height, 480); + assert_equals(settings.resizeMode, "none"); + + try { + await track.applyConstraints( + {width: {exact: 639}, resizeMode: {exact: 'none'}}); + t.step(()=>assert_unreached('applyConstraints should not have succeeded')); + } catch(e) { + assert_equals(e.name, 'OverconstrainedError'); + assert_equals(e.constraint, 'width'); + } +}, "applyConstraints() supports resizeMode in getUserMedia() tracks"); + </script> </body> </html>
diff --git a/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack-getCapabilities.html b/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack-getCapabilities.html index 45c4879fb..9ca6945c 100644 --- a/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack-getCapabilities.html +++ b/third_party/WebKit/LayoutTests/fast/mediastream/MediaStreamTrack-getCapabilities.html
@@ -22,6 +22,9 @@ assert_true(capabilities.hasOwnProperty('groupId')); assert_true(capabilities.hasOwnProperty('facingMode')); verifyVideoRangeProperties(capabilities); + assert_true(capabilities.hasOwnProperty('resizeMode')); + assert_in_array('none', capabilities.resizeMode); + assert_in_array('crop-and-scale', capabilities.resizeMode); }); }, 'getCapabilities() support for getUserMedia() video track.'); @@ -42,6 +45,9 @@ assert_true(capabilities.hasOwnProperty('facingMode')); assert_equals(Object.keys(capabilities.facingMode).length, 0); verifyVideoRangeProperties(capabilities); + assert_true(capabilities.hasOwnProperty('resizeMode')); + assert_in_array('none', capabilities.resizeMode); + assert_in_array('crop-and-scale', capabilities.resizeMode); }, 'getCapabilities() support for video track associated with a canvas element.'); test(function() { @@ -60,6 +66,9 @@ assert_true(videoCapabilities.hasOwnProperty('facingMode')); assert_equals(Object.keys(videoCapabilities.facingMode).length, 0); verifyVideoRangeProperties(videoCapabilities); + assert_true(videoCapabilities.hasOwnProperty('resizeMode')); + assert_in_array('none', videoCapabilities.resizeMode); + assert_in_array('crop-and-scale', videoCapabilities.resizeMode); }; }, 'getCapabilities() support for audio and video tracks associated with a video element.'); @@ -81,6 +90,9 @@ assert_true(videoCapabilities.hasOwnProperty('deviceId')); assert_true(videoCapabilities.hasOwnProperty('facingMode')); assert_equals(Object.keys(videoCapabilities.facingMode).length, 0); + assert_true(videoCapabilities.hasOwnProperty('resizeMode')); + assert_in_array('none', videoCapabilities.resizeMode); + assert_in_array('crop-and-scale', videoCapabilities.resizeMode); }); }, 'getCapabilities() support for audio and video tracks associated with a RTCPeerConnection.');
diff --git a/third_party/WebKit/LayoutTests/fast/mediastream/getusermedia-constraints.html b/third_party/WebKit/LayoutTests/fast/mediastream/getusermedia-constraints.html index 24ea86d..b6335fa 100644 --- a/third_party/WebKit/LayoutTests/fast/mediastream/getusermedia-constraints.html +++ b/third_party/WebKit/LayoutTests/fast/mediastream/getusermedia-constraints.html
@@ -127,6 +127,37 @@ 'Using both mandatory and height should give TypeError', {'mandatory': {'height': '270'}, 'height': '270'}, 'TypeError'); +promise_test(async t => { + let stream = await navigator.mediaDevices.getUserMedia( + {video: {width: 639, height: 479}}); + let track = stream.getVideoTracks()[0]; + let settings = track.getSettings(); + assert_equals(settings.width, 639); + assert_equals(settings.height, 479); + assert_equals(settings.resizeMode, "crop-and-scale"); + track.stop(); + + stream = await navigator.mediaDevices.getUserMedia( + {video: {width: 639, height: 479, resizeMode: {exact: "none"}}}); + track = stream.getVideoTracks()[0]; + settings = track.getSettings(); + // With rescaling disabled, a native resolution is used. + assert_equals(settings.width, 640); + assert_equals(settings.height, 480); + assert_equals(settings.resizeMode, "none"); + track.stop(); + + try { + stream = await navigator.mediaDevices.getUserMedia( + {video: {width: {exact: 639}, resizeMode: {exact: "none"}}}); + t.add_cleanup(()=>stream.getVideoTracks()[0].stop()); + t.step(() => assert_unreached('applyConstraints should have failed')); + } catch(e) { + assert_equals(e.name, 'OverconstrainedError'); + assert_equals(e.constraint, 'width'); + } +}, 'getUserMedia() resizeMode constraint'); + </script> </body> </html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/workers/shared-worker-importScripts-expected.txt b/third_party/WebKit/LayoutTests/http/tests/workers/shared-worker-importScripts-expected.txt index ebd5837..cee477a7 100644 --- a/third_party/WebKit/LayoutTests/http/tests/workers/shared-worker-importScripts-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/workers/shared-worker-importScripts-expected.txt
@@ -27,18 +27,18 @@ PASS: Threw NetworkError: Failed to execute 'importScripts' on 'WorkerGlobalScope': The script at 'http://127.0.0.1:8000/workers/resources/nonexistant' failed to load. when load failed PASS: some resources were loaded despite the network error Loaded resource 1 -PASS: Threw Error: Uncaught SyntaxError: Unexpected identifier when encountering a syntax error in imported script +PASS: Threw SyntaxError: Unexpected identifier when encountering a syntax error in imported script PASS: some resources were loaded despite the presence of a syntax error Testing multiple arguments, with first resource throwing an exception: Loaded resource 1 First resource throwing an exception -PASS: Propagated 'Error: Uncaught Thrown by first resource' from script +PASS: Propagated 'Thrown by first resource' from script PASS: First resource was executed, and second resource was not Testing multiple arguments, with second resource throwing an exception: Loaded resource 1 Loaded resource 2 Second resource throwing an exception -PASS: Propagated 'Error: Uncaught Thrown by second resource' from script +PASS: Propagated 'Thrown by second resource' from script PASS: Both scripts were executed Testing multiple arguments, with second argument throwing in toString(): PASS: User error recieved in toString
diff --git a/third_party/WebKit/LayoutTests/http/tests/workers/worker-importScripts-expected.txt b/third_party/WebKit/LayoutTests/http/tests/workers/worker-importScripts-expected.txt index d6a4aab..25662cb 100644 --- a/third_party/WebKit/LayoutTests/http/tests/workers/worker-importScripts-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/workers/worker-importScripts-expected.txt
@@ -27,18 +27,18 @@ PASS: Threw NetworkError: Failed to execute 'importScripts' on 'WorkerGlobalScope': The script at 'http://127.0.0.1:8000/workers/resources/nonexistant' failed to load. when load failed PASS: some resources were loaded despite the network error Loaded resource 1 -PASS: Threw Error: Uncaught SyntaxError: Unexpected identifier when encountering a syntax error in imported script +PASS: Threw SyntaxError: Unexpected identifier when encountering a syntax error in imported script PASS: some resources were loaded despite the presence of a syntax error Testing multiple arguments, with first resource throwing an exception: Loaded resource 1 First resource throwing an exception -PASS: Propagated 'Error: Uncaught Thrown by first resource' from script +PASS: Propagated 'Thrown by first resource' from script PASS: First resource was executed, and second resource was not Testing multiple arguments, with second resource throwing an exception: Loaded resource 1 Loaded resource 2 Second resource throwing an exception -PASS: Propagated 'Error: Uncaught Thrown by second resource' from script +PASS: Propagated 'Thrown by second resource' from script PASS: Both scripts were executed Testing multiple arguments, with second argument throwing in toString(): PASS: User error recieved in toString
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/webrtc-wpt-unified-plan/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-nomsid-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/webrtc-wpt-unified-plan/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-nomsid-expected.txt new file mode 100644 index 0000000..c2b5c6e4 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/webrtc-wpt-unified-plan/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-nomsid-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL setRemoteDescription with an SDP without a=msid lines triggers ontrack with a default stream. assert_equals: expected 1 but got 0 +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/webrtc-wpt-unified-plan/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-nomsid-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/webrtc-wpt-unified-plan/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-nomsid-expected.txt new file mode 100644 index 0000000..c2b5c6e4 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/webrtc-wpt-unified-plan/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-nomsid-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL setRemoteDescription with an SDP without a=msid lines triggers ontrack with a default stream. assert_equals: expected 1 but got 0 +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/webrtc-wpt-unified-plan/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-nomsid-expected.txt b/third_party/WebKit/LayoutTests/platform/win7/virtual/webrtc-wpt-unified-plan/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-nomsid-expected.txt new file mode 100644 index 0000000..c2b5c6e4 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win7/virtual/webrtc-wpt-unified-plan/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-nomsid-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL setRemoteDescription with an SDP without a=msid lines triggers ontrack with a default stream. assert_equals: expected 1 but got 0 +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/virtual/webrtc-wpt-unified-plan/external/wpt/webrtc/RTCPeerConnection-onnegotiationneeded-expected.txt b/third_party/WebKit/LayoutTests/virtual/webrtc-wpt-unified-plan/external/wpt/webrtc/RTCPeerConnection-onnegotiationneeded-expected.txt index bafe7db..0861101 100644 --- a/third_party/WebKit/LayoutTests/virtual/webrtc-wpt-unified-plan/external/wpt/webrtc/RTCPeerConnection-onnegotiationneeded-expected.txt +++ b/third_party/WebKit/LayoutTests/virtual/webrtc-wpt-unified-plan/external/wpt/webrtc/RTCPeerConnection-onnegotiationneeded-expected.txt
@@ -4,7 +4,7 @@ PASS addTransceiver() should fire negotiationneeded event FAIL Calling addTransceiver() twice should fire negotiationneeded event once assert_unreached: Pending promise should never be resolved. Instead it is fulfilled with: [object Object] Reached unreachable code FAIL Calling both addTransceiver() and createDataChannel() should fire negotiationneeded event once assert_unreached: Pending promise should never be resolved. Instead it is fulfilled with: [object Object] Reached unreachable code -FAIL negotiationneeded event should not fire if signaling state is not stable assert_unreached: Pending promise should never be resolved. Instead it is fulfilled with: [object Object] Reached unreachable code +PASS negotiationneeded event should not fire if signaling state is not stable FAIL negotiationneeded event should fire only after signaling state go back to stable assert_unreached: Expect negotiationneeded promise to resolve after pc has set remote answer and go back to stable state Reached unreachable code Harness: the test ran to completion.
diff --git a/third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom b/third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom index 66f9453..15cc955 100644 --- a/third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom +++ b/third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom
@@ -103,18 +103,17 @@ struct FetchAPIRequest { network.mojom.FetchRequestMode mode = network.mojom.FetchRequestMode.kNoCors; bool is_main_resource_load = false; - RequestContextType request_context_type = - RequestContextType.UNSPECIFIED; + RequestContextType request_context_type = RequestContextType.UNSPECIFIED; network.mojom.RequestContextFrameType frame_type = network.mojom.RequestContextFrameType.kNone; url.mojom.Url url; string method; map<string, string> headers; SerializedBlob? blob; - Referrer referrer; + Referrer? referrer; network.mojom.FetchCredentialsMode credentials_mode = network.mojom.FetchCredentialsMode.kOmit; - FetchCacheMode cache_mode = blink.mojom.FetchCacheMode.kDefault; + FetchCacheMode cache_mode = FetchCacheMode.kDefault; network.mojom.FetchRedirectMode redirect_mode = network.mojom.FetchRedirectMode.kFollow; string? integrity;
diff --git a/third_party/blink/public/platform/modules/fetch/fetch_api_request.typemap b/third_party/blink/public/platform/modules/fetch/fetch_api_request.typemap deleted file mode 100644 index 0be087a..0000000 --- a/third_party/blink/public/platform/modules/fetch/fetch_api_request.typemap +++ /dev/null
@@ -1,10 +0,0 @@ -# Copyright 2017 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -mojom = - "//third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom" -public_headers = [ "//third_party/blink/public/platform/modules/service_worker/web_service_worker_request.h" ] -traits_headers = [ "//third_party/blink/renderer/platform/mojo/fetch_api_request_struct_traits.h" ] -type_mappings = - [ "blink.mojom.FetchAPIRequest=::blink::WebServiceWorkerRequest" ]
diff --git a/third_party/blink/public/platform/modules/service_worker/web_service_worker_request.h b/third_party/blink/public/platform/modules/service_worker/web_service_worker_request.h index 30919c2b4..dfa9130 100644 --- a/third_party/blink/public/platform/modules/service_worker/web_service_worker_request.h +++ b/third_party/blink/public/platform/modules/service_worker/web_service_worker_request.h
@@ -34,6 +34,12 @@ class WebServiceWorkerRequestPrivate; // Represents a request for a web resource. +// +// Now this is used only to carry the request data of a fetch event dispatched +// towards a service worker, from //content across the boundary into Blink. +// TODO(crbug.com/879019): Remove this class once we make the following Mojo +// interface receive the fetch event directly inside Blink. +// - content.mojom.ServiceWorker class BLINK_PLATFORM_EXPORT WebServiceWorkerRequest { public: ~WebServiceWorkerRequest() { Reset(); }
diff --git a/third_party/blink/public/web/web_plugin.h b/third_party/blink/public/web/web_plugin.h index 7f36f0b69..017fa466 100644 --- a/third_party/blink/public/web/web_plugin.h +++ b/third_party/blink/public/web/web_plugin.h
@@ -105,7 +105,7 @@ virtual bool CanProcessDrag() const { return false; } - virtual void UpdateAllLifecyclePhases() = 0; + virtual void UpdateAllLifecyclePhases(WebWidget::LifecycleUpdateReason) = 0; virtual void Paint(cc::PaintCanvas*, const WebRect&) = 0; // Coordinates are relative to the containing window.
diff --git a/third_party/blink/public/web/web_widget.h b/third_party/blink/public/web/web_widget.h index c4f07a8..ba20f61 100644 --- a/third_party/blink/public/web/web_widget.h +++ b/third_party/blink/public/web/web_widget.h
@@ -104,15 +104,23 @@ // Called to run through the entire set of document lifecycle phases needed // to render a frame of the web widget. This MUST be called before Paint, - // and it may result in calls to WebWidgetClient::didInvalidateRect. - virtual void UpdateAllLifecyclePhases() { UpdateLifecycle(); } - - // By default, all phases are updated by |UpdateLifecycle| (e.g., style, - // layout, prepaint, paint, etc. See: document_lifecycle.h). |LifecycleUpdate| - // can be used to only update to a specific lifecycle phase. + // and it may result in calls to WebWidgetClient::DidInvalidateRect. + // |LifecycleUpdateReason| must be used to indicate the source of the + // update for the purposes of metrics gathering. enum class LifecycleUpdate { kLayout, kPrePaint, kAll }; - virtual void UpdateLifecycle( - LifecycleUpdate requested_update = LifecycleUpdate::kAll) {} + // This must be kept coordinated with DocumentLifecycle::LifecycleUpdateReason + enum class LifecycleUpdateReason { kBeginMainFrame, kTest, kOther }; + virtual void UpdateAllLifecyclePhases(LifecycleUpdateReason reason) { + UpdateLifecycle(LifecycleUpdate::kAll, reason); + } + + // UpdateLifecycle is used to update to a specific lifestyle phase, as given + // by |LifecycleUpdate|. To update all lifecycle phases, use + // UpdateAllLifecyclePhases. + // |LifecycleUpdateReason| must be used to indicate the source of the + // update for the purposes of metrics gathering. + virtual void UpdateLifecycle(LifecycleUpdate requested_update, + LifecycleUpdateReason reason) {} // Synchronously performs the complete set of document lifecycle phases, // including updates to the compositor state, optionally including
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.cc b/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.cc index b4cc23f..ad8376e8c 100644 --- a/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.cc +++ b/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.cc
@@ -755,6 +755,18 @@ return frame->WindowProxy(world)->ContextIfInitialized(); } +ScriptState* ToScriptState(ExecutionContext* context, DOMWrapperWorld& world) { + DCHECK(context); + if (auto* document = DynamicTo<Document>(context)) { + if (LocalFrame* frame = document->GetFrame()) + return ToScriptState(frame, world); + } else if (auto* scope = DynamicTo<WorkerOrWorkletGlobalScope>(context)) { + if (WorkerOrWorkletScriptController* script = scope->ScriptController()) + return script->GetScriptState(); + } + return nullptr; +} + ScriptState* ToScriptState(LocalFrame* frame, DOMWrapperWorld& world) { v8::HandleScope handle_scope(ToIsolate(frame)); return ToScriptStateImpl(frame, world);
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h b/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h index db89c04..508fa8c2 100644 --- a/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h +++ b/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h
@@ -466,6 +466,7 @@ // These methods can return nullptr if the context associated with the // ScriptState has already been detached. +CORE_EXPORT ScriptState* ToScriptState(ExecutionContext*, DOMWrapperWorld&); CORE_EXPORT ScriptState* ToScriptState(LocalFrame*, DOMWrapperWorld&); // Do not use this method unless you are sure you should use the main world's // ScriptState
diff --git a/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc b/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc index 5ebe8290..8ede0bd4 100644 --- a/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc +++ b/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc
@@ -332,7 +332,7 @@ return false; } if (sanitize_script_errors == SanitizeScriptErrors::kSanitize) { - *error_event = ErrorEvent::CreateSanitizedError(world_.get()); + *error_event = ErrorEvent::CreateSanitizedError(script_state_); } else { *error_event = ErrorEvent::Create(state.error_message, state.location_->Clone(), @@ -379,11 +379,10 @@ void WorkerOrWorkletScriptController::RethrowExceptionFromImportedScript( ErrorEvent* error_event, ExceptionState& exception_state) { - const String& error_message = error_event->message(); if (execution_state_) execution_state_->error_event_from_imported_script_ = error_event; exception_state.RethrowV8Exception( - V8ThrowException::CreateError(isolate_, error_message)); + error_event->error(script_state_).V8ValueFor(script_state_)); } void WorkerOrWorkletScriptController::Trace(blink::Visitor* visitor) {
diff --git a/third_party/blink/renderer/core/animation/compositor_animations_test.cc b/third_party/blink/renderer/core/animation/compositor_animations_test.cc index a0ec393..0f31c2ae 100644 --- a/third_party/blink/renderer/core/animation/compositor_animations_test.cc +++ b/third_party/blink/renderer/core/animation/compositor_animations_test.cc
@@ -458,7 +458,8 @@ } void ForceFullCompositingUpdate() { - helper_.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + helper_.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); } private:
diff --git a/third_party/blink/renderer/core/css/css_paint_value_test.cc b/third_party/blink/renderer/core/css/css_paint_value_test.cc index 17ad7ed9..bca3c18 100644 --- a/third_party/blink/renderer/core/css/css_paint_value_test.cc +++ b/third_party/blink/renderer/core/css/css_paint_value_test.cc
@@ -33,7 +33,8 @@ } void ForceFullCompositingUpdate() { - helper_.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + helper_.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); } LocalFrame* GetFrame() const { return helper_.LocalMainFrame()->GetFrame(); }
diff --git a/third_party/blink/renderer/core/css/drag_update_test.cc b/third_party/blink/renderer/core/css/drag_update_test.cc index b34d15f..54682f3 100644 --- a/third_party/blink/renderer/core/css/drag_update_test.cc +++ b/third_party/blink/renderer/core/css/drag_update_test.cc
@@ -30,11 +30,13 @@ </div> )HTML"); - document.View()->UpdateAllLifecyclePhases(); + document.View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); unsigned start_count = document.GetStyleEngine().StyleForElementCount(); document.getElementById("div")->SetDragged(true); - document.View()->UpdateAllLifecyclePhases(); + document.View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); unsigned element_count = document.GetStyleEngine().StyleForElementCount() - start_count;
diff --git a/third_party/blink/renderer/core/css/invalidation/pending_invalidations_test.cc b/third_party/blink/renderer/core/css/invalidation/pending_invalidations_test.cc index afd1968a..d67db7cc 100644 --- a/third_party/blink/renderer/core/css/invalidation/pending_invalidations_test.cc +++ b/third_party/blink/renderer/core/css/invalidation/pending_invalidations_test.cc
@@ -33,7 +33,8 @@ TEST_F(PendingInvalidationsTest, ScheduleOnDocumentNode) { GetDocument().body()->SetInnerHTMLFromString( "<div id='d'></div><i id='i'></i><span></span>"); - GetDocument().View()->UpdateAllLifecyclePhases(); + GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); unsigned before_count = GetStyleEngine().StyleForElementCount(); @@ -57,7 +58,8 @@ EXPECT_FALSE(GetDocument().NeedsStyleRecalc()); EXPECT_TRUE(GetDocument().ChildNeedsStyleRecalc()); - GetDocument().View()->UpdateAllLifecyclePhases(); + GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); unsigned after_count = GetStyleEngine().StyleForElementCount(); EXPECT_EQ(2u, after_count - before_count); }
diff --git a/third_party/blink/renderer/core/css/parser/css_parser_local_context.cc b/third_party/blink/renderer/core/css/parser/css_parser_local_context.cc index 9639726f..6ac76945 100644 --- a/third_party/blink/renderer/core/css/parser/css_parser_local_context.cc +++ b/third_party/blink/renderer/core/css/parser/css_parser_local_context.cc
@@ -7,7 +7,10 @@ namespace blink { CSSParserLocalContext::CSSParserLocalContext() - : use_alias_parsing_(false), current_shorthand_(CSSPropertyInvalid) {} + : use_alias_parsing_(false), + is_animation_tainted_(false), + current_shorthand_(CSSPropertyInvalid), + variable_mode_(VariableMode::kTyped) {} CSSParserLocalContext CSSParserLocalContext::WithAliasParsing( bool use_alias_parsing) const { @@ -16,6 +19,13 @@ return context; } +CSSParserLocalContext CSSParserLocalContext::WithAnimationTainted( + bool is_animation_tainted) const { + CSSParserLocalContext context = *this; + context.is_animation_tainted_ = is_animation_tainted; + return context; +} + CSSParserLocalContext CSSParserLocalContext::WithCurrentShorthand( CSSPropertyID current_shorthand) const { CSSParserLocalContext context = *this; @@ -23,12 +33,28 @@ return context; } +CSSParserLocalContext CSSParserLocalContext::WithVariableMode( + VariableMode variable_mode) const { + CSSParserLocalContext context = *this; + context.variable_mode_ = variable_mode; + return context; +} + bool CSSParserLocalContext::UseAliasParsing() const { return use_alias_parsing_; } +bool CSSParserLocalContext::IsAnimationTainted() const { + return is_animation_tainted_; +} + CSSPropertyID CSSParserLocalContext::CurrentShorthand() const { return current_shorthand_; } +CSSParserLocalContext::VariableMode CSSParserLocalContext::GetVariableMode() + const { + return variable_mode_; +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/css/parser/css_parser_local_context.h b/third_party/blink/renderer/core/css/parser/css_parser_local_context.h index 7b56cc2..d5de80e 100644 --- a/third_party/blink/renderer/core/css/parser/css_parser_local_context.h +++ b/third_party/blink/renderer/core/css/parser/css_parser_local_context.h
@@ -18,15 +18,43 @@ public: CSSParserLocalContext(); + // When parsing registered custom properties, a different result is required + // depending on the context. + enum class VariableMode { + // The custom property is parsed according to the registered syntax (if + // available). + kTyped, + // The registration of the custom property (if any) is ignored; the custom + // property will parse as if unregistered. + kUntyped, + // The custom property will be parsed as if unregistered (that is, + // a CSSCustomPropertyDeclaration will be returned), but the tokens must + // also match the registered syntax (if any). This is useful for CSSOM, + // where incoming values must validate against the registered syntax, but + // are otherwise treated as unregistered. + kValidatedUntyped + }; + CSSParserLocalContext WithAliasParsing(bool) const; + CSSParserLocalContext WithAnimationTainted(bool) const; CSSParserLocalContext WithCurrentShorthand(CSSPropertyID) const; + CSSParserLocalContext WithVariableMode(VariableMode) const; bool UseAliasParsing() const; + // Any custom property used in a @keyframes rule becomes animation-tainted, + // which prevents the custom property from being substituted into the + // 'animation' property, or one of its longhands. + // + // https://drafts.csswg.org/css-variables/#animation-tainted + bool IsAnimationTainted() const; CSSPropertyID CurrentShorthand() const; + VariableMode GetVariableMode() const; private: bool use_alias_parsing_; + bool is_animation_tainted_; CSSPropertyID current_shorthand_; + VariableMode variable_mode_; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/css/parser/css_parser_local_context_test.cc b/third_party/blink/renderer/core/css/parser/css_parser_local_context_test.cc index 245e4b4b..4fbcac6 100644 --- a/third_party/blink/renderer/core/css/parser/css_parser_local_context_test.cc +++ b/third_party/blink/renderer/core/css/parser/css_parser_local_context_test.cc
@@ -8,9 +8,13 @@ namespace blink { +using VariableMode = CSSParserLocalContext::VariableMode; + TEST(CSSParserLocalContextTest, Constructor) { EXPECT_FALSE(CSSParserLocalContext().UseAliasParsing()); + EXPECT_FALSE(CSSParserLocalContext().IsAnimationTainted()); EXPECT_EQ(CSSPropertyInvalid, CSSParserLocalContext().CurrentShorthand()); + EXPECT_EQ(VariableMode::kTyped, CSSParserLocalContext().GetVariableMode()); } TEST(CSSParserLocalContextTest, WithAliasParsing) { @@ -19,6 +23,12 @@ EXPECT_TRUE(context.WithAliasParsing(true).UseAliasParsing()); } +TEST(CSSParserLocalContextTest, WithAnimationTainted) { + const CSSParserLocalContext context; + EXPECT_FALSE(context.WithAnimationTainted(false).IsAnimationTainted()); + EXPECT_TRUE(context.WithAnimationTainted(true).IsAnimationTainted()); +} + TEST(CSSParserLocalContextTest, WithCurrentShorthand) { const CSSParserLocalContext context; const CSSPropertyID shorthand = CSSPropertyBackground; @@ -26,18 +36,54 @@ context.WithCurrentShorthand(shorthand).CurrentShorthand()); } +TEST(CSSParserLocalContextTest, WithVariableMode) { + auto mode = VariableMode::kUntyped; + auto context = CSSParserLocalContext().WithVariableMode(mode); + EXPECT_EQ(mode, context.GetVariableMode()); +} + TEST(CSSParserLocalContextTest, LocalMutation) { CSSParserLocalContext context; context = context.WithAliasParsing(true); + context = context.WithAnimationTainted(true); context = context.WithCurrentShorthand(CSSPropertyBackground); + context = context.WithVariableMode(VariableMode::kUntyped); // WithAliasParsing only changes that member. - EXPECT_EQ(CSSPropertyBackground, - context.WithAliasParsing(false).CurrentShorthand()); + { + auto local_context = context.WithAliasParsing(false); + EXPECT_FALSE(local_context.UseAliasParsing()); + EXPECT_EQ(CSSPropertyBackground, local_context.CurrentShorthand()); + EXPECT_TRUE(local_context.IsAnimationTainted()); + EXPECT_EQ(VariableMode::kUntyped, local_context.GetVariableMode()); + } + + // WithAnimationTainted only changes that member. + { + auto local_context = context.WithAnimationTainted(false); + EXPECT_TRUE(local_context.UseAliasParsing()); + EXPECT_EQ(CSSPropertyBackground, local_context.CurrentShorthand()); + EXPECT_FALSE(local_context.IsAnimationTainted()); + EXPECT_EQ(VariableMode::kUntyped, local_context.GetVariableMode()); + } // WithCurrentShorthand only changes that member. - EXPECT_TRUE( - context.WithCurrentShorthand(CSSPropertyInvalid).UseAliasParsing()); + { + auto local_context = context.WithCurrentShorthand(CSSPropertyPadding); + EXPECT_TRUE(local_context.UseAliasParsing()); + EXPECT_EQ(CSSPropertyPadding, local_context.CurrentShorthand()); + EXPECT_TRUE(local_context.IsAnimationTainted()); + EXPECT_EQ(VariableMode::kUntyped, local_context.GetVariableMode()); + } + + // WithVariableMode only changes that member. + { + auto local_context = context.WithVariableMode(VariableMode::kTyped); + EXPECT_TRUE(local_context.UseAliasParsing()); + EXPECT_EQ(CSSPropertyBackground, local_context.CurrentShorthand()); + EXPECT_TRUE(local_context.IsAnimationTainted()); + EXPECT_EQ(VariableMode::kTyped, local_context.GetVariableMode()); + } } } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/custom_property.cc b/third_party/blink/renderer/core/css/properties/longhands/custom_property.cc index 4970e90..f139d170 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/custom_property.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/custom_property.cc
@@ -5,6 +5,8 @@ #include "third_party/blink/renderer/core/css/properties/longhands/custom_property.h" #include "third_party/blink/renderer/core/css/css_custom_property_declaration.h" +#include "third_party/blink/renderer/core/css/parser/css_parser_local_context.h" +#include "third_party/blink/renderer/core/css/parser/css_variable_parser.h" #include "third_party/blink/renderer/core/css/property_registration.h" #include "third_party/blink/renderer/core/css/property_registry.h" #include "third_party/blink/renderer/core/style/computed_style.h" @@ -80,6 +82,24 @@ } } +const CSSValue* CustomProperty::ParseSingleValue( + CSSParserTokenRange& range, + const CSSParserContext& context, + const CSSParserLocalContext& local_context) const { + using VariableMode = CSSParserLocalContext::VariableMode; + + switch (local_context.GetVariableMode()) { + case VariableMode::kTyped: + return ParseTyped(range, context, local_context); + case VariableMode::kUntyped: + return ParseUntyped(range, context, local_context); + case VariableMode::kValidatedUntyped: + if (registration_ && !ParseTyped(range, context, local_context)) + return nullptr; + return ParseUntyped(range, context, local_context); + } +} + const CSSValue* CustomProperty::CSSValueFromComputedStyleInternal( const ComputedStyle& style, const SVGComputedStyle&, @@ -103,4 +123,22 @@ return CSSCustomPropertyDeclaration::Create(name_, data); } +const CSSValue* CustomProperty::ParseUntyped( + CSSParserTokenRange range, + const CSSParserContext& context, + const CSSParserLocalContext& local_context) const { + return CSSVariableParser::ParseDeclarationValue( + name_, range, local_context.IsAnimationTainted(), context); +} + +const CSSValue* CustomProperty::ParseTyped( + CSSParserTokenRange range, + const CSSParserContext& context, + const CSSParserLocalContext& local_context) const { + if (!registration_) + return ParseUntyped(range, context, local_context); + return registration_->Syntax().Parse(range, &context, + local_context.IsAnimationTainted()); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/css/properties/longhands/custom_property.h b/third_party/blink/renderer/core/css/properties/longhands/custom_property.h index cd5fff3..57a2f0f 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/custom_property.h +++ b/third_party/blink/renderer/core/css/properties/longhands/custom_property.h
@@ -35,6 +35,10 @@ void ApplyInherit(StyleResolverState&) const override; void ApplyValue(StyleResolverState&, const CSSValue&) const override; + const CSSValue* ParseSingleValue(CSSParserTokenRange&, + const CSSParserContext&, + const CSSParserLocalContext&) const override; + const CSSValue* CSSValueFromComputedStyleInternal( const ComputedStyle&, const SVGComputedStyle&, @@ -45,6 +49,13 @@ void Trace(blink::Visitor* visitor) { visitor->Trace(registration_); } private: + const CSSValue* ParseUntyped(CSSParserTokenRange, + const CSSParserContext&, + const CSSParserLocalContext&) const; + const CSSValue* ParseTyped(CSSParserTokenRange, + const CSSParserContext&, + const CSSParserLocalContext&) const; + AtomicString name_; Member<const PropertyRegistration> registration_; };
diff --git a/third_party/blink/renderer/core/css/properties/longhands/custom_property_test.cc b/third_party/blink/renderer/core/css/properties/longhands/custom_property_test.cc index f27b9387..9224db4 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/custom_property_test.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/custom_property_test.cc
@@ -7,6 +7,8 @@ #include "third_party/blink/renderer/core/css/css_custom_property_declaration.h" #include "third_party/blink/renderer/core/css/css_primitive_value.h" #include "third_party/blink/renderer/core/css/css_test_helpers.h" +#include "third_party/blink/renderer/core/css/parser/css_parser_local_context.h" +#include "third_party/blink/renderer/core/css/parser/css_tokenizer.h" #include "third_party/blink/renderer/core/dom/node_computed_style.h" #include "third_party/blink/renderer/core/html/html_element.h" #include "third_party/blink/renderer/core/testing/page_test_base.h" @@ -14,6 +16,7 @@ namespace blink { using namespace css_test_helpers; +using VariableMode = CSSParserLocalContext::VariableMode; namespace { @@ -31,6 +34,16 @@ nullptr /* layout_object*/, node, false /* allow_visisted_style */); } + + const CSSValue* ParseValue(const Longhand& property, + const String& value, + const CSSParserLocalContext& local_context) { + CSSTokenizer tokenizer(value); + const auto tokens = tokenizer.TokenizeToEOF(); + CSSParserTokenRange range(tokens); + CSSParserContext* context = CSSParserContext::Create(GetDocument()); + return property.ParseSingleValue(range, *context, local_context); + } }; } // namespace @@ -124,4 +137,61 @@ EXPECT_EQ("100px", value->CssText()); } +TEST_F(CustomPropertyTest, ParseSingleValueUnregistered) { + CustomProperty property("--x", GetDocument()); + const CSSValue* value = + ParseValue(property, "100px", CSSParserLocalContext()); + ASSERT_TRUE(value->IsCustomPropertyDeclaration()); + EXPECT_EQ("100px", value->CssText()); +} + +TEST_F(CustomPropertyTest, ParseSingleValueAnimationTainted) { + CustomProperty property("--x", GetDocument()); + const CSSValue* value1 = ParseValue( + property, "100px", CSSParserLocalContext().WithAnimationTainted(true)); + const CSSValue* value2 = ParseValue( + property, "100px", CSSParserLocalContext().WithAnimationTainted(false)); + + EXPECT_TRUE( + ToCSSCustomPropertyDeclaration(value1)->Value()->IsAnimationTainted()); + EXPECT_FALSE( + ToCSSCustomPropertyDeclaration(value2)->Value()->IsAnimationTainted()); +} + +TEST_F(CustomPropertyTest, ParseSingleValueTyped) { + RegisterProperty(GetDocument(), "--x", "<length>", "0px", false); + CustomProperty property("--x", GetDocument()); + const CSSValue* value1 = + ParseValue(property, "100px", CSSParserLocalContext()); + EXPECT_TRUE(value1->IsPrimitiveValue()); + EXPECT_EQ(100, ToCSSPrimitiveValue(value1)->GetIntValue()); + + const CSSValue* value2 = + ParseValue(property, "maroon", CSSParserLocalContext()); + EXPECT_FALSE(value2); +} + +TEST_F(CustomPropertyTest, ParseSingleValueUntyped) { + RegisterProperty(GetDocument(), "--x", "<length>", "0px", false); + CustomProperty property("--x", GetDocument()); + const CSSValue* value = ParseValue( + property, "maroon", + CSSParserLocalContext().WithVariableMode(VariableMode::kUntyped)); + ASSERT_TRUE(value->IsCustomPropertyDeclaration()); + EXPECT_EQ("maroon", value->CssText()); +} + +TEST_F(CustomPropertyTest, ParseSingleValueValidatedUntyped) { + RegisterProperty(GetDocument(), "--x", "<length>", "0px", false); + CustomProperty property("--x", GetDocument()); + auto local_context = + CSSParserLocalContext().WithVariableMode(VariableMode::kValidatedUntyped); + const CSSValue* value1 = ParseValue(property, "100px", local_context); + ASSERT_TRUE(value1->IsCustomPropertyDeclaration()); + EXPECT_EQ("100px", value1->CssText()); + + const CSSValue* value2 = ParseValue(property, "maroon", local_context); + EXPECT_FALSE(value2); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/css/style_engine_test.cc b/third_party/blink/renderer/core/css/style_engine_test.cc index 61b2a6a9..64dc76d 100644 --- a/third_party/blink/renderer/core/css/style_engine_test.cc +++ b/third_party/blink/renderer/core/css/style_engine_test.cc
@@ -58,7 +58,8 @@ // A wrapper to add a reason for UpdateAllLifecyclePhases void UpdateAllLifecyclePhases() { - GetDocument().View()->UpdateAllLifecyclePhases(); + GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); } private: @@ -1179,7 +1180,8 @@ frame_test_helpers::WebViewHelper web_view_helper; WebViewImpl* web_view_impl = web_view_helper.Initialize(nullptr, &client, nullptr, nullptr); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); + web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); Document* document = ToLocalFrame(web_view_impl->GetPage()->MainFrame())->GetDocument(); @@ -1192,7 +1194,8 @@ const float device_scale = 3.5f; client.set_device_scale_factor(device_scale); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); + web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); desc = document->GetViewportData().GetViewportDescription(); EXPECT_FLOAT_EQ(device_scale * min_width, desc.min_width.GetFloatValue()); @@ -1654,7 +1657,8 @@ <div></div> <div> <!-- --></div> )HTML"); - GetDocument().View()->UpdateAllLifecyclePhases(); + GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); EXPECT_FALSE(UseCounter::IsCounted( GetDocument(), WebFeature::kCSSSelectorEmptyWhitespaceOnlyFail)); @@ -1665,7 +1669,8 @@ auto is_counted = [](Element* element) { element->setAttribute(blink::html_names::kClassAttr, "match"); - element->GetDocument().View()->UpdateAllLifecyclePhases(); + element->GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); return UseCounter::IsCounted( element->GetDocument(), WebFeature::kCSSSelectorEmptyWhitespaceOnlyFail);
diff --git a/third_party/blink/renderer/core/css/style_environment_variables_test.cc b/third_party/blink/renderer/core/css/style_environment_variables_test.cc index 66da5b0..1979b42 100644 --- a/third_party/blink/renderer/core/css/style_environment_variables_test.cc +++ b/third_party/blink/renderer/core/css/style_environment_variables_test.cc
@@ -56,7 +56,8 @@ void InitializeWithHTML(LocalFrame& frame, const String& html_content) { // Sets the inner html and runs the document lifecycle. frame.GetDocument()->body()->SetInnerHTMLFromString(html_content); - frame.GetDocument()->View()->UpdateAllLifecyclePhases(); + frame.GetDocument()->View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); } void InitializeTestPageWithVariableNamed(LocalFrame& frame, @@ -239,7 +240,8 @@ // Create an empty page that does not use the variable. std::unique_ptr<DummyPageHolder> empty_page = DummyPageHolder::Create(IntSize(800, 600)); - empty_page->GetDocument().View()->UpdateAllLifecyclePhases(); + empty_page->GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); StyleEnvironmentVariables::GetRootInstance().SetVariable(kVariableName, kVariableTestColor);
diff --git a/third_party/blink/renderer/core/dom/document_lifecycle.h b/third_party/blink/renderer/core/dom/document_lifecycle.h index 2cb5634b..5d02b28 100644 --- a/third_party/blink/renderer/core/dom/document_lifecycle.h +++ b/third_party/blink/renderer/core/dom/document_lifecycle.h
@@ -87,6 +87,9 @@ kStopped, }; + // This must be kept coordinated with WebWidget::LifecycleUpdateReason + enum LifecycleUpdateReason { kBeginMainFrame, kTest, kOther }; + class Scope { STACK_ALLOCATED();
diff --git a/third_party/blink/renderer/core/dom/element_test.cc b/third_party/blink/renderer/core/dom/element_test.cc index 7ef3ec06..8c5c190a 100644 --- a/third_party/blink/renderer/core/dom/element_test.cc +++ b/third_party/blink/renderer/core/dom/element_test.cc
@@ -24,7 +24,8 @@ Document& document = GetDocument(); DCHECK(IsHTMLHtmlElement(document.documentElement())); document.setDesignMode("on"); - document.View()->UpdateAllLifecyclePhases(); + document.View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); EXPECT_TRUE(document.documentElement()->SupportsFocus()) << "<html> with designMode=on should be focusable."; } @@ -217,7 +218,8 @@ // ensure that the sticky subtree update behavior survives forking. document.getElementById("child")->SetInlineStyleProperty( CSSPropertyWebkitRubyPosition, CSSValueAfter); - document.View()->UpdateAllLifecyclePhases(); + document.View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); EXPECT_EQ(DocumentLifecycle::kPaintClean, document.Lifecycle().GetState()); EXPECT_EQ(RubyPosition::kBefore, outer_sticky->StyleRef().GetRubyPosition()); @@ -239,7 +241,8 @@ // fork it's StyleRareInheritedData to maintain the sticky subtree bit. document.getElementById("outerSticky") ->SetInlineStyleProperty(CSSPropertyPosition, CSSValueStatic); - document.View()->UpdateAllLifecyclePhases(); + document.View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); EXPECT_EQ(DocumentLifecycle::kPaintClean, document.Lifecycle().GetState()); EXPECT_FALSE(outer_sticky->StyleRef().SubtreeIsSticky());
diff --git a/third_party/blink/renderer/core/editing/finder/text_finder_test.cc b/third_party/blink/renderer/core/editing/finder/text_finder_test.cc index 0f3a1d06..824e310 100644 --- a/third_party/blink/renderer/core/editing/finder/text_finder_test.cc +++ b/third_party/blink/renderer/core/editing/finder/text_finder_test.cc
@@ -35,7 +35,8 @@ web_view_helper_.Initialize(); WebLocalFrameImpl& frame_impl = *web_view_helper_.LocalMainFrame(); frame_impl.ViewImpl()->Resize(WebSize(640, 480)); - frame_impl.ViewImpl()->MainFrameWidget()->UpdateAllLifecyclePhases(); + frame_impl.ViewImpl()->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); document_ = static_cast<Document*>(frame_impl.GetDocument()); text_finder_ = &frame_impl.EnsureTextFinder(); }
diff --git a/third_party/blink/renderer/core/editing/serializers/markup_formatter.cc b/third_party/blink/renderer/core/editing/serializers/markup_formatter.cc index 63c365f1..298c557 100644 --- a/third_party/blink/renderer/core/editing/serializers/markup_formatter.cc +++ b/third_party/blink/renderer/core/editing/serializers/markup_formatter.cc
@@ -354,8 +354,9 @@ Namespaces* namespaces) { bool document_is_html = SerializeAsHTMLDocument(element); - QualifiedName prefixed_name = attribute.GetName(); if (document_is_html) { + // https://html.spec.whatwg.org/multipage/parsing.html#attribute's-serialised-name + QualifiedName prefixed_name = attribute.GetName(); if (attribute.NamespaceURI() == xmlns_names::kNamespaceURI) { if (!attribute.Prefix() && attribute.LocalName() != g_xmlns_atom) prefixed_name.SetPrefix(g_xmlns_atom); @@ -367,49 +368,76 @@ result.Append(' '); result.Append(prefixed_name.ToString()); } else { - if (attribute.NamespaceURI() == xmlns_names::kNamespaceURI) { + // https://w3c.github.io/DOM-Parsing/#serializing-an-element-s-attributes + + // 3.3. Let attribute namespace be the value of attr's namespaceURI value. + const AtomicString& attribute_namespace = attribute.NamespaceURI(); + + // 3.4. Let candidate prefix be null. + AtomicString candidate_prefix; + + // 3.5. If attribute namespace is not null, then run these sub-steps: + + // 3.5.1. Let candidate prefix be the result of retrieving a preferred + // prefix string from map given namespace attribute namespace with preferred + // prefix being attr's prefix value. + // TODO(tkent): Implement it. crbug.com/906807 + candidate_prefix = attribute.Prefix(); + + // 3.5.2. If the value of attribute namespace is the XMLNS namespace, then + // run these steps: + if (attribute_namespace == xmlns_names::kNamespaceURI) { if (!attribute.Prefix() && attribute.LocalName() != g_xmlns_atom) - prefixed_name.SetPrefix(g_xmlns_atom); + candidate_prefix = g_xmlns_atom; // Account for the namespace attribute we're about to append. if (namespaces) { const AtomicString& lookup_key = (!attribute.Prefix()) ? g_empty_atom : attribute.LocalName(); namespaces->Set(lookup_key, attribute.Value()); } - } else if (attribute.NamespaceURI() == xml_names::kNamespaceURI) { - if (!attribute.Prefix()) - prefixed_name.SetPrefix(g_xml_atom); + } else if (attribute_namespace == xml_names::kNamespaceURI) { + if (!candidate_prefix) + candidate_prefix = g_xml_atom; } else { - if (attribute.NamespaceURI() == xlink_names::kNamespaceURI) { - if (!attribute.Prefix()) - prefixed_name.SetPrefix(g_xlink_atom); + if (attribute_namespace == xlink_names::kNamespaceURI) { + if (!candidate_prefix) + candidate_prefix = g_xlink_atom; } + // 3.5.3. Otherwise, the attribute namespace in not the XMLNS namespace. + // Run these steps: if (namespaces && ShouldAddNamespaceAttribute(attribute, element)) { - if (!prefixed_name.Prefix()) { + if (!candidate_prefix) { // This behavior is in process of being standardized. See // crbug.com/248044 and // https://www.w3.org/Bugs/Public/show_bug.cgi?id=24208 String prefix_prefix("ns", 2u); - for (unsigned i = attribute.NamespaceURI().Impl()->ExistingHash();; - ++i) { + for (unsigned i = attribute_namespace.Impl()->ExistingHash();; ++i) { AtomicString new_prefix(String(prefix_prefix + String::Number(i))); AtomicString found_uri = namespaces->at(new_prefix); - if (found_uri == attribute.NamespaceURI() || - found_uri == g_null_atom) { + if (found_uri == attribute_namespace || found_uri == g_null_atom) { // We already generated a prefix for this namespace. - prefixed_name.SetPrefix(new_prefix); + candidate_prefix = new_prefix; break; } } } - DCHECK(prefixed_name.Prefix()); - AppendNamespace(result, prefixed_name.Prefix(), - attribute.NamespaceURI(), *namespaces); + // 3.5.3.2. Append the following to result, in the order listed: + DCHECK(candidate_prefix); + AppendNamespace(result, candidate_prefix, attribute_namespace, + *namespaces); } } + // 3.6. Append a " " (U+0020 SPACE) to result. result.Append(' '); - result.Append(prefixed_name.ToString()); + // 3.7. If candidate prefix is not null, then append to result the + // concatenation of candidate prefix with ":" (U+003A COLON). + if (candidate_prefix) { + result.Append(candidate_prefix); + result.Append(':'); + } + // 3.9.1. The value of attr's localName; + result.Append(attribute.LocalName()); } result.Append('=');
diff --git a/third_party/blink/renderer/core/editing/testing/editing_test_base.cc b/third_party/blink/renderer/core/editing/testing/editing_test_base.cc index 59c01b1..941df98 100644 --- a/third_party/blink/renderer/core/editing/testing/editing_test_base.cc +++ b/third_party/blink/renderer/core/editing/testing/editing_test_base.cc
@@ -100,7 +100,8 @@ ->CreateV0ShadowRootForTesting(); shadow_root.SetInnerHTMLFromString(String::FromUTF8(shadow_root_content), ASSERT_NO_EXCEPTION); - scope.GetDocument().View()->UpdateAllLifecyclePhases(); + scope.GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); return &shadow_root; }
diff --git a/third_party/blink/renderer/core/events/error_event.cc b/third_party/blink/renderer/core/events/error_event.cc index d842a49..c5980a14 100644 --- a/third_party/blink/renderer/core/events/error_event.cc +++ b/third_party/blink/renderer/core/events/error_event.cc
@@ -38,6 +38,16 @@ namespace blink { +ErrorEvent* ErrorEvent::CreateSanitizedError(ScriptState* script_state) { + // "6. If script's muted errors is true, then set message to "Script error.", + // urlString to the empty string, line and col to 0, and errorValue to null." + // https://html.spec.whatwg.org/multipage/webappapis.html#runtime-script-errors:muted-errors + DCHECK(script_state); + return MakeGarbageCollected<ErrorEvent>( + "Script error.", SourceLocation::Create(String(), 0, 0, nullptr), + ScriptValue::CreateNull(script_state), &script_state->World()); +} + ErrorEvent::ErrorEvent() : sanitized_message_(), location_(SourceLocation::Create(String(), 0, 0, nullptr)),
diff --git a/third_party/blink/renderer/core/events/error_event.h b/third_party/blink/renderer/core/events/error_event.h index 3bc38a29..8d1f966e 100644 --- a/third_party/blink/renderer/core/events/error_event.h +++ b/third_party/blink/renderer/core/events/error_event.h
@@ -67,11 +67,9 @@ const ErrorEventInit* initializer) { return MakeGarbageCollected<ErrorEvent>(script_state, type, initializer); } - static ErrorEvent* CreateSanitizedError(DOMWrapperWorld* world) { - return MakeGarbageCollected<ErrorEvent>( - "Script error.", SourceLocation::Create(String(), 0, 0, nullptr), - ScriptValue(), world); - } + + // Creates an error for a script whose errors are muted. + static ErrorEvent* CreateSanitizedError(ScriptState* script_state); ErrorEvent(); ErrorEvent(const String& message,
diff --git a/third_party/blink/renderer/core/events/web_input_event_conversion_test.cc b/third_party/blink/renderer/core/events/web_input_event_conversion_test.cc index 1529010..fabfea0 100644 --- a/third_party/blink/renderer/core/events/web_input_event_conversion_test.cc +++ b/third_party/blink/renderer/core/events/web_input_event_conversion_test.cc
@@ -124,7 +124,8 @@ int page_width = 640; int page_height = 480; web_view->Resize(WebSize(page_width, page_height)); - web_view->MainFrameWidget()->UpdateAllLifecyclePhases(); + web_view->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); web_view->SetPageScaleFactor(3); @@ -337,7 +338,8 @@ int page_width = 640; int page_height = 480; web_view->Resize(WebSize(page_width, page_height)); - web_view->MainFrameWidget()->UpdateAllLifecyclePhases(); + web_view->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); web_view->SetPageScaleFactor(2); web_view->MainFrameImpl()->SetInputEventsScaleForEmulation(1.5); @@ -593,7 +595,8 @@ int page_width = 640; int page_height = 480; web_view->Resize(WebSize(page_width, page_height)); - web_view->MainFrameWidget()->UpdateAllLifecyclePhases(); + web_view->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); LocalFrameView* view = ToLocalFrame(web_view->GetPage()->MainFrame())->View(); { @@ -630,7 +633,8 @@ int page_width = 640; int page_height = 480; web_view->Resize(WebSize(page_width, page_height)); - web_view->MainFrameWidget()->UpdateAllLifecyclePhases(); + web_view->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); web_view->SetPageScaleFactor(2); @@ -728,7 +732,8 @@ int page_width = 640; int page_height = 480; web_view->Resize(WebSize(page_width, page_height)); - web_view->MainFrameWidget()->UpdateAllLifecyclePhases(); + web_view->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); LocalFrameView* view = ToLocalFrame(web_view->GetPage()->MainFrame())->View(); @@ -803,7 +808,8 @@ int page_width = 640; int page_height = 480; web_view->Resize(WebSize(page_width, page_height)); - web_view->MainFrameWidget()->UpdateAllLifecyclePhases(); + web_view->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); gfx::Vector2dF elastic_overscroll(10, -20); web_view->ApplyViewportChanges(
diff --git a/third_party/blink/renderer/core/execution_context/execution_context.cc b/third_party/blink/renderer/core/execution_context/execution_context.cc index 9247e155..04f518b 100644 --- a/third_party/blink/renderer/core/execution_context/execution_context.cc +++ b/third_party/blink/renderer/core/execution_context/execution_context.cc
@@ -137,8 +137,10 @@ if (!target) return false; - if (sanitize_script_errors == SanitizeScriptErrors::kSanitize) - error_event = ErrorEvent::CreateSanitizedError(error_event->World()); + if (sanitize_script_errors == SanitizeScriptErrors::kSanitize) { + error_event = ErrorEvent::CreateSanitizedError( + ToScriptState(this, *error_event->World())); + } DCHECK(!in_dispatch_error_event_); in_dispatch_error_event_ = true;
diff --git a/third_party/blink/renderer/core/exported/web_frame_content_dumper.cc b/third_party/blink/renderer/core/exported/web_frame_content_dumper.cc index e5406061..867f81065 100644 --- a/third_party/blink/renderer/core/exported/web_frame_content_dumper.cc +++ b/third_party/blink/renderer/core/exported/web_frame_content_dumper.cc
@@ -232,7 +232,8 @@ if (!frame) return WebString(); - web_view->MainFrameWidget()->UpdateAllLifecyclePhases(); + web_view->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); StringBuilder text; FrameContentAsPlainText(max_chars, ToWebLocalFrameImpl(frame)->GetFrame(),
diff --git a/third_party/blink/renderer/core/exported/web_frame_serializer_sanitization_test.cc b/third_party/blink/renderer/core/exported/web_frame_serializer_sanitization_test.cc index 59f79b7..22f4dfe 100644 --- a/third_party/blink/renderer/core/exported/web_frame_serializer_sanitization_test.cc +++ b/third_party/blink/renderer/core/exported/web_frame_serializer_sanitization_test.cc
@@ -117,7 +117,8 @@ String file_path("frameserialization/" + file_name); RegisterMockedFileURLLoad(parsed_url, file_path, mime_type); frame_test_helpers::LoadFrame(MainFrameImpl(), url.Utf8().data()); - MainFrameImpl()->GetFrame()->View()->UpdateAllLifecyclePhases(); + MainFrameImpl()->GetFrame()->View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); } String GenerateMHTML(const bool only_body_parts) { @@ -171,7 +172,8 @@ shadow_root->SetDelegatesFocus(delegates_focus); shadow_root->SetInnerHTMLFromString(String::FromUTF8(shadow_content), ASSERT_NO_EXCEPTION); - scope.GetDocument().View()->UpdateAllLifecyclePhases(); + scope.GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); return shadow_root; }
diff --git a/third_party/blink/renderer/core/exported/web_frame_test.cc b/third_party/blink/renderer/core/exported/web_frame_test.cc index 46e5042..31c018f 100644 --- a/third_party/blink/renderer/core/exported/web_frame_test.cc +++ b/third_party/blink/renderer/core/exported/web_frame_test.cc
@@ -285,7 +285,8 @@ // Both sets the inner html and runs the document lifecycle. void InitializeWithHTML(LocalFrame& frame, const String& html_content) { frame.GetDocument()->body()->SetInnerHTMLFromString(html_content); - frame.GetDocument()->View()->UpdateAllLifecyclePhases(); + frame.GetDocument()->View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); } WebFrame* LastChild(WebFrame* frame) { return frame->last_child_; } @@ -335,6 +336,11 @@ return node_count; } + void UpdateAllLifecyclePhases(WebViewImpl* web_view) { + web_view->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); + } + static void GetElementAndCaretBoundsForFocusedEditableElement( frame_test_helpers::WebViewHelper& helper, IntRect& element_bounds, @@ -919,7 +925,8 @@ void ExecuteScript(const WebString& code) { frame_->ExecuteScript(WebScriptSource(code)); - frame_->View()->MainFrameWidget()->UpdateAllLifecyclePhases(); + frame_->View()->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); RunPendingTasks(); } @@ -942,7 +949,8 @@ Vector<WebString> selectors; selectors.push_back(WebString::FromUTF8("div.initial_on")); frame_->GetDocument().WatchCSSSelectors(WebVector<WebString>(selectors)); - frame_->View()->MainFrameWidget()->UpdateAllLifecyclePhases(); + frame_->View()->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); RunPendingTasks(); EXPECT_EQ(1, UpdateCount()); EXPECT_THAT(MatchedSelectors(), ElementsAre("div.initial_on")); @@ -950,7 +958,8 @@ // Check that adding a watched selector calls back for already-present nodes. selectors.push_back(WebString::FromUTF8("div.initial_off")); Doc().WatchCSSSelectors(WebVector<WebString>(selectors)); - frame_->View()->MainFrameWidget()->UpdateAllLifecyclePhases(); + frame_->View()->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); RunPendingTasks(); EXPECT_EQ(2, UpdateCount()); EXPECT_THAT(MatchedSelectors(), @@ -958,7 +967,8 @@ // Check that we can turn off callbacks for certain selectors. Doc().WatchCSSSelectors(WebVector<WebString>()); - frame_->View()->MainFrameWidget()->UpdateAllLifecyclePhases(); + frame_->View()->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); RunPendingTasks(); EXPECT_EQ(3, UpdateCount()); EXPECT_THAT(MatchedSelectors(), ElementsAre()); @@ -1075,7 +1085,8 @@ Vector<WebString> selectors(1u, WebString::FromUTF8("span")); Doc().WatchCSSSelectors(WebVector<WebString>(selectors)); - frame_->View()->MainFrameWidget()->UpdateAllLifecyclePhases(); + frame_->View()->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); RunPendingTasks(); EXPECT_EQ(1, UpdateCount()) << "Match elements in display:contents trees."; @@ -1110,7 +1121,8 @@ Vector<WebString> selectors; selectors.push_back(WebString::FromUTF8("span")); Doc().WatchCSSSelectors(WebVector<WebString>(selectors)); - frame_->View()->MainFrameWidget()->UpdateAllLifecyclePhases(); + frame_->View()->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); RunPendingTasks(); EXPECT_EQ(1, UpdateCount()); @@ -1134,7 +1146,8 @@ selectors.push_back(WebString::FromUTF8("span")); selectors.push_back(WebString::FromUTF8("span,p")); Doc().WatchCSSSelectors(WebVector<WebString>(selectors)); - frame_->View()->MainFrameWidget()->UpdateAllLifecyclePhases(); + frame_->View()->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); RunPendingTasks(); EXPECT_EQ(1, UpdateCount()); @@ -1150,7 +1163,8 @@ selectors.push_back(WebString::FromUTF8("[")); // Invalid. selectors.push_back(WebString::FromUTF8("p span")); // Not compound. Doc().WatchCSSSelectors(WebVector<WebString>(selectors)); - frame_->View()->MainFrameWidget()->UpdateAllLifecyclePhases(); + frame_->View()->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); RunPendingTasks(); EXPECT_EQ(1, UpdateCount()); @@ -1420,11 +1434,11 @@ // Device scale factor should be independent of page scale. web_view_helper.GetWebView()->SetDefaultPageScaleLimits(1, 2); web_view_helper.GetWebView()->SetPageScaleFactor(0.5); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); EXPECT_EQ(1, web_view_helper.GetWebView()->PageScaleFactor()); // Force the layout to happen before leaving the test. - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); } TEST_F(WebFrameTest, FixedLayoutInitializeAtMinimumScale) { @@ -1456,7 +1470,7 @@ float user_pinch_page_scale_factor = 2; web_view_helper.GetWebView()->SetPageScaleFactor( user_pinch_page_scale_factor); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); // Make sure we don't reset to initial scale if the page continues to load. web_view_helper.GetWebView()->DidCommitLoad(false, false); @@ -1498,7 +1512,7 @@ float user_pinch_page_scale_factor = 2; web_view_helper.GetWebView()->SetPageScaleFactor( user_pinch_page_scale_factor); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); // Make sure we don't reset to initial scale if the page continues to load. web_view_helper.GetWebView()->DidCommitLoad(false, false); @@ -1535,7 +1549,7 @@ ViewportDescription description = viewport.GetViewportDescription(); description.zoom = 2; viewport.SetViewportDescription(description); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); EXPECT_EQ(2, web_view_helper.GetWebView()->PageScaleFactor()); } @@ -1795,7 +1809,7 @@ web_view_helper.GetWebView()->GetSettings()->SetLoadWithOverviewMode(false); web_view_helper.GetWebView()->SetInitialPageScaleOverride( enforced_page_scale_factor); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); EXPECT_EQ(enforced_page_scale_factor, web_view_helper.GetWebView()->PageScaleFactor()); @@ -1808,7 +1822,7 @@ web_view_helper.GetWebView()->PageScaleFactor()); web_view_helper.GetWebView()->SetInitialPageScaleOverride(-1); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); EXPECT_EQ(1.0, web_view_helper.GetWebView()->PageScaleFactor()); } @@ -1960,7 +1974,7 @@ web_view_helper.InitializeAndLoad(base_url_ + "0-by-0.html", nullptr, &client, nullptr, ConfigureAndroid); web_view_helper.GetWebView()->GetSettings()->SetForceZeroLayoutHeight(true); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); PaintLayerCompositor* compositor = web_view_helper.GetWebView()->Compositor(); GraphicsLayer* scroll_container = compositor->RootGraphicsLayer(); @@ -2186,7 +2200,8 @@ LocalFrameView* frame_view = local_frame->GetFrameView(); frame_view->Resize(800, 600); frame_view->SetNeedsLayout(); - frame_view->UpdateAllLifecyclePhases(); + frame_view->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); // Expect scrollbars to be enabled by default. EXPECT_NE(nullptr, frame_view->LayoutViewport()->HorizontalScrollbar()); EXPECT_NE(nullptr, frame_view->LayoutViewport()->VerticalScrollbar()); @@ -2237,7 +2252,7 @@ frame_test_helpers::LoadFrame(web_view_helper.GetWebView()->MainFrameImpl(), base_url_ + "large-div.html"); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); EXPECT_EQ(0, web_view_helper.GetWebView() ->MainFrameImpl() @@ -2377,7 +2392,7 @@ description.min_width = Length(321, blink::kFixed); description.max_width = Length(321, blink::kFixed); viewport.SetViewportDescription(description); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); EXPECT_EQ(321, web_view_helper.GetWebView() ->MainFrameImpl() ->GetFrameView() @@ -2387,7 +2402,7 @@ description.min_width = Length(320, blink::kFixed); description.max_width = Length(320, blink::kFixed); viewport.SetViewportDescription(description); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); EXPECT_EQ(600, web_view_helper.GetWebView() ->MainFrameImpl() ->GetFrameView() @@ -2397,7 +2412,7 @@ description = viewport.GetViewportDescription(); description.max_height = Length(1000, blink::kFixed); viewport.SetViewportDescription(description); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); EXPECT_EQ(1000, web_view_helper.GetWebView() ->MainFrameImpl() ->GetFrameView() @@ -2406,7 +2421,7 @@ description.max_height = Length(320, blink::kFixed); viewport.SetViewportDescription(description); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); EXPECT_EQ(800, web_view_helper.GetWebView() ->MainFrameImpl() ->GetFrameView() @@ -2442,7 +2457,7 @@ EXPECT_EQ(1.0f, web_view_helper.GetWebView()->PageScaleFactor()); web_view_helper.GetWebView()->GetSettings()->SetUseWideViewport(true); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); EXPECT_EQ(viewport_width, web_view_helper.GetWebView() ->MainFrameImpl() ->GetFrameView() @@ -2546,7 +2561,7 @@ web_view_helper.GetWebView()->PageScaleFactor()); web_view_helper.GetWebView()->GetSettings()->SetUseWideViewport(true); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); EXPECT_EQ(viewport_width / expected_page_scale_factor, web_view_helper.GetWebView() ->MainFrameImpl() @@ -3240,9 +3255,7 @@ web_view_helper.GetWebView()->SetPageScaleFactor( initial_page_scale_factor); web_view_helper.LocalMainFrame()->SetScrollOffset(scroll_offset); - web_view_helper.GetWebView() - ->MainFrameWidget() - ->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); const WebSize expected_scroll_offset = web_view_helper.LocalMainFrame()->GetScrollOffset(); web_view_helper.Resize( @@ -3367,13 +3380,13 @@ EXPECT_EQ(2.0f, web_view_helper.GetWebView()->MaximumPageScaleFactor()); web_view_helper.GetWebView()->SetIgnoreViewportTagScaleLimits(true); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); EXPECT_EQ(1.0f, web_view_helper.GetWebView()->MinimumPageScaleFactor()); EXPECT_EQ(5.0f, web_view_helper.GetWebView()->MaximumPageScaleFactor()); web_view_helper.GetWebView()->SetIgnoreViewportTagScaleLimits(false); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); EXPECT_EQ(2.0f, web_view_helper.GetWebView()->MinimumPageScaleFactor()); EXPECT_EQ(2.0f, web_view_helper.GetWebView()->MaximumPageScaleFactor()); @@ -3402,7 +3415,7 @@ frame_test_helpers::LoadFrame(web_view_helper.GetWebView()->MainFrameImpl(), base_url_ + "large-div.html"); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); LocalFrameView* view = web_view_helper.LocalMainFrame()->GetFrameView(); EXPECT_TRUE(view->LayoutViewport()->LayerForHorizontalScrollbar()); EXPECT_TRUE(view->LayoutViewport()->LayerForVerticalScrollbar()); @@ -3417,7 +3430,8 @@ float scale) { web_view->SetPageScaleFactor(scale); web_view->MainFrameImpl()->SetScrollOffset(WebSize(scroll.x, scroll.y)); - web_view->MainFrameWidget()->UpdateAllLifecyclePhases(); + web_view->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); } void SimulatePageScale(WebViewImpl* web_view_impl, float& scale) { @@ -3528,7 +3542,7 @@ web_view_helper.Resize(WebSize(viewport_width, viewport_height)); web_view_helper.GetWebView()->SetDeviceScaleFactor(kDeviceScaleFactor); web_view_helper.GetWebView()->SetPageScaleFactor(1.0f); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); web_view_helper.GetWebView()->EnableFakePageScaleAnimationForTesting(true); @@ -3566,7 +3580,7 @@ web_view_helper.Resize(WebSize(viewport_width, viewport_height)); web_view_helper.GetWebView()->SetDeviceScaleFactor(kDeviceScaleFactor); web_view_helper.GetWebView()->SetPageScaleFactor(1.0f); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); WebRect div(200, 300, 400, 5000); gfx::Point point(div.x + 50, div.y + 3000); @@ -3597,7 +3611,7 @@ web_view_helper.GetWebView()->SetDeviceScaleFactor(kDeviceScaleFactor); web_view_helper.GetWebView()->SetPageScaleFactor(0.5f); web_view_helper.GetWebView()->SetMaximumLegibleScale(1.f); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); web_view_helper.GetWebView()->EnableFakePageScaleAnimationForTesting(true); @@ -3662,7 +3676,7 @@ web_view_helper.Resize(WebSize(viewport_width, viewport_height)); web_view_helper.GetWebView()->SetDeviceScaleFactor(1.5f); web_view_helper.GetWebView()->SetMaximumLegibleScale(1.f); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); web_view_helper.GetWebView()->EnableFakePageScaleAnimationForTesting(true); @@ -3673,7 +3687,7 @@ // Test double tap scale bounds. // minimumPageScale < doubleTapZoomAlreadyLegibleScale < 1 web_view_helper.GetWebView()->SetDefaultPageScaleLimits(0.5f, 4); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); float double_tap_zoom_already_legible_scale = web_view_helper.GetWebView()->MinimumPageScaleFactor() * double_tap_zoom_already_legible_ratio; @@ -3695,7 +3709,7 @@ cc::BrowserControlsState::kBoth}); // 1 < minimumPageScale < doubleTapZoomAlreadyLegibleScale web_view_helper.GetWebView()->SetDefaultPageScaleLimits(1.1f, 4); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); double_tap_zoom_already_legible_scale = web_view_helper.GetWebView()->MinimumPageScaleFactor() * double_tap_zoom_already_legible_ratio; @@ -3717,7 +3731,7 @@ cc::BrowserControlsState::kBoth}); // minimumPageScale < 1 < doubleTapZoomAlreadyLegibleScale web_view_helper.GetWebView()->SetDefaultPageScaleLimits(0.95f, 4); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); double_tap_zoom_already_legible_scale = web_view_helper.GetWebView()->MinimumPageScaleFactor() * double_tap_zoom_already_legible_ratio; @@ -3748,7 +3762,7 @@ web_view_helper.Resize(WebSize(viewport_width, viewport_height)); web_view_helper.GetWebView()->SetMaximumLegibleScale( maximum_legible_scale_factor); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); web_view_helper.GetWebView()->EnableFakePageScaleAnimationForTesting(true); web_view_helper.GetWebView() @@ -3772,7 +3786,7 @@ web_view_helper.GetWebView()->MinimumPageScaleFactor() * double_tap_zoom_already_legible_ratio; web_view_helper.GetWebView()->SetDefaultPageScaleLimits(0.5f, 4); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); SimulateDoubleTap(web_view_helper.GetWebView(), double_tap_point, scale); EXPECT_FLOAT_EQ(legible_scale, scale); SimulateDoubleTap(web_view_helper.GetWebView(), double_tap_point, scale); @@ -3788,7 +3802,7 @@ // 1 < maximumLegibleScaleFactor < minimumPageScale < // doubleTapZoomAlreadyLegibleScale web_view_helper.GetWebView()->SetDefaultPageScaleLimits(1.0f, 4); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); double_tap_zoom_already_legible_scale = web_view_helper.GetWebView()->MinimumPageScaleFactor() * double_tap_zoom_already_legible_ratio; @@ -3811,7 +3825,7 @@ // minimumPageScale < 1 < maximumLegibleScaleFactor < // doubleTapZoomAlreadyLegibleScale web_view_helper.GetWebView()->SetDefaultPageScaleLimits(0.95f, 4); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); double_tap_zoom_already_legible_scale = web_view_helper.GetWebView()->MinimumPageScaleFactor() * double_tap_zoom_already_legible_ratio; @@ -3834,7 +3848,7 @@ // minimumPageScale < 1 < doubleTapZoomAlreadyLegibleScale < // maximumLegibleScaleFactor web_view_helper.GetWebView()->SetDefaultPageScaleLimits(0.9f, 4); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); double_tap_zoom_already_legible_scale = web_view_helper.GetWebView()->MinimumPageScaleFactor() * double_tap_zoom_already_legible_ratio; @@ -3864,7 +3878,7 @@ nullptr, nullptr, ConfigureAndroid); web_view_helper.Resize(WebSize(viewport_width, viewport_height)); web_view_helper.GetWebView()->SetMaximumLegibleScale(1.f); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); web_view_helper.GetWebView()->EnableFakePageScaleAnimationForTesting(true); web_view_helper.GetWebView() @@ -3892,7 +3906,7 @@ web_view_helper.GetWebView()->MinimumPageScaleFactor() * double_tap_zoom_already_legible_ratio; web_view_helper.GetWebView()->SetDefaultPageScaleLimits(0.5f, 4); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); SimulateDoubleTap(web_view_helper.GetWebView(), double_tap_point, scale); EXPECT_FLOAT_EQ(legible_scale, scale); SimulateDoubleTap(web_view_helper.GetWebView(), double_tap_point, scale); @@ -3908,7 +3922,7 @@ // 1 < accessibilityFontScaleFactor < minimumPageScale < // doubleTapZoomAlreadyLegibleScale web_view_helper.GetWebView()->SetDefaultPageScaleLimits(1.0f, 4); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); double_tap_zoom_already_legible_scale = web_view_helper.GetWebView()->MinimumPageScaleFactor() * double_tap_zoom_already_legible_ratio; @@ -3931,7 +3945,7 @@ // minimumPageScale < 1 < accessibilityFontScaleFactor < // doubleTapZoomAlreadyLegibleScale web_view_helper.GetWebView()->SetDefaultPageScaleLimits(0.95f, 4); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); double_tap_zoom_already_legible_scale = web_view_helper.GetWebView()->MinimumPageScaleFactor() * double_tap_zoom_already_legible_ratio; @@ -3954,7 +3968,7 @@ // minimumPageScale < 1 < doubleTapZoomAlreadyLegibleScale < // accessibilityFontScaleFactor web_view_helper.GetWebView()->SetDefaultPageScaleLimits(0.9f, 4); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); double_tap_zoom_already_legible_scale = web_view_helper.GetWebView()->MinimumPageScaleFactor() * double_tap_zoom_already_legible_ratio; @@ -5108,7 +5122,7 @@ &frame_client); web_view_helper.Resize(WebSize(640, 480)); web_view_helper.GetWebView()->SetMaximumLegibleScale(1.f); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); RunPendingTasks(); // Note that the 'result 19' in the <select> element is not expected to @@ -6157,7 +6171,7 @@ web_view_helper.InitializeAndLoad(base_url_ + "smartclip.html"); WebLocalFrame* frame = web_view_helper.LocalMainFrame(); web_view_helper.Resize(WebSize(500, 500)); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); WebRect crop_rect(300, 125, 152, 50); frame->ExtractSmartClipData(crop_rect, clip_text, clip_html, clip_rect); EXPECT_STREQ(kExpectedClipText, clip_text.Utf8().c_str()); @@ -6194,7 +6208,7 @@ web_view_helper.InitializeAndLoad(base_url_ + "smartclip.html"); WebLocalFrame* frame = web_view_helper.LocalMainFrame(); web_view_helper.Resize(WebSize(500, 500)); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); web_view_helper.GetWebView()->SetPageScaleFactor(1.5); web_view_helper.GetWebView()->SetVisualViewportOffset( WebFloatPoint(167, 100)); @@ -6215,7 +6229,7 @@ "smartclip_user_select_none.html"); WebLocalFrame* frame = web_view_helper.LocalMainFrame(); web_view_helper.Resize(WebSize(500, 500)); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); WebRect crop_rect(0, 0, 100, 100); frame->ExtractSmartClipData(crop_rect, clip_text, clip_html, clip_rect); EXPECT_STREQ("", clip_text.Utf8().c_str()); @@ -6233,7 +6247,7 @@ "smartclip_reversed_positions.html"); WebLocalFrame* frame = web_view_helper.LocalMainFrame(); web_view_helper.Resize(WebSize(500, 500)); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); // Left upper corner of the rect will be end position in the DOM hierarchy. WebRect crop_rect(30, 110, 400, 250); // This should not still crash. See crbug.com/589082 for more details. @@ -6373,9 +6387,7 @@ web_view_helper_.GetWebView()->SetFocus(true); frame_test_helpers::LoadFrame( web_view_helper_.GetWebView()->MainFrameImpl(), base_url_ + test_file); - web_view_helper_.GetWebView() - ->MainFrameWidget() - ->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper_.GetWebView()); cc::LayerTreeHost* layer_tree_host = web_view_client_.layer_tree_view()->layer_tree_host(); @@ -6391,9 +6403,7 @@ web_view_helper_.GetWebView()->SetFocus(true); frame_test_helpers::LoadFrame( web_view_helper_.GetWebView()->MainFrameImpl(), base_url_ + test_file); - web_view_helper_.GetWebView() - ->MainFrameWidget() - ->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper_.GetWebView()); v8::HandleScope handle_scope(v8::Isolate::GetCurrent()); v8::Local<v8::Value> result = @@ -7971,7 +7981,7 @@ frame_test_helpers::LoadFrame(web_view_helper.GetWebView()->MainFrameImpl(), base_url_ + "non-scrollable.html"); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); PaintLayerCompositor* compositor = web_view_helper.GetWebView()->Compositor(); GraphicsLayer* scroll_layer = compositor->ScrollLayer(); ASSERT_TRUE(scroll_layer); @@ -7984,7 +7994,7 @@ // Call javascript to make the layer scrollable, and verify it. WebLocalFrameImpl* frame = web_view_helper.LocalMainFrame(); frame->ExecuteScript(WebScriptSource("allowScroll();")); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); scroll_layer = compositor->ScrollLayer(); cc_scroll_layer = scroll_layer->CcLayer(); @@ -8087,7 +8097,7 @@ frame_test_helpers::WebViewHelper web_view_helper; web_view_helper.InitializeAndLoad("about:blank"); web_view_helper.Resize(WebSize(200, 200)); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); LocalFrameView* frame_view = web_view_helper.LocalMainFrame()->GetFrameView(); EXPECT_EQ(IntRect(0, 0, 200, 200), frame_view->FrameRect()); @@ -8109,7 +8119,7 @@ web_view->ResizeWithBrowserControls(WebSize(100, 100), browser_controls_height, 0, false); web_view->SetPageScaleFactor(2.0f); - web_view->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); web_view->MainFrameImpl()->SetScrollOffset(WebSize(0, 2000)); EXPECT_EQ(ScrollOffset(0, 1900), @@ -8145,7 +8155,7 @@ 30.0f / browser_controls_height, cc::BrowserControlsState::kBoth}); web_view->ResizeWithBrowserControls(WebSize(100, 60), 40.0f, 0, true); - web_view->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); EXPECT_EQ(ScrollOffset(0, 1940), frame_view->LayoutViewport()->MaximumScrollOffset()); @@ -8163,7 +8173,7 @@ cc::BrowserControlsState::kBoth}); web_view->ResizeWithBrowserControls(WebSize(100, 100), browser_controls_height, 0, false); - web_view->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); EXPECT_EQ(ScrollOffset(0, 1900), frame_view->LayoutViewport()->MaximumScrollOffset()); @@ -8202,7 +8212,7 @@ web_view_helper.GetWebView()->GetSettings()->SetLoadWithOverviewMode(true); web_view_helper.GetWebView()->GetSettings()->SetUseWideViewport(true); web_view_helper.Resize(WebSize(viewport_width, viewport_height)); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); LocalFrameView* frame_view = web_view_helper.LocalMainFrame()->GetFrameView(); ScrollableArea* layout_viewport = frame_view->LayoutViewport(); @@ -8221,7 +8231,7 @@ base_url_ + "fullscreen_div.html", nullptr, &client, nullptr, ConfigureAndroid); web_view_helper.Resize(WebSize(viewport_width, viewport_height)); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_impl); LocalFrame* frame = web_view_impl->MainFrameImpl()->GetFrame(); Document* document = frame->GetDocument(); @@ -8232,7 +8242,7 @@ EXPECT_EQ(nullptr, Fullscreen::FullscreenElementFrom(*document)); web_view_impl->DidEnterFullscreen(); EXPECT_EQ(div_fullscreen, Fullscreen::FullscreenElementFrom(*document)); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_impl); EXPECT_EQ(div_fullscreen, Fullscreen::FullscreenElementFrom(*document)); // Verify that the element is sized to the viewport. @@ -8245,7 +8255,7 @@ client.screen_info_.rect.width = viewport_height; client.screen_info_.rect.height = viewport_width; web_view_helper.Resize(WebSize(viewport_height, viewport_width)); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_impl); EXPECT_EQ(viewport_height, fullscreen_layout_object->LogicalWidth().ToInt()); EXPECT_EQ(viewport_width, fullscreen_layout_object->LogicalHeight().ToInt()); } @@ -8260,7 +8270,7 @@ base_url_ + "fullscreen_div.html", nullptr, &client, nullptr, ConfigureAndroid); web_view_helper.Resize(WebSize(viewport_width, viewport_height)); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_impl); LocalFrame* frame = web_view_impl->MainFrameImpl()->GetFrame(); Document* document = frame->GetDocument(); @@ -8271,7 +8281,7 @@ EXPECT_EQ(nullptr, Fullscreen::FullscreenElementFrom(*document)); web_view_impl->DidEnterFullscreen(); EXPECT_EQ(div_fullscreen, Fullscreen::FullscreenElementFrom(*document)); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_impl); EXPECT_EQ(div_fullscreen, Fullscreen::FullscreenElementFrom(*document)); // Verify that the viewports are nonscrollable. @@ -8294,7 +8304,7 @@ EXPECT_EQ(div_fullscreen, Fullscreen::FullscreenElementFrom(*document)); web_view_impl->DidExitFullscreen(); EXPECT_EQ(nullptr, Fullscreen::FullscreenElementFrom(*document)); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_impl); EXPECT_EQ(nullptr, Fullscreen::FullscreenElementFrom(*document)); layout_viewport_scroll_layer = web_view_impl->Compositor()->ScrollLayer(); visual_viewport_scroll_layer = @@ -8319,7 +8329,7 @@ base_url_ + "fullscreen_div.html", nullptr, &client, nullptr, ConfigureAndroid); web_view_helper.Resize(WebSize(viewport_width, viewport_height)); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_impl); cc::Layer* cc_scroll_layer = web_view_impl->MainFrameImpl() ->GetFrame() @@ -8341,7 +8351,7 @@ EXPECT_EQ(document->documentElement(), Fullscreen::FullscreenElementFrom(*document)); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_impl); EXPECT_EQ(document->documentElement(), Fullscreen::FullscreenElementFrom(*document)); @@ -8376,7 +8386,7 @@ client.screen_info_.rect.width = viewport_width; client.screen_info_.rect.height = viewport_height; web_view_helper.Resize(WebSize(viewport_width, viewport_height)); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_impl); LocalFrame* frame = ToWebLocalFrameImpl( @@ -8388,7 +8398,7 @@ Element* div_fullscreen = document->getElementById("div1"); Fullscreen::RequestFullscreen(*div_fullscreen); web_view_impl->DidEnterFullscreen(); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_impl); // Verify that the element is sized to the viewport. LayoutBox* fullscreen_layout_object = @@ -8400,7 +8410,7 @@ client.screen_info_.rect.width = viewport_height; client.screen_info_.rect.height = viewport_width; web_view_helper.Resize(WebSize(viewport_height, viewport_width)); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_impl); EXPECT_EQ(viewport_height, fullscreen_layout_object->LogicalWidth().ToInt()); EXPECT_EQ(viewport_width, fullscreen_layout_object->LogicalHeight().ToInt()); } @@ -8414,7 +8424,7 @@ WebViewImpl* web_view_impl = web_view_helper.InitializeAndLoad(base_url_ + "fullscreen_iframe.html"); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_impl); Document* top_doc = web_view_impl->MainFrameImpl()->GetFrame()->GetDocument(); Element* top_body = top_doc->body(); @@ -8430,7 +8440,7 @@ Fullscreen::RequestFullscreen(*top_body); } web_view_impl->DidEnterFullscreen(); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_impl); { std::unique_ptr<UserGestureIndicator> gesture = @@ -8439,7 +8449,7 @@ } web_view_impl->DidEnterFullscreen(); Microtask::PerformCheckpoint(V8PerIsolateData::MainThreadIsolate()); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_impl); // We are now in nested fullscreen, with both documents having a non-empty // fullscreen element stack. @@ -8447,7 +8457,7 @@ EXPECT_EQ(iframe_body, Fullscreen::FullscreenElementFrom(*iframe_doc)); web_view_impl->DidExitFullscreen(); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_impl); // We should now have fully exited fullscreen. EXPECT_EQ(nullptr, Fullscreen::FullscreenElementFrom(*top_doc)); @@ -8466,7 +8476,7 @@ client.screen_info_.rect.width = viewport_width; client.screen_info_.rect.height = viewport_height; web_view_helper.Resize(WebSize(viewport_width, viewport_height)); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_impl); auto* layout_view = web_view_helper.GetWebView() ->MainFrameImpl() @@ -8483,7 +8493,7 @@ LocalFrame::NotifyUserActivation(frame); Fullscreen::RequestFullscreen(*frame->GetDocument()->documentElement()); web_view_impl->DidEnterFullscreen(); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_impl); EXPECT_EQ(384, layout_view->LogicalWidth().Floor()); EXPECT_EQ(640, layout_view->LogicalHeight().Floor()); EXPECT_FLOAT_EQ(1.0, web_view_impl->PageScaleFactor()); @@ -8491,7 +8501,7 @@ EXPECT_FLOAT_EQ(1.0, web_view_impl->MaximumPageScaleFactor()); web_view_impl->DidExitFullscreen(); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_impl); EXPECT_EQ(320, layout_view->LogicalWidth().Floor()); EXPECT_EQ(533, layout_view->LogicalHeight().Floor()); EXPECT_FLOAT_EQ(1.2, web_view_impl->PageScaleFactor()); @@ -8511,7 +8521,7 @@ client.screen_info_.rect.width = viewport_width; client.screen_info_.rect.height = viewport_height; web_view_helper.Resize(WebSize(viewport_width, viewport_height)); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_impl); auto* layout_view = web_view_helper.GetWebView() ->MainFrameImpl() @@ -8522,7 +8532,7 @@ LocalFrame::NotifyUserActivation(frame); Fullscreen::RequestFullscreen(*frame->GetDocument()->documentElement()); web_view_impl->DidEnterFullscreen(); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_impl); EXPECT_EQ(384, layout_view->LogicalWidth().Floor()); EXPECT_EQ(640, layout_view->LogicalHeight().Floor()); EXPECT_FLOAT_EQ(1.0, web_view_impl->PageScaleFactor()); @@ -8534,7 +8544,7 @@ client.screen_info_.rect.width = viewport_width; client.screen_info_.rect.height = viewport_height; web_view_helper.Resize(WebSize(viewport_width, viewport_height)); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_impl); EXPECT_EQ(640, layout_view->LogicalWidth().Floor()); EXPECT_EQ(384, layout_view->LogicalHeight().Floor()); EXPECT_FLOAT_EQ(1.0, web_view_impl->PageScaleFactor()); @@ -8542,7 +8552,7 @@ EXPECT_FLOAT_EQ(1.0, web_view_impl->MaximumPageScaleFactor()); web_view_impl->DidExitFullscreen(); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_impl); EXPECT_EQ(320, layout_view->LogicalWidth().Floor()); EXPECT_EQ(192, layout_view->LogicalHeight().Floor()); EXPECT_FLOAT_EQ(2, web_view_impl->PageScaleFactor()); @@ -8590,7 +8600,7 @@ } web_view_impl->DidEnterFullscreen(); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_impl); client.screen_info_.rect.width = screen_size_minus_status_bars.width; client.screen_info_.rect.height = screen_size_minus_status_bars.height; web_view_helper.Resize(screen_size_minus_status_bars); @@ -8604,7 +8614,7 @@ EXPECT_FLOAT_EQ(1.0, web_view_impl->MaximumPageScaleFactor()); web_view_impl->DidExitFullscreen(); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_impl); client.screen_info_.rect.width = screen_size_minus_status_bars.width; client.screen_info_.rect.height = screen_size_minus_status_bars.height; web_view_helper.Resize(screen_size_minus_status_bars); @@ -8635,7 +8645,7 @@ ConfigureAndroid); web_view_helper.Resize(WebSize(viewport_width, viewport_height)); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_impl); // viewport-tiny.html specifies a 320px layout width. auto* layout_view = @@ -8651,7 +8661,7 @@ LocalFrame::NotifyUserActivation(frame, UserGestureToken::kNewGesture); Fullscreen::RequestFullscreen(*frame->GetDocument()->documentElement()); web_view_impl->DidEnterFullscreen(); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_impl); // Entering fullscreen causes layout size and page scale limits to be // overridden. @@ -8668,7 +8678,7 @@ WebLocalFrame* web_frame = web_view_helper.LocalMainFrame(); frame_test_helpers::LoadHTMLString(web_frame, kSource, test_url); web_view_impl->DidExitFullscreen(); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_impl); // Make sure the new page's layout size and scale factor limits aren't // overridden. @@ -8701,12 +8711,12 @@ video->webkitEnterFullscreen(); web_view_impl->DidEnterFullscreen(); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_impl); EXPECT_TRUE(video->IsFullscreen()); EXPECT_LT(SkColorGetA(layer_tree_host->background_color()), SK_AlphaOPAQUE); web_view_impl->DidExitFullscreen(); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_impl); EXPECT_FALSE(video->IsFullscreen()); EXPECT_EQ(SkColorGetA(layer_tree_host->background_color()), SK_AlphaOPAQUE); } @@ -8719,7 +8729,7 @@ WebViewImpl* web_view = web_view_helper.GetWebView(); web_view_helper.Resize(WebSize(800, 800)); - web_view->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view); Document* document = web_view->MainFrameImpl()->GetFrame()->GetDocument(); LayoutBlock* container = @@ -9307,7 +9317,8 @@ event_registry.DidAddEventHandler( *child_document, EventHandlerRegistry::kTouchStartOrMoveEventBlocking); // Passes if this does not crash or DCHECK. - main_frame->View()->UpdateAllLifecyclePhases(); + main_frame->View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); } TEST_F(WebFrameSwapTest, EventsOnDisconnectedElementSkipped) { @@ -9334,7 +9345,8 @@ *child_document->body(), EventHandlerRegistry::kTouchStartOrMoveEventBlocking); // Passes if this does not crash or DCHECK. - main_frame->View()->UpdateAllLifecyclePhases(); + main_frame->View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); } TEST_F(WebFrameSwapTest, SwapParentShouldDetachChildren) { @@ -10745,7 +10757,8 @@ void ExecuteScriptOnMainFrame(const WebScriptSource& script) { MainFrame()->ExecuteScript(script); - MainFrame()->View()->MainFrameWidget()->UpdateAllLifecyclePhases(); + MainFrame()->View()->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); RunPendingTasks(); } @@ -10895,7 +10908,7 @@ SaveImageFromDataURLWebFrameClient client; WebViewImpl* web_view = helper.InitializeAndLoad(url, &client); web_view->Resize(WebSize(400, 400)); - web_view->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view); WebLocalFrame* local_frame = web_view->MainFrameImpl(); @@ -11180,7 +11193,7 @@ " }" "</style>" "<div id='elem'></div>"); - web_view->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view); Document* document = web_view->MainFrameImpl()->GetFrame()->GetDocument(); LocalFrameView* frame_view = web_view->MainFrameImpl()->GetFrameView(); @@ -11281,8 +11294,7 @@ " <div id='div2' title='Title Attribute Value'>Then HERE</div>" " <br><br><br>" "</body>"); - - web_view->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view); Document* document = web_view->MainFrameImpl()->GetFrame()->GetDocument(); Element* div1_tag = document->getElementById("div1"); @@ -11628,7 +11640,8 @@ canvas.scale(scale, scale); canvas.translate(-zoom_rect.x, -zoom_rect.y); - WebView().MainFrameWidget()->UpdateAllLifecyclePhases(); + WebView().MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); WebView().PaintContentIgnoringCompositing(&canvas, zoom_rect); // All the pixels in the canvas should be the <div> color. @@ -12341,7 +12354,8 @@ frame_test_helpers::LoadHTMLString(web_view->MainFrameImpl(), html, ToKURL("about:blank")); web_view->Resize(WebSize(500, 300)); - web_view->MainFrameWidget()->UpdateAllLifecyclePhases(); + web_view->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); RunPendingTasks(); web_view->SetInitialFocus(false); RunPendingTasks(); @@ -12377,7 +12391,7 @@ frame_test_helpers::LoadHTMLString(web_view->MainFrameImpl(), html, ToKURL("about:blank")); web_view->Resize(WebSize(500, 300)); - web_view->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view); RunPendingTasks(); web_view->SetInitialFocus(false); RunPendingTasks(); @@ -12405,7 +12419,7 @@ frame_test_helpers::LoadHTMLString(web_view->MainFrameImpl(), html, ToKURL("about:blank")); web_view->Resize(WebSize(500, 300)); - web_view->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view); RunPendingTasks(); web_view->SetInitialFocus(false); RunPendingTasks(); @@ -12438,7 +12452,7 @@ frame_test_helpers::LoadHTMLString(web_view->MainFrameImpl(), html, ToKURL("about:blank")); web_view->Resize(WebSize(500, 300)); - web_view->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view); RunPendingTasks(); web_view->SetInitialFocus(false); RunPendingTasks(); @@ -12551,7 +12565,7 @@ const char kSource[] = "<img id='foo' src='foo' alt='foo alt' width='200' height='200'>"; frame_test_helpers::LoadHTMLString(frame, kSource, ToKURL("about:blank")); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view_helper.GetWebView()); RunPendingTasks(); // Check LayoutText with alt text "foo alt" @@ -12650,7 +12664,7 @@ " <div id='forceScroll'></div>" "</div>"); - web_view->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view); Document* document = web_view->MainFrameImpl()->GetFrame()->GetDocument(); Element* scrollable = document->getElementById("scrollable"); @@ -12667,7 +12681,7 @@ // area using the DidScroll callback. EXPECT_EQ(ScrollOffset(), scrollable_area->GetScrollOffset()); cc_scroll_layer->SetScrollOffsetFromImplSide(gfx::ScrollOffset(0, 1)); - web_view->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(web_view); EXPECT_EQ(ScrollOffset(0, 1), scrollable_area->GetScrollOffset()); // Make the scrollable area non-scrollable. @@ -12818,7 +12832,8 @@ // Confirm that exiting fullscreen restores back to default values. WebView().DidExitFullscreen(); - WebView().MainFrameWidget()->UpdateAllLifecyclePhases(); + WebView().MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); EXPECT_EQ(0.5f, WebView().PageScaleFactor()); EXPECT_EQ(94, WebView().MainFrameImpl()->GetScrollOffset().width);
diff --git a/third_party/blink/renderer/core/exported/web_layer_test.cc b/third_party/blink/renderer/core/exported/web_layer_test.cc index dfc9fd51..0dee0be 100644 --- a/third_party/blink/renderer/core/exported/web_layer_test.cc +++ b/third_party/blink/renderer/core/exported/web_layer_test.cc
@@ -47,7 +47,8 @@ // Both sets the inner html and runs the document lifecycle. void InitializeWithHTML(LocalFrame& frame, const String& html_content) { frame.GetDocument()->body()->SetInnerHTMLFromString(html_content); - frame.GetDocument()->View()->UpdateAllLifecyclePhases(); + frame.GetDocument()->View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); } WebLocalFrame* LocalMainFrame() { return web_view_helper_->LocalMainFrame(); } @@ -92,10 +93,16 @@ return frame->GetFrame()->GetDocument()->getElementById(id); } + void UpdateAllLifecyclePhases() { + WebView()->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); + } + private: PaintArtifactCompositor* paint_artifact_compositor() { return GetLocalFrameView()->GetPaintArtifactCompositorForTesting(); } + frame_test_helpers::TestWebViewClient web_view_client_; std::unique_ptr<frame_test_helpers::WebViewHelper> web_view_helper_; }; @@ -117,7 +124,7 @@ " <div id='forceScroll'></div>" "</div>"); - WebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(); Document* document = WebView()->MainFrameImpl()->GetFrame()->GetDocument(); Element* scrollable = document->getElementById("scrollable"); @@ -143,7 +150,7 @@ // area using the DidScroll callback. EXPECT_EQ(ScrollOffset(), scrollable_area->GetScrollOffset()); overflow_scroll_layer->SetScrollOffsetFromImplSide(gfx::ScrollOffset(0, 1)); - WebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(); EXPECT_EQ(ScrollOffset(0, 1), scrollable_area->GetScrollOffset()); // Make the scrollable area non-scrollable. @@ -164,7 +171,7 @@ EXPECT_EQ(ScrollHitTestLayerCount(), initial_scroll_hit_test_layer_count); overflow_scroll_layer->SetScrollOffsetFromImplSide(gfx::ScrollOffset(0, 3)); - WebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(); EXPECT_LT(ContentLayerCount(), initial_content_layer_count); if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) EXPECT_LT(ScrollHitTestLayerCount(), initial_scroll_hit_test_layer_count); @@ -180,7 +187,7 @@ "</style>" "<div id='forceScroll'></div>"); - WebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(); auto* scrollable_area = GetLocalFrameView()->LayoutViewport(); EXPECT_NE(nullptr, scrollable_area); @@ -204,7 +211,7 @@ // area using the DidScroll callback. EXPECT_EQ(ScrollOffset(), scrollable_area->GetScrollOffset()); scroll_layer->SetScrollOffsetFromImplSide(gfx::ScrollOffset(0, 1)); - WebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(); EXPECT_EQ(ScrollOffset(0, 1), scrollable_area->GetScrollOffset()); } @@ -218,10 +225,11 @@ request.Complete(html); // Enable the paint artifact compositor extra testing data. - WebView().MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(); DCHECK(paint_artifact_compositor()); paint_artifact_compositor()->EnableExtraDataForTesting(); - WebView().MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(); + DCHECK(paint_artifact_compositor()->GetExtraDataForTesting()); } @@ -242,6 +250,11 @@ return MainFrame().GetFrame()->GetDocument()->getElementById(id); } + void UpdateAllLifecyclePhases() { + WebView().MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); + } + private: PaintArtifactCompositor* paint_artifact_compositor() { return MainFrame().GetFrameView()->GetPaintArtifactCompositorForTesting(); @@ -291,7 +304,7 @@ // Modifying b should only cause the b layer to need to push properties. b_element->setAttribute(html_names::kStyleAttr, "opacity: 0.2"); - WebView().MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(); EXPECT_FALSE(host->LayersThatShouldPushProperties().count(a_layer)); EXPECT_TRUE(host->LayersThatShouldPushProperties().count(b_layer)); @@ -351,7 +364,7 @@ // not cause the c layer to push properties. a_element->setAttribute(html_names::kStyleAttr, "opacity: 0.3"); b_element->setAttribute(html_names::kStyleAttr, ""); - WebView().MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(); EXPECT_TRUE(host->LayersThatShouldPushProperties().count(a_layer)); EXPECT_TRUE(host->LayersThatShouldPushProperties().count(b_layer)); EXPECT_FALSE(host->LayersThatShouldPushProperties().count(c_layer)); @@ -383,7 +396,7 @@ EXPECT_FALSE(layer_tree_host->needs_full_tree_sync()); // A no-op update should not cause the host to need a full tree sync. - WebView().MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(); EXPECT_FALSE(layer_tree_host->needs_full_tree_sync()); } @@ -445,7 +458,7 @@ // both layers. outer_element->setAttribute(html_names::kStyleAttr, "transform: translate(20px, 20px)"); - WebView().MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(); EXPECT_TRUE(outer_element_layer->subtree_property_changed()); EXPECT_TRUE(inner_element_layer->subtree_property_changed()); @@ -508,7 +521,7 @@ // Modifying the filter style should set |subtree_property_changed| on // both layers. outer_element->setAttribute(html_names::kStyleAttr, "filter: blur(20px)"); - WebView().MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(); EXPECT_TRUE(outer_element_layer->subtree_property_changed()); EXPECT_TRUE(inner_element_layer->subtree_property_changed()); @@ -569,7 +582,7 @@ // both layers. outer_element->setAttribute(html_names::kStyleAttr, "clip: rect(1px, 8px, 7px, 4px);"); - WebView().MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(); EXPECT_TRUE(outer_element_layer->subtree_property_changed()); EXPECT_TRUE(inner_element_layer->subtree_property_changed()); @@ -627,7 +640,7 @@ // Modifying the clip width should set |subtree_property_changed| on // both layers. outer_element->setAttribute(html_names::kStyleAttr, "width: 200px;"); - WebView().MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(); EXPECT_TRUE(outer_element_layer->subtree_property_changed()); EXPECT_TRUE(inner_element_layer->subtree_property_changed());
diff --git a/third_party/blink/renderer/core/exported/web_page_popup_impl.cc b/third_party/blink/renderer/core/exported/web_page_popup_impl.cc index 3800808d..c7bd80c 100644 --- a/third_party/blink/renderer/core/exported/web_page_popup_impl.cc +++ b/third_party/blink/renderer/core/exported/web_page_popup_impl.cc
@@ -401,10 +401,14 @@ animation_host_ = nullptr; } -void WebPagePopupImpl::UpdateLifecycle(LifecycleUpdate requested_update) { +void WebPagePopupImpl::UpdateLifecycle(LifecycleUpdate requested_update, + LifecycleUpdateReason reason) { if (!page_) return; - PageWidgetDelegate::UpdateLifecycle(*page_, MainFrame(), requested_update); + // Popups always update their lifecycle in the context of the containing + // document's lifecycle, so explicitly override the reason. + PageWidgetDelegate::UpdateLifecycle(*page_, MainFrame(), requested_update, + WebWidget::LifecycleUpdateReason::kOther); } void WebPagePopupImpl::UpdateAllLifecyclePhasesAndCompositeForTesting(
diff --git a/third_party/blink/renderer/core/exported/web_page_popup_impl.h b/third_party/blink/renderer/core/exported/web_page_popup_impl.h index 859fe80..6193629 100644 --- a/third_party/blink/renderer/core/exported/web_page_popup_impl.h +++ b/third_party/blink/renderer/core/exported/web_page_popup_impl.h
@@ -85,7 +85,8 @@ void SetLayerTreeView(WebLayerTreeView*) override; void SetSuppressFrameRequestsWorkaroundFor704763Only(bool) final; void BeginFrame(base::TimeTicks last_frame_time) override; - void UpdateLifecycle(LifecycleUpdate requested_update) override; + void UpdateLifecycle(LifecycleUpdate requested_update, + LifecycleUpdateReason reason /* Not used */) override; void UpdateAllLifecyclePhasesAndCompositeForTesting(bool do_raster) override; void WillCloseLayerTreeView() override; void PaintContent(cc::PaintCanvas*, const WebRect&) override;
diff --git a/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc b/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc index 4e357d5..7ab781c 100644 --- a/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc +++ b/third_party/blink/renderer/core/exported/web_plugin_container_impl.cc
@@ -136,7 +136,8 @@ if (!web_plugin_) return; - web_plugin_->UpdateAllLifecyclePhases(); + web_plugin_->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kOther); } void WebPluginContainerImpl::SetFrameRect(const IntRect& frame_rect) {
diff --git a/third_party/blink/renderer/core/exported/web_plugin_container_test.cc b/third_party/blink/renderer/core/exported/web_plugin_container_test.cc index 4b43ab6..4d0949e 100644 --- a/third_party/blink/renderer/core/exported/web_plugin_container_test.cc +++ b/third_party/blink/renderer/core/exported/web_plugin_container_test.cc
@@ -104,7 +104,8 @@ } void UpdateAllLifecyclePhases(WebViewImpl* web_view) { - web_view->MainFrameWidget()->UpdateAllLifecyclePhases(); + web_view->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); } protected: @@ -242,7 +243,8 @@ DCHECK(web_view); web_view->GetSettings()->SetPluginsEnabled(true); web_view->MainFrameWidget()->Resize(size); - web_view->MainFrameWidget()->UpdateAllLifecyclePhases(); + web_view->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); RunPendingTasks(); }
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc index 295828c..12817d8 100644 --- a/third_party/blink/renderer/core/exported/web_view_impl.cc +++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -1088,7 +1088,7 @@ void WebViewImpl::EnableTapHighlights( HeapVector<Member<Node>>& highlight_nodes) { GetPage()->GetLinkHighlights().SetTapHighlights(highlight_nodes); - UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(LifecycleUpdateReason::kOther); } void WebViewImpl::AnimateDoubleTapZoom(const IntPoint& point_in_root_frame, @@ -1429,7 +1429,7 @@ // Update lifecyle phases immediately to recalculate the minimum scale limit // for rotation anchoring, and to make sure that no lifecycle states are // stale if this WebView is embedded in another one. - UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(LifecycleUpdateReason::kOther); } void WebViewImpl::ResizeWithBrowserControls( @@ -1538,7 +1538,8 @@ frame_begin_time); } -void WebViewImpl::UpdateLifecycle(LifecycleUpdate requested_update) { +void WebViewImpl::UpdateLifecycle(LifecycleUpdate requested_update, + LifecycleUpdateReason reason) { TRACE_EVENT0("blink", "WebViewImpl::updateAllLifecyclePhases"); if (!MainFrameImpl()) return; @@ -1547,7 +1548,7 @@ MainFrameImpl()->GetFrame()->GetDocument()->Lifecycle()); PageWidgetDelegate::UpdateLifecycle(*page_, *MainFrameImpl()->GetFrame(), - requested_update); + requested_update, reason); if (requested_update == LifecycleUpdate::kLayout) return;
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.h b/third_party/blink/renderer/core/exported/web_view_impl.h index bcb1519..0d0f81cc 100644 --- a/third_party/blink/renderer/core/exported/web_view_impl.h +++ b/third_party/blink/renderer/core/exported/web_view_impl.h
@@ -121,7 +121,8 @@ void SetSuppressFrameRequestsWorkaroundFor704763Only(bool) override; void BeginFrame(base::TimeTicks last_frame_time) override; void RecordEndOfFrameMetrics(base::TimeTicks frame_begin_time) override; - void UpdateLifecycle(LifecycleUpdate requested_update) override; + void UpdateLifecycle(LifecycleUpdate requested_update, + LifecycleUpdateReason reason) override; void UpdateAllLifecyclePhasesAndCompositeForTesting(bool do_raster) override; void RequestPresentationCallbackForTesting( base::OnceClosure callback) 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 505f36a1..2fb08f2 100644 --- a/third_party/blink/renderer/core/exported/web_view_test.cc +++ b/third_party/blink/renderer/core/exported/web_view_test.cc
@@ -295,9 +295,8 @@ IntSize PrintICBSizeFromPageSize(const FloatSize& page_size); void UpdateAllLifecyclePhases() { - web_view_helper_.GetWebView() - ->MainFrameWidget() - ->UpdateAllLifecyclePhases(); + web_view_helper_.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); } std::string base_url_; @@ -2256,7 +2255,7 @@ WebViewImpl* web_view_impl = web_view_helper_.InitializeAndLoad(base_url_ + "200-by-300.html"); web_view_impl->Resize(WebSize(100, 150)); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(); EXPECT_EQ(0, web_view_impl->MainFrameImpl()->GetScrollOffset().width); EXPECT_EQ(0, web_view_impl->MainFrameImpl()->GetScrollOffset().height); @@ -2301,7 +2300,8 @@ WebViewImpl* web_view_impl = web_view_helper_.InitializeAndLoad( base_url_ + "back_forward_restore_scroll.html"); web_view_impl->Resize(WebSize(640, 480)); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); + web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); // Emulate a user scroll web_view_impl->MainFrameImpl()->SetScrollOffset(WebSize(0, 900)); @@ -2354,7 +2354,7 @@ WebViewImpl* web_view_impl = web_view_helper_.InitializeAndLoad(base_url_ + "fullscreen_style.html"); web_view_impl->Resize(WebSize(800, 600)); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(); // Scroll the page down. web_view_impl->MainFrameImpl()->SetScrollOffset(WebSize(0, 2000)); @@ -2367,7 +2367,7 @@ LocalFrame::NotifyUserActivation(frame); Fullscreen::RequestFullscreen(*element); web_view_impl->DidEnterFullscreen(); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(); // Assert the scroll position on the document element doesn't change. ASSERT_EQ(2000, web_view_impl->MainFrameImpl()->GetScrollOffset().height); @@ -2375,7 +2375,7 @@ web_view_impl->MainFrameImpl()->SetScrollOffset(WebSize(0, 2100)); web_view_impl->DidExitFullscreen(); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(); EXPECT_EQ(2100, web_view_impl->MainFrameImpl()->GetScrollOffset().height); } @@ -2386,7 +2386,7 @@ WebViewImpl* web_view_impl = web_view_helper_.InitializeAndLoad(base_url_ + "fullscreen_style.html"); web_view_impl->Resize(WebSize(800, 600)); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(); EXPECT_EQ(SK_ColorWHITE, web_view_impl->BackgroundColor()); // Enter fullscreen. @@ -2397,7 +2397,7 @@ LocalFrame::NotifyUserActivation(frame); Fullscreen::RequestFullscreen(*element); web_view_impl->DidEnterFullscreen(); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(); EXPECT_EQ(SK_ColorYELLOW, web_view_impl->BackgroundColor()); } @@ -4255,7 +4255,8 @@ web_view_ = mojo_test_helper_->WebView(); web_view_->Resize(WebSize(500, 300)); - web_view_->MainFrameWidget()->UpdateAllLifecyclePhases(); + web_view_->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); RunPendingTasks(); mojo_test_helper_->BindTestApi(
diff --git a/third_party/blink/renderer/core/fetch/fetch_request_data.cc b/third_party/blink/renderer/core/fetch/fetch_request_data.cc index 14635d1c..3507f2d 100644 --- a/third_party/blink/renderer/core/fetch/fetch_request_data.cc +++ b/third_party/blink/renderer/core/fetch/fetch_request_data.cc
@@ -65,6 +65,45 @@ return request; } +FetchRequestData* FetchRequestData::Create( + ScriptState* script_state, + const mojom::blink::FetchAPIRequest& fetch_api_request) { + FetchRequestData* request = FetchRequestData::Create(); + request->url_ = fetch_api_request.url; + request->method_ = AtomicString(fetch_api_request.method); + for (const auto& pair : fetch_api_request.headers) { + // TODO(leonhsl): Check sources of |fetch_api_request.headers| to make clear + // whether we really need this filter. + if (DeprecatedEqualIgnoringCase(pair.key, "referer")) + continue; + request->header_list_->Append(pair.key, pair.value); + } + if (fetch_api_request.blob) { + request->SetBuffer(new BodyStreamBuffer( + script_state, + new BlobBytesConsumer(ExecutionContext::From(script_state), + fetch_api_request.blob), + nullptr /* AbortSignal */)); + } + request->SetContext(fetch_api_request.request_context_type); + request->SetReferrerString(AtomicString(Referrer::NoReferrer())); + if (fetch_api_request.referrer) { + if (!fetch_api_request.referrer->url.IsEmpty()) + request->SetReferrerString(AtomicString(fetch_api_request.referrer->url)); + request->SetReferrerPolicy( + static_cast<ReferrerPolicy>(fetch_api_request.referrer->policy)); + } + request->SetMode(fetch_api_request.mode); + request->SetCredentials(fetch_api_request.credentials_mode); + request->SetCacheMode(fetch_api_request.cache_mode); + request->SetRedirect(fetch_api_request.redirect_mode); + request->SetMIMEType(request->header_list_->ExtractMIMEType()); + request->SetIntegrity(fetch_api_request.integrity); + request->SetKeepalive(fetch_api_request.keepalive); + request->SetIsHistoryNavigation(fetch_api_request.is_history_navigation); + return request; +} + FetchRequestData* FetchRequestData::CloneExceptBody() { FetchRequestData* request = FetchRequestData::Create(); request->url_ = url_;
diff --git a/third_party/blink/renderer/core/fetch/fetch_request_data.h b/third_party/blink/renderer/core/fetch/fetch_request_data.h index e8a683e..56a61b2 100644 --- a/third_party/blink/renderer/core/fetch/fetch_request_data.h +++ b/third_party/blink/renderer/core/fetch/fetch_request_data.h
@@ -10,7 +10,7 @@ #include "base/unguessable_token.h" #include "services/network/public/mojom/fetch_api.mojom-blink.h" #include "services/network/public/mojom/url_loader_factory.mojom-blink.h" -#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom-shared.h" +#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom-blink.h" #include "third_party/blink/public/platform/modules/service_worker/web_service_worker_request.h" #include "third_party/blink/public/platform/web_url_request.h" #include "third_party/blink/renderer/core/fetch/body_stream_buffer.h" @@ -38,6 +38,8 @@ static FetchRequestData* Create(); static FetchRequestData* Create(ScriptState*, const WebServiceWorkerRequest&); + static FetchRequestData* Create(ScriptState*, + const mojom::blink::FetchAPIRequest&); // Call Request::refreshBody() after calling clone() or pass(). FetchRequestData* Clone(ScriptState*, ExceptionState&); FetchRequestData* Pass(ScriptState*, ExceptionState&);
diff --git a/third_party/blink/renderer/core/fetch/request.cc b/third_party/blink/renderer/core/fetch/request.cc index 4eef6ee..d1a52b8e 100644 --- a/third_party/blink/renderer/core/fetch/request.cc +++ b/third_party/blink/renderer/core/fetch/request.cc
@@ -619,9 +619,16 @@ Request* Request::Create(ScriptState* script_state, const WebServiceWorkerRequest& web_request) { - FetchRequestData* request = - FetchRequestData::Create(script_state, web_request); - return new Request(script_state, request); + FetchRequestData* data = FetchRequestData::Create(script_state, web_request); + return new Request(script_state, data); +} + +Request* Request::Create( + ScriptState* script_state, + const mojom::blink::FetchAPIRequest& fetch_api_request) { + FetchRequestData* data = + FetchRequestData::Create(script_state, fetch_api_request); + return new Request(script_state, data); } bool Request::ParseCredentialsMode( @@ -883,35 +890,50 @@ return BodyBuffer(); } -void Request::PopulateWebServiceWorkerRequest( - WebServiceWorkerRequest& web_request) const { - web_request.SetMethod(method()); - web_request.SetMode(request_->Mode()); - web_request.SetCredentialsMode(request_->Credentials()); - web_request.SetCacheMode(request_->CacheMode()); - web_request.SetRedirectMode(request_->Redirect()); - web_request.SetIntegrity(request_->Integrity()); - web_request.SetIsHistoryNavigation(request_->IsHistoryNavigation()); - web_request.SetRequestContext(request_->Context()); +mojom::blink::FetchAPIRequestPtr Request::CreateFetchAPIRequest() const { + auto fetch_api_request = mojom::blink::FetchAPIRequest::New(); + fetch_api_request->method = method(); + fetch_api_request->mode = request_->Mode(); + fetch_api_request->credentials_mode = request_->Credentials(); + fetch_api_request->cache_mode = request_->CacheMode(); + fetch_api_request->redirect_mode = request_->Redirect(); + fetch_api_request->integrity = request_->Integrity(); + fetch_api_request->is_history_navigation = request_->IsHistoryNavigation(); + fetch_api_request->request_context_type = request_->Context(); - // Strip off the fragment part of URL. So far, all users of - // WebServiceWorkerRequest expect the fragment to be excluded. + // Strip off the fragment part of URL. So far, all callers expect the fragment + // to be excluded. KURL url(request_->Url()); if (request_->Url().HasFragmentIdentifier()) url.RemoveFragmentIdentifier(); - web_request.SetURL(url); + fetch_api_request->url = url; - const FetchHeaderList* header_list = headers_->HeaderList(); - for (const auto& header : header_list->List()) { - web_request.AppendHeader(header.first, header.second); + HTTPHeaderMap headers; + for (const auto& header : headers_->HeaderList()->List()) { + if (DeprecatedEqualIgnoringCase(header.first, "referer")) + continue; + AtomicString key(header.first); + AtomicString value(header.second); + HTTPHeaderMap::AddResult result = headers.Add(key, value); + if (!result.is_new_entry) { + result.stored_value->value = + result.stored_value->value + ", " + String(value); + } } + for (const auto& pair : headers) + fetch_api_request->headers.insert(pair.key, pair.value); - web_request.SetReferrer(request_->ReferrerString(), - static_cast<network::mojom::ReferrerPolicy>( - request_->GetReferrerPolicy())); + if (!request_->ReferrerString().IsEmpty()) { + fetch_api_request->referrer = + mojom::blink::Referrer::New(KURL(NullURL(), request_->ReferrerString()), + static_cast<network::mojom::ReferrerPolicy>( + request_->GetReferrerPolicy())); + DCHECK(fetch_api_request->referrer->url.IsValid()); + } // FIXME: How can we set isReload properly? What is the correct place to load // it in to the Request object? We should investigate the right way to plumb // this information in to here. + return fetch_api_request; } String Request::MimeType() const {
diff --git a/third_party/blink/renderer/core/fetch/request.h b/third_party/blink/renderer/core/fetch/request.h index 06bd5de..fea6f2f 100644 --- a/third_party/blink/renderer/core/fetch/request.h +++ b/third_party/blink/renderer/core/fetch/request.h
@@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_FETCH_REQUEST_H_ #include "services/network/public/mojom/fetch_api.mojom-shared.h" +#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom-blink.h" #include "third_party/blink/public/platform/web_url_request.h" #include "third_party/blink/renderer/bindings/core/v8/dictionary.h" #include "third_party/blink/renderer/bindings/core/v8/request_or_usv_string.h" @@ -52,6 +53,7 @@ ExceptionState&); static Request* Create(ScriptState*, FetchRequestData*); static Request* Create(ScriptState*, const WebServiceWorkerRequest&); + static Request* Create(ScriptState*, const mojom::blink::FetchAPIRequest&); // Returns false if |credentials_mode| doesn't represent a valid credentials // mode. @@ -79,7 +81,7 @@ Request* clone(ScriptState*, ExceptionState&); FetchRequestData* PassRequestData(ScriptState*, ExceptionState&); - void PopulateWebServiceWorkerRequest(WebServiceWorkerRequest&) const; + mojom::blink::FetchAPIRequestPtr CreateFetchAPIRequest() const; bool HasBody() const; BodyStreamBuffer* BodyBuffer() override { return request_->Buffer(); } const BodyStreamBuffer* BodyBuffer() const override {
diff --git a/third_party/blink/renderer/core/fetch/request_test.cc b/third_party/blink/renderer/core/fetch/request_test.cc index 08154830..d5720fcf 100644 --- a/third_party/blink/renderer/core/fetch/request_test.cc +++ b/third_party/blink/renderer/core/fetch/request_test.cc
@@ -46,9 +46,9 @@ EXPECT_EQ(url, request2->url()); } -TEST(ServiceWorkerRequestTest, FromAndToWebRequest) { +TEST(ServiceWorkerRequestTest, FromAndToFetchAPIRequest) { V8TestingScope scope; - WebServiceWorkerRequest web_request; + auto fetch_api_request = mojom::blink::FetchAPIRequest::New(); const KURL url("http://www.example.com/"); const String method = "GET"; @@ -68,20 +68,20 @@ const network::mojom::FetchRedirectMode kRedirectMode = network::mojom::FetchRedirectMode::kError; - web_request.SetURL(url); - web_request.SetMethod(method); - web_request.SetMode(kMode); - web_request.SetCredentialsMode(kCredentialsMode); - web_request.SetCacheMode(kCacheMode); - web_request.SetRedirectMode(kRedirectMode); - web_request.SetRequestContext(kContext); - for (int i = 0; headers[i].key; ++i) { - web_request.SetHeader(WebString::FromUTF8(headers[i].key), - WebString::FromUTF8(headers[i].value)); - } - web_request.SetReferrer(referrer, kReferrerPolicy); + fetch_api_request->url = url; + fetch_api_request->method = method; + fetch_api_request->mode = kMode; + fetch_api_request->credentials_mode = kCredentialsMode; + fetch_api_request->cache_mode = kCacheMode; + fetch_api_request->redirect_mode = kRedirectMode; + fetch_api_request->request_context_type = kContext; + for (int i = 0; headers[i].key; ++i) + fetch_api_request->headers.insert(headers[i].key, headers[i].value); + fetch_api_request->referrer = + mojom::blink::Referrer::New(KURL(NullURL(), referrer), kReferrerPolicy); - Request* request = Request::Create(scope.GetScriptState(), web_request); + Request* request = + Request::Create(scope.GetScriptState(), *fetch_api_request); DCHECK(request); EXPECT_EQ(url, request->url()); EXPECT_EQ(method, request->method()); @@ -102,22 +102,22 @@ EXPECT_FALSE(exception_state.HadException()); } - WebServiceWorkerRequest second_web_request; - request->PopulateWebServiceWorkerRequest(second_web_request); - EXPECT_EQ(url, KURL(second_web_request.Url())); - EXPECT_EQ(method, String(second_web_request.Method())); - EXPECT_EQ(kMode, second_web_request.Mode()); - EXPECT_EQ(kCredentialsMode, second_web_request.CredentialsMode()); - EXPECT_EQ(kCacheMode, second_web_request.CacheMode()); - EXPECT_EQ(kRedirectMode, second_web_request.RedirectMode()); - EXPECT_EQ(kContext, second_web_request.GetRequestContext()); - EXPECT_EQ(referrer, KURL(second_web_request.ReferrerUrl())); + mojom::blink::FetchAPIRequestPtr second_fetch_api_request = + request->CreateFetchAPIRequest(); + EXPECT_EQ(url, second_fetch_api_request->url); + EXPECT_EQ(method, second_fetch_api_request->method); + EXPECT_EQ(kMode, second_fetch_api_request->mode); + EXPECT_EQ(kCredentialsMode, second_fetch_api_request->credentials_mode); + EXPECT_EQ(kCacheMode, second_fetch_api_request->cache_mode); + EXPECT_EQ(kRedirectMode, second_fetch_api_request->redirect_mode); + EXPECT_EQ(kContext, second_fetch_api_request->request_context_type); + EXPECT_EQ(referrer, second_fetch_api_request->referrer->url); EXPECT_EQ(network::mojom::ReferrerPolicy::kAlways, - second_web_request.GetReferrerPolicy()); - EXPECT_EQ(web_request.Headers(), second_web_request.Headers()); + second_fetch_api_request->referrer->policy); + EXPECT_EQ(fetch_api_request->headers, second_fetch_api_request->headers); } -TEST(ServiceWorkerRequestTest, ToWebRequestStripsURLFragment) { +TEST(ServiceWorkerRequestTest, ToFetchAPIRequestStripsURLFragment) { V8TestingScope scope; DummyExceptionStateForTesting exception_state; String url_without_fragment = "http://www.example.com/"; @@ -126,9 +126,9 @@ Request::Create(scope.GetScriptState(), url, exception_state); DCHECK(request); - WebServiceWorkerRequest web_request; - request->PopulateWebServiceWorkerRequest(web_request); - EXPECT_EQ(url_without_fragment, KURL(web_request.Url())); + mojom::blink::FetchAPIRequestPtr fetch_api_request = + request->CreateFetchAPIRequest(); + EXPECT_EQ(url_without_fragment, fetch_api_request->url); } } // namespace
diff --git a/third_party/blink/renderer/core/frame/browser_controls_test.cc b/third_party/blink/renderer/core/frame/browser_controls_test.cc index 32df278..87ff69a 100644 --- a/third_party/blink/renderer/core/frame/browser_controls_test.cc +++ b/third_party/blink/renderer/core/frame/browser_controls_test.cc
@@ -142,7 +142,8 @@ } void UpdateAllLifecyclePhases() { - GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); } private:
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc index 9ab834fd..c2cf83a 100644 --- a/third_party/blink/renderer/core/frame/local_frame.cc +++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -492,6 +492,10 @@ Document* document = GetDocument(); DCHECK(document); GetEditor().Clear(); + // Clearing the event handler clears many events, but notably can ensure that + // for a drag started on an element in a frame that was moved (likely via + // appendChild()), the drag source will detach and stop firing drag events + // even after the frame reattaches. GetEventHandler().Clear(); Selection().DidAttachDocument(document); GetInputMethodController().DidAttachDocument(document);
diff --git a/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.cc b/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.cc index f284767..152ba1b4 100644 --- a/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.cc +++ b/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.cc
@@ -127,6 +127,11 @@ return ScopedUkmHierarchicalTimer(this, metric_index); } +void LocalFrameUkmAggregator::BeginMainFrame() { + DCHECK(!in_main_frame_update_); + in_main_frame_update_ = true; +} + void LocalFrameUkmAggregator::RecordSample(size_t metric_index, TimeTicks start, TimeTicks end) { @@ -143,13 +148,23 @@ // Record the UMA record.uma_counter->CountMicroseconds(duration); - // Just record the duration for ratios. We compute the ratio later - // when we know the frame time. - main_frame_percentage_records_[metric_index].interval_duration += duration; + // Only record ratios when inside a main frame. + if (in_main_frame_update_) { + // Just record the duration for ratios. We compute the ratio later + // when we know the frame time. + main_frame_percentage_records_[metric_index].interval_duration += duration; + } } -void LocalFrameUkmAggregator::RecordPrimarySample(TimeTicks start, - TimeTicks end) { +void LocalFrameUkmAggregator::RecordEndOfFrameMetrics(TimeTicks start, + TimeTicks end) { + // Any of the early out's in LocalFrameView::UpdateLifecyclePhases + // will mean we are not in a main frame update. Recording is triggered + // higher in the stack, so we cannot know to avoid calling this method. + if (!in_main_frame_update_) + return; + in_main_frame_update_ = false; + TimeDelta duration = end - start; // Record UMA
diff --git a/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h b/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h index 7a19d93..487bba7 100644 --- a/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h +++ b/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h
@@ -68,7 +68,7 @@ // // At this point an sample for kMetric2 is recorded. // ... // // When the primary time completes -// aggregator->RecordPrimaryMetric(time_delta); +// aggregator->RecordEndOfFrameMetrics(time_delta); // // This records a primary sample and the sub-metrics that depend on it. // // It may generate an event. // ... @@ -82,9 +82,9 @@ // "sub_metric1.Average", "sub_metric1.WorstCase", // "sub_metric2.Average", "sub_metric2.WorstCase", // "sub_metric3.Average", "sub_metric3.WorstCase" -// "sub_metric1.AveragePercentage", "sub_metric1.WorstCasePercentage", -// "sub_metric2.AveragePercentage", "sub_metric2.WorstCasePercentage", -// "sub_metric3.AveragePercentage", "sub_metric3.WorstCasePercentage" +// "sub_metric1.AverageRatio", "sub_metric1.WorstCaseRatio", +// "sub_metric2.AverageRatio", "sub_metric2.WorstCaseRatio", +// "sub_metric3.AverageRatio", "sub_metric3.WorstCaseRatio" // // It will report 13 UMA values: // "primary_uma_counter", @@ -167,15 +167,17 @@ // correspond to the matching index in metric_names. ScopedUkmHierarchicalTimer GetScopedTimer(size_t metric_index); - // Record a primary sample, that also computes the ratios for the + // Record a main frame time metric, that also computes the ratios for the // sub-metrics and may generate an event. - void RecordPrimarySample(TimeTicks start, TimeTicks end); + void RecordEndOfFrameMetrics(TimeTicks start, TimeTicks end); // Record a sample for a sub-metric. This should only be used when // a ScopedUkmHierarchicalTimer cannot be used (such as when the timed // interval does not fall inside a single calling function). void RecordSample(size_t metric_index, TimeTicks start, TimeTicks end); + void BeginMainFrame(); + private: struct AbsoluteMetricRecord { String worst_case_metric_name; @@ -221,6 +223,10 @@ Vector<MainFramePercentageRecord> main_frame_percentage_records_; TimeTicks last_flushed_time_; + // Set by BeginMainFrame() and cleared in RecordMEndOfFrameMetrics. + // Main frame metrics are only recorded if this is true. + bool in_main_frame_update_ = false; + bool has_data_ = false; DISALLOW_COPY_AND_ASSIGN(LocalFrameUkmAggregator);
diff --git a/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator_test.cc b/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator_test.cc index 3784a810..ab43965cf 100644 --- a/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator_test.cc +++ b/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator_test.cc
@@ -103,12 +103,13 @@ unsigned millisecond_per_step = (unsigned)ceil(3000.0 / (double)LocalFrameUkmAggregator::kCount); for (int i = 0; i < num_runs; ++i) { + aggregator().BeginMainFrame(); { auto timer = aggregator().GetScopedTimer(i % LocalFrameUkmAggregator::kCount); clock().Advance(TimeDelta::FromMilliseconds(millisecond_per_step)); } - aggregator().RecordPrimarySample(start_time, Now()); + aggregator().RecordEndOfFrameMetrics(start_time, Now()); start_time = Now(); } @@ -159,6 +160,8 @@ if (!base::TimeTicks::IsHighResolution()) return; + aggregator().BeginMainFrame(); + // 1, 2, and 3 seconds. for (int i = 1; i <= 3; ++i) { { @@ -177,7 +180,7 @@ clock().Advance(TimeDelta::FromSeconds(1)); } - aggregator().RecordPrimarySample( + aggregator().RecordEndOfFrameMetrics( base::TimeTicks(), base::TimeTicks() + base::TimeDelta::FromSecondsD(20)); ResetAggregator(); @@ -238,6 +241,7 @@ entry, GetWorstCaseRatioMetricName(1))); const int64_t* metric2_worst_ratio = ukm::TestUkmRecorder::GetEntryMetric( entry, GetWorstCaseRatioMetricName(1)); + // Only one main frame sample, so worst is same as average EXPECT_NEAR(*metric2_worst_ratio, floor(10.0 * 100.0 / 20.0), 0.0001); }
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc index 908f669..b214f27 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.cc +++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -2165,38 +2165,46 @@ } } -void LocalFrameView::UpdateAllLifecyclePhases() { +void LocalFrameView::UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason reason) { GetFrame().LocalFrameRoot().View()->UpdateLifecyclePhases( - DocumentLifecycle::kPaintClean); + DocumentLifecycle::kPaintClean, reason); } -// TODO(chrishtr): add a scrolling update lifecycle phase. +// TODO(schenney): add a scrolling update lifecycle phase. +// TODO(schenney): Pass a LifecycleUpdateReason in here bool LocalFrameView::UpdateLifecycleToCompositingCleanPlusScrolling() { if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) { return UpdateAllLifecyclePhasesExceptPaint(); } else { return GetFrame().LocalFrameRoot().View()->UpdateLifecyclePhases( - DocumentLifecycle::kCompositingClean); + DocumentLifecycle::kCompositingClean, + DocumentLifecycle::LifecycleUpdateReason::kOther); } } +// TODO(schenney): Pass a LifecycleUpdateReason in here bool LocalFrameView::UpdateLifecycleToCompositingInputsClean() { // When SPv2 is enabled, the standard compositing lifecycle steps do not // exist; compositing is done after paint instead. DCHECK(!RuntimeEnabledFeatures::SlimmingPaintV2Enabled()); return GetFrame().LocalFrameRoot().View()->UpdateLifecyclePhases( - DocumentLifecycle::kCompositingInputsClean); + DocumentLifecycle::kCompositingInputsClean, + DocumentLifecycle::LifecycleUpdateReason::kOther); } +// TODO(schenney): Pass a LifecycleUpdateReason in here bool LocalFrameView::UpdateAllLifecyclePhasesExceptPaint() { return GetFrame().LocalFrameRoot().View()->UpdateLifecyclePhases( - DocumentLifecycle::kPrePaintClean); + DocumentLifecycle::kPrePaintClean, + DocumentLifecycle::LifecycleUpdateReason::kOther); } void LocalFrameView::UpdateLifecyclePhasesForPrinting() { auto* local_frame_view_root = GetFrame().LocalFrameRoot().View(); local_frame_view_root->UpdateLifecyclePhases( - DocumentLifecycle::kPrePaintClean); + DocumentLifecycle::kPrePaintClean, + DocumentLifecycle::LifecycleUpdateReason::kOther); auto* detached_frame_view = this; while (detached_frame_view->is_attached_ && @@ -2211,17 +2219,21 @@ // was not reached in some phases during during |local_frame_view_root-> // UpdateLifecyclePhasesnormal()|. We need the subtree to be ready for // painting. - detached_frame_view->UpdateLifecyclePhases(DocumentLifecycle::kPrePaintClean); + detached_frame_view->UpdateLifecyclePhases( + DocumentLifecycle::kPrePaintClean, + DocumentLifecycle::LifecycleUpdateReason::kOther); } +// TODO(schenney): Pass a LifecycleUpdateReason in here bool LocalFrameView::UpdateLifecycleToLayoutClean() { return GetFrame().LocalFrameRoot().View()->UpdateLifecyclePhases( - DocumentLifecycle::kLayoutClean); + DocumentLifecycle::kLayoutClean, + DocumentLifecycle::LifecycleUpdateReason::kOther); } void LocalFrameView::RecordEndOfFrameMetrics(base::TimeTicks frame_begin_time) { LocalFrameUkmAggregator& ukm_aggregator = EnsureUkmAggregator(); - ukm_aggregator.RecordPrimarySample(frame_begin_time, CurrentTimeTicks()); + ukm_aggregator.RecordEndOfFrameMetrics(frame_begin_time, CurrentTimeTicks()); } void LocalFrameView::ScheduleVisualUpdateForPaintInvalidationIfNeeded() { @@ -2307,7 +2319,8 @@ // TODO(leviw): We don't assert lifecycle information from documents in child // WebPluginContainerImpls. bool LocalFrameView::UpdateLifecyclePhases( - DocumentLifecycle::LifecycleState target_state) { + DocumentLifecycle::LifecycleState target_state, + DocumentLifecycle::LifecycleUpdateReason reason) { // If the lifecycle is postponed, which can happen if the inspector requests // it, then we shouldn't update any lifecycle phases. if (UNLIKELY(frame_->GetDocument() && @@ -2365,6 +2378,9 @@ return Lifecycle().GetState() == target_state; } + if (reason == DocumentLifecycle::LifecycleUpdateReason::kBeginMainFrame) + EnsureUkmAggregator().BeginMainFrame(); + // If we're in PrintBrowser mode, setup a print context. // TODO(vmpstr): It doesn't seem like we need to do this every lifecycle // update, but rather once somewhere at creation time. @@ -2595,7 +2611,7 @@ base::Optional<CompositorElementIdSet> composited_element_ids = CompositorElementIdSet(); PushPaintArtifactToCompositor(composited_element_ids.value()); - // TODO(wkorman): Add call to UpdateCompositorScrollAnimations here. + // TODO(pdr): Add call to UpdateCompositorScrollAnimations here. ForAllNonThrottledLocalFrameViews( [&composited_element_ids](LocalFrameView& frame_view) { DocumentAnimations::UpdateAnimations( @@ -2985,9 +3001,9 @@ // WebView plugins need to update regardless of whether the // LayoutEmbeddedObject that owns them needed layout. - // TODO(leviw): This currently runs the entire lifecycle on plugin WebViews. - // We should have a way to only run these other Documents to the same - // lifecycle stage as this frame. + // TODO(schenney): This currently runs the entire lifecycle on plugin + // WebViews. We should have a way to only run these other Documents to the + // same lifecycle stage as this frame. for (const auto& plugin : plugins_) { plugin->UpdateAllLifecyclePhases(); } @@ -3390,7 +3406,7 @@ return; // Ensure the document is up-to-date before tracking invalidations. - UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(DocumentLifecycle::LifecycleUpdateReason::kTest); for (Frame* frame = &frame_->Tree().Top(); frame; frame = frame->Tree().TraverseNext()) {
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.h b/third_party/blink/renderer/core/frame/local_frame_view.h index a8ae539..befa30d 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.h +++ b/third_party/blink/renderer/core/frame/local_frame_view.h
@@ -319,8 +319,10 @@ // be in the lifecycle state PaintClean. If lifecycle throttling is allowed // (see DocumentLifecycle::AllowThrottlingScope), some frames may skip the // lifecycle update (e.g., based on visibility) and will not end up being - // PaintClean. - void UpdateAllLifecyclePhases(); + // PaintClean. Set |reason| to indicate the reason for this update, + // for metrics purposes. + void UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason reason); // Computes the style, layout, compositing and pre-paint lifecycle stages // if needed. @@ -733,7 +735,8 @@ // Returns whether the lifecycle was succesfully updated to the // target state. - bool UpdateLifecyclePhases(DocumentLifecycle::LifecycleState target_state); + bool UpdateLifecyclePhases(DocumentLifecycle::LifecycleState target_state, + DocumentLifecycle::LifecycleUpdateReason reason); // The internal version that does the work after the proper context and checks // have passed in the above function call. void UpdateLifecyclePhasesInternal(
diff --git a/third_party/blink/renderer/core/frame/use_counter_test.cc b/third_party/blink/renderer/core/frame/use_counter_test.cc index 8c0e7cc..a48eba7 100644 --- a/third_party/blink/renderer/core/frame/use_counter_test.cc +++ b/third_party/blink/renderer/core/frame/use_counter_test.cc
@@ -64,7 +64,8 @@ HistogramTester histogram_tester_; void UpdateAllLifecyclePhases(Document& document) { - document.View()->UpdateAllLifecyclePhases(); + document.View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); } }; @@ -433,11 +434,11 @@ a {} </style> )HTML"); - document.View()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(document); EXPECT_FALSE(UseCounter::IsCounted(document, feature)); document.documentElement()->SetInnerHTMLFromString("<style>foo|a {}</style>"); - document.View()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(document); EXPECT_TRUE(UseCounter::IsCounted(document, feature)); }
diff --git a/third_party/blink/renderer/core/frame/visual_viewport_test.cc b/third_party/blink/renderer/core/frame/visual_viewport_test.cc index 6148091..9af2fe5 100644 --- a/third_party/blink/renderer/core/frame/visual_viewport_test.cc +++ b/third_party/blink/renderer/core/frame/visual_viewport_test.cc
@@ -113,7 +113,8 @@ } void UpdateAllLifecyclePhases() { - WebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + WebView()->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); } void ForceFullCompositingUpdate() { UpdateAllLifecyclePhases(); } @@ -208,8 +209,6 @@ protected: std::string base_url_; frame_test_helpers::TestWebViewClient mock_web_view_client_; - - private: frame_test_helpers::WebViewHelper helper_; }; @@ -1664,7 +1663,8 @@ WebScriptSource("var content = document.getElementById(\"content\");" "content.style.width = \"1500px\";" "content.style.height = \"2400px\";")); - frame_view.UpdateAllLifecyclePhases(); + frame_view.UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); cc::Layer* scroll_layer = frame_view.LayoutViewport()->LayerForScrolling()->CcLayer(); @@ -1748,9 +1748,8 @@ // Test that the various window.scroll and document.body.scroll properties and // methods don't change with the visual viewport. TEST_P(VisualViewportTest, visualViewportIsInert) { - frame_test_helpers::WebViewHelper web_view_helper; - WebViewImpl* web_view_impl = web_view_helper.Initialize( - nullptr, nullptr, nullptr, &ConfigureAndroidCompositing); + WebViewImpl* web_view_impl = helper_.Initialize(nullptr, nullptr, nullptr, + &ConfigureAndroidCompositing); web_view_impl->MainFrameWidget()->Resize(IntSize(200, 300)); @@ -1767,8 +1766,7 @@ " }" "</style>", base_url); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); - + UpdateAllLifecyclePhases(); LocalDOMWindow* window = web_view_impl->MainFrameImpl()->GetFrame()->DomWindow(); HTMLElement* html = ToHTMLHtmlElement(window->document()->documentElement()); @@ -2103,9 +2101,8 @@ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) return; - frame_test_helpers::WebViewHelper web_view_helper; - WebViewImpl* web_view_impl = web_view_helper.Initialize( - nullptr, nullptr, nullptr, &ConfigureAndroidCompositing); + WebViewImpl* web_view_impl = helper_.Initialize(nullptr, nullptr, nullptr, + &ConfigureAndroidCompositing); int page_width = 640; int page_height = 480; @@ -2130,8 +2127,8 @@ "</style>" "<div></div>", base_url); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhases(); Document* document = ToLocalFrame(web_view_impl->GetPage()->MainFrame())->GetDocument(); GraphicsLayer* backgroundLayer = document->GetLayoutView() @@ -2178,8 +2175,7 @@ if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) return; - frame_test_helpers::WebViewHelper web_view_helper; - WebViewImpl* web_view_impl = web_view_helper.Initialize( + WebViewImpl* web_view_impl = helper_.Initialize( nullptr, nullptr, nullptr, &ConfigureAndroidNonCompositing); int page_width = 640; @@ -2206,8 +2202,7 @@ "</style>" "<div></div>", base_url); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); - + UpdateAllLifecyclePhases(); Document* document = ToLocalFrame(web_view_impl->GetPage()->MainFrame())->GetDocument(); document->View()->SetTracksPaintInvalidations(true); @@ -2250,9 +2245,8 @@ // Make sure a browser control resize with background-attachment:not-fixed // background doesn't cause invalidation or layout. TEST_P(VisualViewportTest, ResizeNonFixedBackgroundNoLayoutOrInvalidation) { - frame_test_helpers::WebViewHelper web_view_helper; - WebViewImpl* web_view_impl = web_view_helper.Initialize( - nullptr, nullptr, nullptr, &ConfigureAndroidCompositing); + WebViewImpl* web_view_impl = helper_.Initialize(nullptr, nullptr, nullptr, + &ConfigureAndroidCompositing); int page_width = 640; int page_height = 480; @@ -2278,8 +2272,7 @@ "</style>" "<div></div>", base_url); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); - + UpdateAllLifecyclePhases(); Document* document = ToLocalFrame(web_view_impl->GetPage()->MainFrame())->GetDocument(); @@ -2294,8 +2287,7 @@ total_objects, is_subtree); EXPECT_EQ(0u, needs_layout_objects); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); - + UpdateAllLifecyclePhases(); // Do a real resize to check for invalidations. document->View()->SetTracksPaintInvalidations(true); web_view_impl->ResizeWithBrowserControls(WebSize(page_width, smallest_height), @@ -2316,9 +2308,8 @@ } TEST_P(VisualViewportTest, InvalidateLayoutViewWhenDocumentSmallerThanView) { - frame_test_helpers::WebViewHelper web_view_helper; - WebViewImpl* web_view_impl = web_view_helper.Initialize( - nullptr, nullptr, nullptr, &ConfigureAndroidCompositing); + WebViewImpl* web_view_impl = helper_.Initialize(nullptr, nullptr, nullptr, + &ConfigureAndroidCompositing); int page_width = 320; int page_height = 590; @@ -2329,8 +2320,7 @@ browser_controls_height, 0, true); frame_test_helpers::LoadFrame(web_view_impl->MainFrameImpl(), "about:blank"); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); - + UpdateAllLifecyclePhases(); Document* document = ToLocalFrame(web_view_impl->GetPage()->MainFrame())->GetDocument();
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc index 9d04f6e..8ded6d90 100644 --- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc +++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
@@ -312,7 +312,8 @@ frame_begin_time); } -void WebFrameWidgetImpl::UpdateLifecycle(LifecycleUpdate requested_update) { +void WebFrameWidgetImpl::UpdateLifecycle(LifecycleUpdate requested_update, + LifecycleUpdateReason reason) { TRACE_EVENT0("blink", "WebFrameWidgetImpl::updateAllLifecyclePhases"); if (!LocalRootImpl()) return; @@ -320,7 +321,7 @@ DocumentLifecycle::AllowThrottlingScope throttling_scope( LocalRootImpl()->GetFrame()->GetDocument()->Lifecycle()); PageWidgetDelegate::UpdateLifecycle(*GetPage(), *LocalRootImpl()->GetFrame(), - requested_update); + requested_update, reason); UpdateLayerTreeBackgroundColor(); }
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.h b/third_party/blink/renderer/core/frame/web_frame_widget_impl.h index 2ca5a22..c9ead4e 100644 --- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.h +++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.h
@@ -85,7 +85,8 @@ void SetSuppressFrameRequestsWorkaroundFor704763Only(bool) final; void BeginFrame(base::TimeTicks last_frame_time) override; void RecordEndOfFrameMetrics(base::TimeTicks) override; - void UpdateLifecycle(LifecycleUpdate requested_update) override; + void UpdateLifecycle(LifecycleUpdate requested_update, + LifecycleUpdateReason reason) override; void PaintContent(cc::PaintCanvas*, const WebRect&) override; void LayoutAndPaintAsync(base::OnceClosure callback) override; void CompositeAndReadbackAsync(
diff --git a/third_party/blink/renderer/core/frame/web_view_frame_widget.cc b/third_party/blink/renderer/core/frame/web_view_frame_widget.cc index 96827f7a..9533a997 100644 --- a/third_party/blink/renderer/core/frame/web_view_frame_widget.cc +++ b/third_party/blink/renderer/core/frame/web_view_frame_widget.cc
@@ -61,8 +61,9 @@ web_view_->RecordEndOfFrameMetrics(frame_begin_time); } -void WebViewFrameWidget::UpdateLifecycle(LifecycleUpdate requested_update) { - web_view_->UpdateLifecycle(requested_update); +void WebViewFrameWidget::UpdateLifecycle(LifecycleUpdate requested_update, + LifecycleUpdateReason reason) { + web_view_->UpdateLifecycle(requested_update, reason); } void WebViewFrameWidget::PaintContent(cc::PaintCanvas* canvas,
diff --git a/third_party/blink/renderer/core/frame/web_view_frame_widget.h b/third_party/blink/renderer/core/frame/web_view_frame_widget.h index b6444435..e9217a0d 100644 --- a/third_party/blink/renderer/core/frame/web_view_frame_widget.h +++ b/third_party/blink/renderer/core/frame/web_view_frame_widget.h
@@ -50,7 +50,8 @@ void SetSuppressFrameRequestsWorkaroundFor704763Only(bool) final; void BeginFrame(base::TimeTicks last_frame_time) override; void RecordEndOfFrameMetrics(base::TimeTicks frame_begin_time) override; - void UpdateLifecycle(LifecycleUpdate requested_update) override; + void UpdateLifecycle(LifecycleUpdate requested_update, + LifecycleUpdateReason reason) override; void PaintContent(cc::PaintCanvas*, const WebRect& view_port) override; void LayoutAndPaintAsync(base::OnceClosure callback) override; void CompositeAndReadbackAsync(
diff --git a/third_party/blink/renderer/core/html/forms/external_popup_menu_test.cc b/third_party/blink/renderer/core/html/forms/external_popup_menu_test.cc index cce8dd3..a6888218 100644 --- a/third_party/blink/renderer/core/html/forms/external_popup_menu_test.cc +++ b/third_party/blink/renderer/core/html/forms/external_popup_menu_test.cc
@@ -115,7 +115,8 @@ void LoadFrame(const std::string& file_name) { frame_test_helpers::LoadFrame(MainFrame(), base_url_ + file_name); WebView()->Resize(WebSize(800, 600)); - WebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + WebView()->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); } WebViewImpl* WebView() const { return helper_.GetWebView(); } @@ -135,7 +136,8 @@ LoadFrame("select_mid_screen.html"); WebView()->Resize(WebSize(100, 100)); - WebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + WebView()->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); HTMLSelectElement* select = ToHTMLSelectElement( MainFrame()->GetFrame()->GetDocument()->getElementById("select"));
diff --git a/third_party/blink/renderer/core/html/forms/password_input_type_test.cc b/third_party/blink/renderer/core/html/forms/password_input_type_test.cc index e85ad1b7..75bf907 100644 --- a/third_party/blink/renderer/core/html/forms/password_input_type_test.cc +++ b/third_party/blink/renderer/core/html/forms/password_input_type_test.cc
@@ -72,7 +72,8 @@ MockInsecureInputService mock_service(page_holder->GetFrame()); page_holder->GetDocument().body()->SetInnerHTMLFromString( "<input type='password'>"); - page_holder->GetDocument().View()->UpdateAllLifecyclePhases(); + page_holder->GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); blink::test::RunPendingTasks(); EXPECT_TRUE(mock_service.PasswordFieldVisibleCalled()); } @@ -90,7 +91,8 @@ SecureContextState::kSecure); page_holder->GetDocument().body()->SetInnerHTMLFromString( "<input type='password'>"); - page_holder->GetDocument().View()->UpdateAllLifecyclePhases(); + page_holder->GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); // No message should have been sent from a secure context. blink::test::RunPendingTasks(); EXPECT_FALSE(mock_service.PasswordFieldVisibleCalled()); @@ -104,7 +106,8 @@ MockInsecureInputService mock_service(page_holder->GetFrame()); page_holder->GetDocument().body()->SetInnerHTMLFromString( "<input type='password' style='display:none;'>"); - page_holder->GetDocument().View()->UpdateAllLifecyclePhases(); + page_holder->GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); blink::test::RunPendingTasks(); // The message should not be sent for a hidden password field. EXPECT_FALSE(mock_service.PasswordFieldVisibleCalled()); @@ -113,7 +116,8 @@ HTMLInputElement* input = ToHTMLInputElement(page_holder->GetDocument().body()->firstChild()); input->setAttribute("style", "", ASSERT_NO_EXCEPTION); - page_holder->GetDocument().View()->UpdateAllLifecyclePhases(); + page_holder->GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); blink::test::RunPendingTasks(); EXPECT_TRUE(mock_service.PasswordFieldVisibleCalled()); } @@ -126,7 +130,8 @@ MockInsecureInputService mock_service(page_holder->GetFrame()); page_holder->GetDocument().body()->SetInnerHTMLFromString( "<input type='text'>"); - page_holder->GetDocument().View()->UpdateAllLifecyclePhases(); + page_holder->GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); // The message should not be sent for a non-password field. blink::test::RunPendingTasks(); EXPECT_FALSE(mock_service.PasswordFieldVisibleCalled()); @@ -135,7 +140,8 @@ HTMLInputElement* input = ToHTMLInputElement(page_holder->GetDocument().body()->firstChild()); input->setType("password"); - page_holder->GetDocument().View()->UpdateAllLifecyclePhases(); + page_holder->GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); blink::test::RunPendingTasks(); EXPECT_TRUE(mock_service.PasswordFieldVisibleCalled()); } @@ -149,7 +155,8 @@ MockInsecureInputService mock_service(page_holder->GetFrame()); page_holder->GetDocument().body()->SetInnerHTMLFromString( "<input type='password' style='display:none;'>"); - page_holder->GetDocument().View()->UpdateAllLifecyclePhases(); + page_holder->GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); blink::test::RunPendingTasks(); // The message should not be sent for a hidden password field. EXPECT_FALSE(mock_service.PasswordFieldVisibleCalled()); @@ -159,7 +166,8 @@ ToHTMLInputElement(page_holder->GetDocument().body()->firstChild()); input->setType("text"); input->setAttribute("style", "", ASSERT_NO_EXCEPTION); - page_holder->GetDocument().View()->UpdateAllLifecyclePhases(); + page_holder->GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); blink::test::RunPendingTasks(); EXPECT_FALSE(mock_service.PasswordFieldVisibleCalled()); } @@ -172,7 +180,8 @@ MockInsecureInputService mock_service(page_holder->GetFrame()); page_holder->GetDocument().body()->SetInnerHTMLFromString( "<input type='password'>"); - page_holder->GetDocument().View()->UpdateAllLifecyclePhases(); + page_holder->GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); blink::test::RunPendingTasks(); EXPECT_TRUE(mock_service.PasswordFieldVisibleCalled()); EXPECT_EQ(0u, mock_service.NumPasswordFieldsInvisibleCalls()); @@ -181,7 +190,8 @@ HTMLInputElement* input = ToHTMLInputElement(page_holder->GetDocument().body()->firstChild()); input->setAttribute("style", "display:none;", ASSERT_NO_EXCEPTION); - page_holder->GetDocument().View()->UpdateAllLifecyclePhases(); + page_holder->GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); blink::test::RunPendingTasks(); EXPECT_EQ(1u, mock_service.NumPasswordFieldsInvisibleCalls()); } @@ -194,7 +204,8 @@ MockInsecureInputService mock_service(page_holder->GetFrame()); page_holder->GetDocument().body()->SetInnerHTMLFromString( "<input type='password'><input type='password'>"); - page_holder->GetDocument().View()->UpdateAllLifecyclePhases(); + page_holder->GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); blink::test::RunPendingTasks(); EXPECT_EQ(0u, mock_service.NumPasswordFieldsInvisibleCalls()); @@ -203,25 +214,29 @@ HTMLInputElement* input = ToHTMLInputElement(page_holder->GetDocument().body()->firstChild()); input->setAttribute("style", "display:none;", ASSERT_NO_EXCEPTION); - page_holder->GetDocument().View()->UpdateAllLifecyclePhases(); + page_holder->GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); blink::test::RunPendingTasks(); EXPECT_EQ(0u, mock_service.NumPasswordFieldsInvisibleCalls()); // When all inputs are invisible, then a message should be sent. input = ToHTMLInputElement(page_holder->GetDocument().body()->lastChild()); input->setAttribute("style", "display:none;", ASSERT_NO_EXCEPTION); - page_holder->GetDocument().View()->UpdateAllLifecyclePhases(); + page_holder->GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); blink::test::RunPendingTasks(); EXPECT_EQ(1u, mock_service.NumPasswordFieldsInvisibleCalls()); // If the count of visible inputs goes positive again and then back to // zero, a message should be sent again. input->setAttribute("style", "", ASSERT_NO_EXCEPTION); - page_holder->GetDocument().View()->UpdateAllLifecyclePhases(); + page_holder->GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); blink::test::RunPendingTasks(); EXPECT_EQ(1u, mock_service.NumPasswordFieldsInvisibleCalls()); input->setAttribute("style", "display:none;", ASSERT_NO_EXCEPTION); - page_holder->GetDocument().View()->UpdateAllLifecyclePhases(); + page_holder->GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); blink::test::RunPendingTasks(); EXPECT_EQ(2u, mock_service.NumPasswordFieldsInvisibleCalls()); } @@ -234,7 +249,8 @@ MockInsecureInputService mock_service(page_holder->GetFrame()); page_holder->GetDocument().body()->SetInnerHTMLFromString( "<div><input type='password'></div>"); - page_holder->GetDocument().View()->UpdateAllLifecyclePhases(); + page_holder->GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); blink::test::RunPendingTasks(); EXPECT_EQ(0u, mock_service.NumPasswordFieldsInvisibleCalls()); @@ -242,18 +258,21 @@ HTMLElement* div = ToHTMLDivElement(page_holder->GetDocument().body()->firstChild()); div->setAttribute("style", "display:none;", ASSERT_NO_EXCEPTION); - page_holder->GetDocument().View()->UpdateAllLifecyclePhases(); + page_holder->GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); blink::test::RunPendingTasks(); EXPECT_EQ(1u, mock_service.NumPasswordFieldsInvisibleCalls()); // If the containing div becomes visible and then invisible again, a message // should be sent. div->setAttribute("style", "", ASSERT_NO_EXCEPTION); - page_holder->GetDocument().View()->UpdateAllLifecyclePhases(); + page_holder->GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); blink::test::RunPendingTasks(); EXPECT_EQ(1u, mock_service.NumPasswordFieldsInvisibleCalls()); div->setAttribute("style", "display:none;", ASSERT_NO_EXCEPTION); - page_holder->GetDocument().View()->UpdateAllLifecyclePhases(); + page_holder->GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); blink::test::RunPendingTasks(); EXPECT_EQ(2u, mock_service.NumPasswordFieldsInvisibleCalls()); } @@ -266,7 +285,8 @@ MockInsecureInputService mock_service(page_holder->GetFrame()); page_holder->GetDocument().body()->SetInnerHTMLFromString( "<input type='password'><input type='password'>"); - page_holder->GetDocument().View()->UpdateAllLifecyclePhases(); + page_holder->GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); blink::test::RunPendingTasks(); EXPECT_EQ(0u, mock_service.NumPasswordFieldsInvisibleCalls()); @@ -275,14 +295,16 @@ HTMLInputElement* input = ToHTMLInputElement(page_holder->GetDocument().body()->firstChild()); input->setType("text"); - page_holder->GetDocument().View()->UpdateAllLifecyclePhases(); + page_holder->GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); blink::test::RunPendingTasks(); EXPECT_EQ(0u, mock_service.NumPasswordFieldsInvisibleCalls()); // When all inputs are no longer passwords, then a message should be sent. input = ToHTMLInputElement(page_holder->GetDocument().body()->lastChild()); input->setType("text"); - page_holder->GetDocument().View()->UpdateAllLifecyclePhases(); + page_holder->GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); blink::test::RunPendingTasks(); EXPECT_EQ(1u, mock_service.NumPasswordFieldsInvisibleCalls()); } @@ -295,12 +317,14 @@ MockInsecureInputService mock_service(page_holder->GetFrame()); page_holder->GetDocument().body()->SetInnerHTMLFromString( "<input type='password'>"); - page_holder->GetDocument().View()->UpdateAllLifecyclePhases(); + page_holder->GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); // Make the password field invisible in the same task. HTMLInputElement* input = ToHTMLInputElement(page_holder->GetDocument().body()->firstChild()); input->setType("text"); - page_holder->GetDocument().View()->UpdateAllLifecyclePhases(); + page_holder->GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); blink::test::RunPendingTasks(); // Only a single Mojo message should have been sent, with the latest state of // the page (which is that no password fields are visible). @@ -316,7 +340,8 @@ MockInsecureInputService mock_service(page_holder->GetFrame()); page_holder->GetDocument().body()->SetInnerHTMLFromString( "<input type='password'>"); - page_holder->GetDocument().View()->UpdateAllLifecyclePhases(); + page_holder->GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); blink::test::RunPendingTasks(); EXPECT_EQ(0u, mock_service.DidEditFieldCalls()); // Simulate a text field edit. @@ -342,7 +367,8 @@ SecureContextState::kSecure); page_holder->GetDocument().body()->SetInnerHTMLFromString( "<input type='password'>"); - page_holder->GetDocument().View()->UpdateAllLifecyclePhases(); + page_holder->GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); // Simulate a text field edit. page_holder->GetDocument().MaybeQueueSendDidEditFieldInInsecureContext(); // No message should have been sent from a secure context.
diff --git a/third_party/blink/renderer/core/html/forms/text_control_element_test.cc b/third_party/blink/renderer/core/html/forms/text_control_element_test.cc index 28d9d5d..8b55264a 100644 --- a/third_party/blink/renderer/core/html/forms/text_control_element_test.cc +++ b/third_party/blink/renderer/core/html/forms/text_control_element_test.cc
@@ -30,7 +30,8 @@ HTMLInputElement& Input() const { return *input_; } void UpdateAllLifecyclePhases() { - GetDocument().View()->UpdateAllLifecyclePhases(); + GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); } private:
diff --git a/third_party/blink/renderer/core/html/html_content_element_test.cc b/third_party/blink/renderer/core/html/html_content_element_test.cc index 09d8a0c..dca37d4 100644 --- a/third_party/blink/renderer/core/html/html_content_element_test.cc +++ b/third_party/blink/renderer/core/html/html_content_element_test.cc
@@ -30,7 +30,8 @@ Element* host = GetDocument().getElementById("host"); ShadowRoot& root = host->CreateV0ShadowRootForTesting(); - GetDocument().View()->UpdateAllLifecyclePhases(); + GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); auto* content = GetDocument().CreateRawElement(html_names::kContentTag); auto* fallback = GetDocument().CreateRawElement(html_names::kSpanTag);
diff --git a/third_party/blink/renderer/core/html/html_object_element_test.cc b/third_party/blink/renderer/core/html/html_object_element_test.cc index c7afb8a1..976fd39f 100644 --- a/third_party/blink/renderer/core/html/html_object_element_test.cc +++ b/third_party/blink/renderer/core/html/html_object_element_test.cc
@@ -35,7 +35,8 @@ Node* slot = object->GetShadowRoot()->firstChild(); ASSERT_TRUE(slot); - GetDocument().View()->UpdateAllLifecyclePhases(); + GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); object->RenderFallbackContent(nullptr); GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kInStyleRecalc);
diff --git a/third_party/blink/renderer/core/html/html_slot_element_test.cc b/third_party/blink/renderer/core/html/html_slot_element_test.cc index 0089908..f94036d9 100644 --- a/third_party/blink/renderer/core/html/html_slot_element_test.cc +++ b/third_party/blink/renderer/core/html/html_slot_element_test.cc
@@ -157,7 +157,8 @@ R"HTML(<span><slot /></span>)HTML"); Element& shadow_span = *ToElement(shadow_root.firstChild()); - GetDocument().View()->UpdateAllLifecyclePhases(); + GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); shadow_span.setAttribute(html_names::kStyleAttr, "display:block");
diff --git a/third_party/blink/renderer/core/html/shadow/progress_shadow_element_test.cc b/third_party/blink/renderer/core/html/shadow/progress_shadow_element_test.cc index 213362b..3536077 100644 --- a/third_party/blink/renderer/core/html/shadow/progress_shadow_element_test.cc +++ b/third_party/blink/renderer/core/html/shadow/progress_shadow_element_test.cc
@@ -37,7 +37,8 @@ Element* shadow_element = ToElement(progress->GetShadowRoot()->firstChild()); ASSERT_TRUE(shadow_element); - GetDocument().View()->UpdateAllLifecyclePhases(); + GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); progress->LazyReattachIfAttached(); GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kInStyleRecalc);
diff --git a/third_party/blink/renderer/core/input/gesture_manager.cc b/third_party/blink/renderer/core/input/gesture_manager.cc index bc034380..b148e1b 100644 --- a/third_party/blink/renderer/core/input/gesture_manager.cc +++ b/third_party/blink/renderer/core/input/gesture_manager.cc
@@ -256,8 +256,10 @@ // http://crbug.com/398920 if (current_hit_test.InnerNode()) { LocalFrame& main_frame = frame_->LocalFrameRoot(); - if (main_frame.View()) - main_frame.View()->UpdateAllLifecyclePhases(); + if (main_frame.View()) { + main_frame.View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kOther); + } adjusted_point = frame_view->ConvertFromRootFrame(tapped_position); current_hit_test = event_handling_util::HitTestResultInFrame( frame_, HitTestLocation(adjusted_point), hit_type);
diff --git a/third_party/blink/renderer/core/input/mouse_event_manager.cc b/third_party/blink/renderer/core/input/mouse_event_manager.cc index 8357c59f62..f7b73744 100644 --- a/third_party/blink/renderer/core/input/mouse_event_manager.cc +++ b/third_party/blink/renderer/core/input/mouse_event_manager.cc
@@ -1100,8 +1100,29 @@ } void MouseEventManager::ResetDragSource() { + // Check validity of drag source. if (!frame_->GetPage()) return; + + Node* drag_src = GetDragState().drag_src_; + if (!drag_src) + return; + + Frame* drag_src_frame = drag_src->GetDocument().GetFrame(); + if (!drag_src_frame) { + // The frame containing the drag_src has been navigated away, so the + // drag_src is no longer has an owning frame and is invalid. + // See https://crbug.com/903705 for more details. + GetDragState().drag_src_ = nullptr; + return; + } + + // Only allow resetting drag_src_ if the frame requesting reset is above the + // drag_src_ node's frame in the frame hierarchy. This way, unrelated frames + // can't reset a drag state. + if (!drag_src_frame->Tree().IsDescendantOf(frame_)) + return; + GetDragState().drag_src_ = nullptr; }
diff --git a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc index cf328a32..627cef2 100644 --- a/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_overlay_agent.cc
@@ -504,7 +504,8 @@ needs_update_ = false; RebuildOverlayPage(); } - OverlayMainFrame()->View()->UpdateAllLifecyclePhases(); + OverlayMainFrame()->View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kOther); } if (page_overlay_ && page_overlay_->GetGraphicsLayer())
diff --git a/third_party/blink/renderer/core/inspector/main_thread_debugger_test.cc b/third_party/blink/renderer/core/inspector/main_thread_debugger_test.cc index f533220..6f87c32 100644 --- a/third_party/blink/renderer/core/inspector/main_thread_debugger_test.cc +++ b/third_party/blink/renderer/core/inspector/main_thread_debugger_test.cc
@@ -23,7 +23,8 @@ // The following steps would cause either style update or layout, it should // never crash. document.View()->ViewportSizeChanged(true, true); - document.View()->UpdateAllLifecyclePhases(); + document.View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); document.UpdateStyleAndLayoutIgnorePendingStylesheets(); document.UpdateStyleAndLayoutTree();
diff --git a/third_party/blink/renderer/core/layout/jank_tracker_test.cc b/third_party/blink/renderer/core/layout/jank_tracker_test.cc index 5189747..abe86ef 100644 --- a/third_party/blink/renderer/core/layout/jank_tracker_test.cc +++ b/third_party/blink/renderer/core/layout/jank_tracker_test.cc
@@ -25,7 +25,10 @@ WebInputEvent::Modifiers::kLeftButtonDown, CurrentTimeTicks())); } - void UpdateAllLifecyclePhases() { GetFrameView().UpdateAllLifecyclePhases(); } + void UpdateAllLifecyclePhases() { + GetFrameView().UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); + } }; TEST_F(JankTrackerTest, SimpleBlockMovement) {
diff --git a/third_party/blink/renderer/core/layout/layout_geometry_map_test.cc b/third_party/blink/renderer/core/layout/layout_geometry_map_test.cc index 99f7e4d..d67642b52 100644 --- a/third_party/blink/renderer/core/layout/layout_geometry_map_test.cc +++ b/third_party/blink/renderer/core/layout/layout_geometry_map_test.cc
@@ -162,7 +162,8 @@ } void UpdateAllLifecyclePhases(WebView* web_view) { - web_view->MainFrameWidget()->UpdateAllLifecyclePhases(); + web_view->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); } const std::string base_url_;
diff --git a/third_party/blink/renderer/core/layout/layout_grid.cc b/third_party/blink/renderer/core/layout/layout_grid.cc index 2df38ce..a6e6e10 100644 --- a/third_party/blink/renderer/core/layout/layout_grid.cc +++ b/third_party/blink/renderer/core/layout/layout_grid.cc
@@ -323,13 +323,20 @@ ComputeTrackSizesForDefiniteSize( kForRows, AvailableLogicalHeight(kExcludeMarginBorderPadding)); } else { - ComputeTrackSizesForIndefiniteSize(track_sizing_algorithm_, kForRows, - min_content_height_, - max_content_height_); + ComputeTrackSizesForIndefiniteSize(track_sizing_algorithm_, kForRows); } LayoutUnit track_based_logical_height = track_sizing_algorithm_.ComputeTrackBasedSize() + - BorderAndPaddingLogicalHeight() + ScrollbarLogicalHeight(); + BorderAndPaddingLogicalHeight(); + + // TODO(rego): We shouldn't need this once crbug.com/906530 is fixed. + // Right now we need this because + // LayoutBox::ComputeContentAndScrollbarLogicalHeightUsing() is adding the + // ScrollbarLogicalHeight() for the intrinsic height cases. But that's + // causing more problems as described in the bug linked before. + if (!StyleRef().LogicalHeight().IsIntrinsic()) + track_based_logical_height += ScrollbarLogicalHeight(); + SetLogicalHeight(track_based_logical_height); LayoutUnit old_client_after_edge = ClientLogicalBottom(); @@ -512,8 +519,8 @@ } } - ComputeTrackSizesForIndefiniteSize(algorithm, kForColumns, min_logical_width, - max_logical_width); + ComputeTrackSizesForIndefiniteSize(algorithm, kForColumns, &min_logical_width, + &max_logical_width); LayoutUnit scrollbar_width = LayoutUnit(ScrollbarLogicalWidth()); min_logical_width += scrollbar_width; @@ -523,54 +530,26 @@ void LayoutGrid::ComputeTrackSizesForIndefiniteSize( GridTrackSizingAlgorithm& algo, GridTrackSizingDirection direction, - LayoutUnit& min_intrinsic_size, - LayoutUnit& max_intrinsic_size) const { + LayoutUnit* min_intrinsic_size, + LayoutUnit* max_intrinsic_size) const { const Grid& grid = algo.GetGrid(); algo.Setup(direction, NumTracks(direction, grid), base::nullopt); algo.Run(); - min_intrinsic_size = algo.MinContentSize(); - max_intrinsic_size = algo.MaxContentSize(); - size_t number_of_tracks = algo.Tracks(direction).size(); LayoutUnit total_gutters_size = GuttersSize(grid, direction, 0, number_of_tracks, base::nullopt); - min_intrinsic_size += total_gutters_size; - max_intrinsic_size += total_gutters_size; + + if (min_intrinsic_size) + *min_intrinsic_size = algo.MinContentSize() + total_gutters_size; + if (max_intrinsic_size) + *max_intrinsic_size = algo.MaxContentSize() + total_gutters_size; #if DCHECK_IS_ON() DCHECK(algo.TracksAreWiderThanMinTrackBreadth()); #endif } -LayoutUnit LayoutGrid::ComputeIntrinsicLogicalContentHeightUsing( - const Length& logical_height_length, - LayoutUnit intrinsic_content_height, - LayoutUnit border_and_padding) const { - if (logical_height_length.IsMinContent()) - return min_content_height_; - - if (logical_height_length.IsMaxContent()) - return max_content_height_; - - if (logical_height_length.IsFitContent()) { - if (min_content_height_ == -1 || max_content_height_ == -1) - return LayoutUnit(-1); - LayoutUnit fill_available_extent = - ContainingBlock()->AvailableLogicalHeight(kExcludeMarginBorderPadding); - return std::min<LayoutUnit>( - max_content_height_, - std::max(min_content_height_, fill_available_extent)); - } - - if (logical_height_length.IsFillAvailable()) - return ContainingBlock()->AvailableLogicalHeight( - kExcludeMarginBorderPadding) - - border_and_padding; - NOTREACHED(); - return LayoutUnit(); -} - LayoutUnit LayoutGrid::OverrideContainingBlockContentSizeForChild( const LayoutBox& child, GridTrackSizingDirection direction) {
diff --git a/third_party/blink/renderer/core/layout/layout_grid.h b/third_party/blink/renderer/core/layout/layout_grid.h index 00cd7ee..8d08fb1fe 100644 --- a/third_party/blink/renderer/core/layout/layout_grid.h +++ b/third_party/blink/renderer/core/layout/layout_grid.h
@@ -132,11 +132,6 @@ LayoutUnit& min_logical_width, LayoutUnit& max_logical_width) const override; - LayoutUnit ComputeIntrinsicLogicalContentHeightUsing( - const Length& logical_height_length, - LayoutUnit intrinsic_content_height, - LayoutUnit border_and_padding) const override; - void AddChild(LayoutObject* new_child, LayoutObject* before_child = nullptr) override; void RemoveChild(LayoutObject*) override; @@ -184,10 +179,11 @@ GridTrackSizingDirection AutoPlacementMajorAxisDirection() const; GridTrackSizingDirection AutoPlacementMinorAxisDirection() const; - void ComputeTrackSizesForIndefiniteSize(GridTrackSizingAlgorithm&, - GridTrackSizingDirection, - LayoutUnit& min_intrinsic_size, - LayoutUnit& max_intrinsic_size) const; + void ComputeTrackSizesForIndefiniteSize( + GridTrackSizingAlgorithm&, + GridTrackSizingDirection, + LayoutUnit* min_intrinsic_size = nullptr, + LayoutUnit* max_intrinsic_size = nullptr) const; void ComputeTrackSizesForDefiniteSize(GridTrackSizingDirection, LayoutUnit free_space); @@ -319,9 +315,6 @@ OutOfFlowPositionsMap column_of_positioned_item_; OutOfFlowPositionsMap row_of_positioned_item_; - LayoutUnit min_content_height_{-1}; - LayoutUnit max_content_height_{-1}; - bool has_any_orthogonal_item_{false}; bool baseline_items_cached_{false}; base::Optional<bool> has_definite_logical_height_;
diff --git a/third_party/blink/renderer/core/layout/layout_object_test.cc b/third_party/blink/renderer/core/layout/layout_object_test.cc index bc840f270..d74784b 100644 --- a/third_party/blink/renderer/core/layout/layout_object_test.cc +++ b/third_party/blink/renderer/core/layout/layout_object_test.cc
@@ -812,7 +812,8 @@ class LayoutObjectSimTest : public SimTest { public: bool DocumentHasTouchActionRegion(const EventHandlerRegistry& registry) { - GetDocument().View()->UpdateAllLifecyclePhases(); + GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); return registry.HasEventHandlers( EventHandlerRegistry::EventHandlerClass::kTouchAction); } @@ -886,7 +887,8 @@ <div id='target'>target</div> )HTML"); - GetDocument().View()->UpdateAllLifecyclePhases(); + GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); Element* iframe_element = GetDocument().QuerySelector("iframe"); HTMLFrameOwnerElement* frame_owner_element = ToHTMLFrameOwnerElement(iframe_element); @@ -897,7 +899,8 @@ Element* occluder = GetDocument().getElementById("occluder"); occluder->SetInlineStyleProperty(CSSPropertyMarginTop, "-150px"); - GetDocument().View()->UpdateAllLifecyclePhases(); + GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); result = target->GetLayoutObject()->HitTestForOcclusion(); EXPECT_EQ(result.InnerNode(), occluder); }
diff --git a/third_party/blink/renderer/core/layout/layout_table_test.cc b/third_party/blink/renderer/core/layout/layout_table_test.cc index 2cd8931..d43c46e 100644 --- a/third_party/blink/renderer/core/layout/layout_table_test.cc +++ b/third_party/blink/renderer/core/layout/layout_table_test.cc
@@ -36,7 +36,8 @@ ToElement(child->GetNode()) ->setAttribute(html_names::kStyleAttr, "outline: 2px solid black"); - target->GetFrameView()->UpdateAllLifecyclePhases(); + target->GetFrameView()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); EXPECT_EQ(LayoutRect(-2, -2, 104, 204), target->SelfVisualOverflowRect()); EXPECT_EQ(LayoutRect(-2, -2, 104, 204), child->SelfVisualOverflowRect());
diff --git a/third_party/blink/renderer/core/layout/map_coordinates_test.cc b/third_party/blink/renderer/core/layout/map_coordinates_test.cc index 3180ae1..a4fad37 100644 --- a/third_party/blink/renderer/core/layout/map_coordinates_test.cc +++ b/third_party/blink/renderer/core/layout/map_coordinates_test.cc
@@ -725,7 +725,8 @@ ChildDocument().View()->LayoutViewport()->SetScrollOffset( ScrollOffset(0.0, 1000), kProgrammaticScroll); - ChildDocument().View()->UpdateAllLifecyclePhases(); + ChildDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); Element* target = ChildDocument().getElementById("target"); ASSERT_TRUE(target);
diff --git a/third_party/blink/renderer/core/layout/scrollbars_test.cc b/third_party/blink/renderer/core/layout/scrollbars_test.cc index 11674cb..e26fe4b 100644 --- a/third_party/blink/renderer/core/layout/scrollbars_test.cc +++ b/third_party/blink/renderer/core/layout/scrollbars_test.cc
@@ -220,7 +220,8 @@ "<body>" "</body>", base_url); - web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases(); + web_view_impl->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); Document* document = ToLocalFrame(web_view_impl->GetPage()->MainFrame())->GetDocument();
diff --git a/third_party/blink/renderer/core/loader/programmatic_scroll_test.cc b/third_party/blink/renderer/core/loader/programmatic_scroll_test.cc index ec50a05..be0ecb6b 100644 --- a/third_party/blink/renderer/core/loader/programmatic_scroll_test.cc +++ b/third_party/blink/renderer/core/loader/programmatic_scroll_test.cc
@@ -53,7 +53,8 @@ WebViewImpl* web_view = web_view_helper.InitializeAndLoad(base_url_ + "long_scroll.html"); web_view->Resize(WebSize(1000, 1000)); - web_view->MainFrameWidget()->UpdateAllLifecyclePhases(); + web_view->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); FrameLoader& loader = web_view->MainFrameImpl()->GetFrame()->Loader(); loader.GetDocumentLoader()->SetLoadType(WebFrameLoadType::kBackForward); @@ -85,7 +86,8 @@ WebViewImpl* web_view = web_view_helper.InitializeAndLoad(base_url_ + "long_scroll.html"); web_view->Resize(WebSize(1000, 1000)); - web_view->MainFrameWidget()->UpdateAllLifecyclePhases(); + web_view->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); FrameLoader& loader = web_view->MainFrameImpl()->GetFrame()->Loader(); loader.GetDocumentLoader()->SetLoadType(WebFrameLoadType::kBackForward); @@ -114,7 +116,8 @@ WebViewImpl* web_view = web_view_helper.InitializeAndLoad(base_url_ + "long_scroll.html"); web_view->Resize(WebSize(1000, 1000)); - web_view->MainFrameWidget()->UpdateAllLifecyclePhases(); + web_view->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); FrameLoader& loader = web_view->MainFrameImpl()->GetFrame()->Loader(); loader.GetDocumentLoader()->SetLoadType(WebFrameLoadType::kBackForward);
diff --git a/third_party/blink/renderer/core/page/context_menu_controller_test.cc b/third_party/blink/renderer/core/page/context_menu_controller_test.cc index 17386e5..4090b43 100644 --- a/third_party/blink/renderer/core/page/context_menu_controller_test.cc +++ b/third_party/blink/renderer/core/page/context_menu_controller_test.cc
@@ -67,7 +67,8 @@ WebLocalFrameImpl* local_main_frame = web_view_helper_.LocalMainFrame(); local_main_frame->ViewImpl()->MainFrameWidget()->Resize(WebSize(640, 480)); - local_main_frame->ViewImpl()->MainFrameWidget()->UpdateAllLifecyclePhases(); + local_main_frame->ViewImpl()->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); } bool ShowContextMenu(const LayoutPoint& location, WebMenuSourceType source) {
diff --git a/third_party/blink/renderer/core/page/page_animator.cc b/third_party/blink/renderer/core/page/page_animator.cc index 19099bd..82157069 100644 --- a/third_party/blink/renderer/core/page/page_animator.cc +++ b/third_party/blink/renderer/core/page/page_animator.cc
@@ -103,11 +103,13 @@ page_->GetChromeClient().ScheduleAnimation(frame->View()); } -void PageAnimator::UpdateAllLifecyclePhases(LocalFrame& root_frame) { +void PageAnimator::UpdateAllLifecyclePhases( + LocalFrame& root_frame, + DocumentLifecycle::LifecycleUpdateReason reason) { LocalFrameView* view = root_frame.View(); base::AutoReset<bool> servicing(&updating_layout_and_style_for_painting_, true); - view->UpdateAllLifecyclePhases(); + view->UpdateAllLifecyclePhases(reason); } void PageAnimator::UpdateAllLifecyclePhasesExceptPaint(LocalFrame& root_frame) {
diff --git a/third_party/blink/renderer/core/page/page_animator.h b/third_party/blink/renderer/core/page/page_animator.h index 3ee99c4..24e2d52 100644 --- a/third_party/blink/renderer/core/page/page_animator.h +++ b/third_party/blink/renderer/core/page/page_animator.h
@@ -7,6 +7,7 @@ #include "third_party/blink/renderer/core/animation/animation_clock.h" #include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/core/dom/document_lifecycle.h" #include "third_party/blink/renderer/platform/heap/handle.h" namespace blink { @@ -31,7 +32,9 @@ void SetSuppressFrameRequestsWorkaroundFor704763Only(bool); // See documents of methods with the same names in LocalFrameView class. - void UpdateAllLifecyclePhases(LocalFrame& root_frame); + void UpdateAllLifecyclePhases( + LocalFrame& root_frame, + DocumentLifecycle::LifecycleUpdateReason reason); void UpdateAllLifecyclePhasesExceptPaint(LocalFrame& root_frame); void UpdateLifecycleToLayoutClean(LocalFrame& root_frame); AnimationClock& Clock() { return animation_clock_; }
diff --git a/third_party/blink/renderer/core/page/page_overlay_test.cc b/third_party/blink/renderer/core/page/page_overlay_test.cc index 93b5706..08ce4c6 100644 --- a/third_party/blink/renderer/core/page/page_overlay_test.cc +++ b/third_party/blink/renderer/core/page/page_overlay_test.cc
@@ -67,7 +67,8 @@ nullptr /* web_view_client */, nullptr /* web_widget_client */); GetWebView()->Resize(WebSize(kViewportWidth, kViewportHeight)); - GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); } WebViewImpl* GetWebView() const { return helper_.GetWebView(); } @@ -116,7 +117,8 @@ std::unique_ptr<PageOverlay> page_overlay = CreateSolidYellowOverlay(); page_overlay->Update(); - GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); GraphicsLayer* graphics_layer = page_overlay->GetGraphicsLayer(); WebRect rect(0, 0, kViewportWidth, kViewportHeight); @@ -139,7 +141,8 @@ TEST_F(PageOverlayTest, PageOverlay_VisualRect) { std::unique_ptr<PageOverlay> page_overlay = CreateSolidYellowOverlay(); page_overlay->Update(); - GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); EXPECT_EQ(LayoutRect(0, 0, kViewportWidth, kViewportHeight), page_overlay->VisualRect()); }
diff --git a/third_party/blink/renderer/core/page/page_widget_delegate.cc b/third_party/blink/renderer/core/page/page_widget_delegate.cc index c3ba5e5c..56f1a47f 100644 --- a/third_party/blink/renderer/core/page/page_widget_delegate.cc +++ b/third_party/blink/renderer/core/page/page_widget_delegate.cc
@@ -61,13 +61,15 @@ void PageWidgetDelegate::UpdateLifecycle( Page& page, LocalFrame& root, - WebWidget::LifecycleUpdate requested_update) { + WebWidget::LifecycleUpdate requested_update, + WebWidget::LifecycleUpdateReason reason) { if (requested_update == WebWidget::LifecycleUpdate::kLayout) { page.Animator().UpdateLifecycleToLayoutClean(root); } else if (requested_update == WebWidget::LifecycleUpdate::kPrePaint) { page.Animator().UpdateAllLifecyclePhasesExceptPaint(root); } else { - page.Animator().UpdateAllLifecyclePhases(root); + page.Animator().UpdateAllLifecyclePhases( + root, static_cast<DocumentLifecycle::LifecycleUpdateReason>(reason)); } }
diff --git a/third_party/blink/renderer/core/page/page_widget_delegate.h b/third_party/blink/renderer/core/page/page_widget_delegate.h index e179a52..9d6e0ed 100644 --- a/third_party/blink/renderer/core/page/page_widget_delegate.h +++ b/third_party/blink/renderer/core/page/page_widget_delegate.h
@@ -82,7 +82,8 @@ // See comment of WebWidget::UpdateLifecycle. static void UpdateLifecycle(Page&, LocalFrame& root, - WebWidget::LifecycleUpdate requested_update); + WebWidget::LifecycleUpdate requested_update, + WebWidget::LifecycleUpdateReason reason); // See documents of methods with the same names in FrameView class. static void PaintContent(Page&,
diff --git a/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc b/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc index f8d00ec..f40e429 100644 --- a/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc +++ b/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc
@@ -113,7 +113,8 @@ void ExecuteScript(const WebString& code, WebLocalFrame& frame) { frame.ExecuteScript(WebScriptSource(code)); - frame.View()->MainFrameWidget()->UpdateAllLifecyclePhases(); + frame.View()->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); RunPendingTasks(); } @@ -191,7 +192,8 @@ } void UpdateAllLifecyclePhases(LocalFrameView* view) { - view->UpdateAllLifecyclePhases(); + view->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); } std::string base_url_;
diff --git a/third_party/blink/renderer/core/page/scrolling/scroll_metrics_test.cc b/third_party/blink/renderer/core/page/scrolling/scroll_metrics_test.cc index cb74342..0285f32 100644 --- a/third_party/blink/renderer/core/page/scrolling/scroll_metrics_test.cc +++ b/third_party/blink/renderer/core/page/scrolling/scroll_metrics_test.cc
@@ -42,7 +42,8 @@ void SetUpHtml(const char*); void Scroll(Element*, const WebGestureDevice); void UpdateAllLifecyclePhases() { - GetDocument().View()->UpdateAllLifecyclePhases(); + GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); } };
diff --git a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_test.cc b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_test.cc index 906536b..7e7b3bb 100644 --- a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_test.cc +++ b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_test.cc
@@ -77,7 +77,8 @@ // macOS attaches main frame scrollbars to the VisualViewport so the // VisualViewport layers need to be initialized. - GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); WebFrameWidgetBase* main_frame_widget = GetWebView()->MainFrameImpl()->FrameWidgetImpl(); main_frame_widget->SetRootGraphicsLayer(GetWebView() @@ -105,7 +106,8 @@ } void ForceFullCompositingUpdate() { - GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); } void RegisterMockedHttpURLLoad(const std::string& file_name) {
diff --git a/third_party/blink/renderer/core/page/spatial_navigation_test.cc b/third_party/blink/renderer/core/page/spatial_navigation_test.cc index 779ccf2..ca2fdfb 100644 --- a/third_party/blink/renderer/core/page/spatial_navigation_test.cc +++ b/third_party/blink/renderer/core/page/spatial_navigation_test.cc
@@ -61,7 +61,8 @@ } void UpdateAllLifecyclePhases(LocalFrameView* frame_view) { - frame_view->UpdateAllLifecyclePhases(); + frame_view->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); } };
diff --git a/third_party/blink/renderer/core/page/validation_message_overlay_delegate.cc b/third_party/blink/renderer/core/page/validation_message_overlay_delegate.cc index 9a2c75e50..0fd8a0f8 100644 --- a/third_party/blink/renderer/core/page/validation_message_overlay_delegate.cc +++ b/third_party/blink/renderer/core/page/validation_message_overlay_delegate.cc
@@ -120,7 +120,8 @@ // FindVisualRectNeedingUpdateScopeBase::CheckVisualRect(). FrameView().GetLayoutView()->SetSubtreeShouldCheckForPaintInvalidation(); - FrameView().UpdateAllLifecyclePhases(); + FrameView().UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kOther); } void ValidationMessageOverlayDelegate::EnsurePage(const PageOverlay& overlay, @@ -169,7 +170,9 @@ .SetInlineStyleProperty(CSSPropertyTransition, "none"); } // Get the size to decide position later. - FrameView().UpdateAllLifecyclePhases(); + // TODO(schenney): This says get size, so we only need to update to layout. + FrameView().UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kOther); bubble_size_ = container.VisibleBoundsInVisualViewport().Size(); // Add one because the content sometimes exceeds the exact width due to // rounding errors. @@ -178,7 +181,8 @@ bubble_size_.Width() / zoom_factor, CSSPrimitiveValue::UnitType::kPixels); container.setAttribute(html_names::kClassAttr, "shown-initially"); - FrameView().UpdateAllLifecyclePhases(); + FrameView().UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kOther); } void ValidationMessageOverlayDelegate::WriteDocument(SharedBuffer* data) {
diff --git a/third_party/blink/renderer/core/page/viewport_test.cc b/third_party/blink/renderer/core/page/viewport_test.cc index bc7e24f..66afb24 100644 --- a/third_party/blink/renderer/core/page/viewport_test.cc +++ b/third_party/blink/renderer/core/page/viewport_test.cc
@@ -2921,7 +2921,8 @@ base_url_ + "viewport/viewport-limits-adjusted-for-no-user-scale.html", nullptr, nullptr, nullptr, SetViewportSettings); - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); Page* page = web_view_helper.GetWebView()->GetPage(); PageScaleConstraints constraints = RunViewportTest(page, 10, 10); @@ -2938,8 +2939,8 @@ web_view_helper.InitializeAndLoad( base_url_ + "viewport/viewport-limits-adjusted-for-user-scale.html", nullptr, nullptr, nullptr, SetViewportSettings); - - web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases(); + web_view_helper.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); Page* page = web_view_helper.GetWebView()->GetPage(); PageScaleConstraints constraints = RunViewportTest(page, 10, 10);
diff --git a/third_party/blink/renderer/core/paint/link_highlight_impl_test.cc b/third_party/blink/renderer/core/paint/link_highlight_impl_test.cc index 2fc364fc..313cc562 100644 --- a/third_party/blink/renderer/core/paint/link_highlight_impl_test.cc +++ b/third_party/blink/renderer/core/paint/link_highlight_impl_test.cc
@@ -109,9 +109,8 @@ } void UpdateAllLifecyclePhases() { - web_view_helper_.GetWebView() - ->MainFrameWidget() - ->UpdateAllLifecyclePhases(); + web_view_helper_.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); } frame_test_helpers::WebViewHelper web_view_helper_;
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc index 369f955..5a3f1d6 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc
@@ -866,7 +866,7 @@ EXPECT_TRUE(scroller->BackgroundNeedsFullPaintInvalidation()); } EXPECT_TRUE(scroller->NeedsPaintPropertyUpdate()); - GetDocument().View()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); EXPECT_EQ(FloatSize(0, 1), scrollable_area->GetScrollOffset()); const auto* properties = scroller->FirstFragment().PaintProperties(); EXPECT_NE(nullptr, properties->ScrollTranslation()); @@ -947,7 +947,7 @@ EXPECT_TRUE(GetLayoutView().BackgroundNeedsFullPaintInvalidation()); } EXPECT_TRUE(GetLayoutView().NeedsPaintPropertyUpdate()); - GetDocument().View()->UpdateAllLifecyclePhases(); + UpdateAllLifecyclePhasesForTest(); // Programmatically changing the div's scroll offset. Should invalidate the // scrolled div with fixed attachment background.
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc index 8c2d1c0..3f3d2d0 100644 --- a/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc +++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc
@@ -126,7 +126,8 @@ transformed_scroll->setScrollTop(5); LocalFrameView* frame_view = GetDocument().View(); - frame_view->UpdateAllLifecyclePhases(); + frame_view->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); // target1 is a fixed-position element inside an absolute-position scrolling // element. It should be attached under the viewport to skip scrolling and @@ -212,7 +213,8 @@ Element* scroller = GetDocument().getElementById("scroller"); scroller->scrollTo(0, 100); LocalFrameView* frame_view = GetDocument().View(); - frame_view->UpdateAllLifecyclePhases(); + frame_view->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); const ObjectPaintProperties* scroller_properties = scroller->GetLayoutObject()->FirstFragment().PaintProperties(); EXPECT_EQ(TransformationMatrix().Translate(0, -100), @@ -488,7 +490,8 @@ GetDocument().domWindow()->scrollTo(0, 100); LocalFrameView* frame_view = GetDocument().View(); - frame_view->UpdateAllLifecyclePhases(); + frame_view->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); EXPECT_EQ(TransformationMatrix(), DocPreTranslation()->Matrix()); EXPECT_EQ( GetDocument().GetPage()->GetVisualViewport().GetScrollTranslationNode(), @@ -1752,7 +1755,8 @@ )HTML"); LocalFrameView* frame_view = GetDocument().View(); - frame_view->UpdateAllLifecyclePhases(); + frame_view->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); LayoutObject* div_with_transform = GetLayoutObjectByElementId("divWithTransform"); @@ -1846,7 +1850,8 @@ )HTML"); LocalFrameView* frame_view = GetDocument().View(); - frame_view->UpdateAllLifecyclePhases(); + frame_view->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); LayoutObject* frame = ChildFrame().View()->GetLayoutView(); const auto& frame_contents_properties = @@ -1905,7 +1910,8 @@ // However, isolation stops this recursion. GetDocument().getElementById("parent")->setAttribute(html_names::kClassAttr, "transformed"); - frame_view->UpdateAllLifecyclePhases(); + frame_view->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); // Verify that our clobbered state is still clobbered. EXPECT_EQ(TransformationMatrix().Translate(123, 321), @@ -1942,7 +1948,8 @@ <div id='transform'></div> )HTML"); LocalFrameView* frame_view = GetDocument().View(); - frame_view->UpdateAllLifecyclePhases(); + frame_view->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); // Assert that we have the following tree structure: // ...
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_update_tests.cc b/third_party/blink/renderer/core/paint/paint_property_tree_update_tests.cc index 4fc29480..6bca95b 100644 --- a/third_party/blink/renderer/core/paint/paint_property_tree_update_tests.cc +++ b/third_party/blink/renderer/core/paint/paint_property_tree_update_tests.cc
@@ -312,7 +312,8 @@ "translate3d(4px, 5px, 6px); width: 100px; height: 200px'></div>"); LocalFrameView* frame_view = GetDocument().View(); - frame_view->UpdateAllLifecyclePhases(); + frame_view->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); LayoutObject* div_with_transform = GetLayoutObjectByElementId("divWithTransform"); @@ -338,7 +339,8 @@ EXPECT_FALSE(inner_div_with_transform->DescendantNeedsPaintPropertyUpdate()); // After a lifecycle update, no nodes should need a descendant update. - frame_view->UpdateAllLifecyclePhases(); + frame_view->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); EXPECT_FALSE( GetDocument().GetLayoutView()->DescendantNeedsPaintPropertyUpdate()); EXPECT_FALSE(div_with_transform->DescendantNeedsPaintPropertyUpdate()); @@ -351,7 +353,8 @@ child_frame_view->SetNeedsPaintPropertyUpdate(); EXPECT_TRUE( GetDocument().GetLayoutView()->DescendantNeedsPaintPropertyUpdate()); - frame_view->UpdateAllLifecyclePhases(); + frame_view->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); EXPECT_FALSE( GetDocument().GetLayoutView()->DescendantNeedsPaintPropertyUpdate()); EXPECT_FALSE(GetDocument().GetLayoutView()->NeedsPaintPropertyUpdate()); @@ -576,14 +579,16 @@ "<div id='forceScroll' style='height: 3000px;'></div>"); LocalFrameView* frame_view = GetDocument().View(); - frame_view->UpdateAllLifecyclePhases(); + frame_view->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); EXPECT_EQ(nullptr, DocScroll()); Document* child_doc = &ChildDocument(); EXPECT_NE(nullptr, DocScroll(child_doc)); auto* iframe_container = GetDocument().getElementById("iframeContainer"); iframe_container->setAttribute(html_names::kStyleAttr, "visibility: hidden;"); - frame_view->UpdateAllLifecyclePhases(); + frame_view->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); EXPECT_EQ(nullptr, DocScroll()); EXPECT_EQ(nullptr, DocScroll(child_doc));
diff --git a/third_party/blink/renderer/core/paint/text_paint_timing_detector_test.cc b/third_party/blink/renderer/core/paint/text_paint_timing_detector_test.cc index 1af0ee46..475edcc7 100644 --- a/third_party/blink/renderer/core/paint/text_paint_timing_detector_test.cc +++ b/third_party/blink/renderer/core/paint/text_paint_timing_detector_test.cc
@@ -31,7 +31,8 @@ } void UpdateAllLifecyclePhasesAndSimulateSwapTime() { - GetFrameView().UpdateAllLifecyclePhases(); + GetFrameView().UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); TextPaintTimingDetector& detector = GetPaintTracker().GetTextPaintTimingDetector(); if (detector.texts_to_record_swap_time_.size() > 0) {
diff --git a/third_party/blink/renderer/core/paint/view_painter_test.cc b/third_party/blink/renderer/core/paint/view_painter_test.cc index 6f4a2b5..f217354 100644 --- a/third_party/blink/renderer/core/paint/view_painter_test.cc +++ b/third_party/blink/renderer/core/paint/view_painter_test.cc
@@ -45,7 +45,8 @@ ScrollOffset scroll_offset(200, 150); layout_viewport->SetScrollOffset(scroll_offset, kUserScroll); - frame_view->UpdateAllLifecyclePhases(); + frame_view->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); const DisplayItem* background_display_item = nullptr; if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
diff --git a/third_party/blink/renderer/core/scheduler/frame_throttling_test.cc b/third_party/blink/renderer/core/scheduler/frame_throttling_test.cc index 3da725a..2d91b42 100644 --- a/third_party/blink/renderer/core/scheduler/frame_throttling_test.cc +++ b/third_party/blink/renderer/core/scheduler/frame_throttling_test.cc
@@ -77,7 +77,8 @@ } void UpdateAllLifecyclePhases() { - GetDocument().View()->UpdateAllLifecyclePhases(); + GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); } };
diff --git a/third_party/blink/renderer/core/testing/fake_web_plugin.h b/third_party/blink/renderer/core/testing/fake_web_plugin.h index e96d6b4..9866bd5a 100644 --- a/third_party/blink/renderer/core/testing/fake_web_plugin.h +++ b/third_party/blink/renderer/core/testing/fake_web_plugin.h
@@ -53,7 +53,7 @@ bool Initialize(WebPluginContainer*) override; void Destroy() override; bool CanProcessDrag() const override { return false; } - void UpdateAllLifecyclePhases() override {} + void UpdateAllLifecyclePhases(WebWidget::LifecycleUpdateReason) override {} void Paint(cc::PaintCanvas*, const WebRect&) override {} void UpdateGeometry(const WebRect& client_rect, const WebRect& clip_rect,
diff --git a/third_party/blink/renderer/core/testing/internals.cc b/third_party/blink/renderer/core/testing/internals.cc index 80f3e7a..e9b67e8 100644 --- a/third_party/blink/renderer/core/testing/internals.cc +++ b/third_party/blink/renderer/core/testing/internals.cc
@@ -547,7 +547,8 @@ if (!GetFrame()) return; - GetFrame()->View()->UpdateAllLifecyclePhases(); + GetFrame()->View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); GetFrame()->GetDocument()->Timeline().PauseAnimationsForTesting(pause_time); } @@ -687,7 +688,8 @@ String Internals::elementLayoutTreeAsText(Element* element, ExceptionState& exception_state) { DCHECK(element); - element->GetDocument().View()->UpdateAllLifecyclePhases(); + element->GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); String representation = ExternalRepresentation(element); if (representation.IsEmpty()) { @@ -2126,7 +2128,8 @@ ExceptionState& exception_state) const { DCHECK(element); LocalFrameView* frame_view = element->GetDocument().View(); - frame_view->UpdateAllLifecyclePhases(); + frame_view->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); return elementLayerTreeAsText(element, 0, exception_state); } @@ -2135,7 +2138,8 @@ Element* element2, ExceptionState& exception_state) { DCHECK(element1 && element2); - element1->GetDocument().View()->UpdateAllLifecyclePhases(); + element1->GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); LayoutObject* layout_object1 = element1->GetLayoutObject(); LayoutObject* layout_object2 = element2->GetLayoutObject(); @@ -2180,7 +2184,8 @@ return String(); } - document->View()->UpdateAllLifecyclePhases(); + document->View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); return document->GetFrame()->GetLayerTreeAsTextForTesting(flags); } @@ -2226,7 +2231,8 @@ return String(); } - document->GetFrame()->View()->UpdateAllLifecyclePhases(); + document->GetFrame()->View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); return document->GetFrame()->View()->MainThreadScrollingReasonsAsText(); } @@ -2255,7 +2261,8 @@ // Update lifecycle to kPrePaintClean. This includes the compositing update // and ScrollingCoordinator::UpdateAfterPaint, which computes the non-fast // scrollable region. - frame->View()->UpdateAllLifecyclePhases(); + frame->View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); GraphicsLayer* layer = frame->View()->LayoutViewport()->LayerForScrolling(); if (!layer) @@ -2560,7 +2567,8 @@ } LocalFrameView* frame_view = document->View(); - frame_view->UpdateAllLifecyclePhases(); + frame_view->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); frame_view->SetTracksPaintInvalidations(true); } @@ -2574,7 +2582,8 @@ } LocalFrameView* frame_view = document->View(); - frame_view->UpdateAllLifecyclePhases(); + frame_view->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); frame_view->SetTracksPaintInvalidations(false); } @@ -2997,7 +3006,8 @@ return; } - document->GetFrame()->View()->UpdateAllLifecyclePhases(); + document->GetFrame()->View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); } void Internals::setZoomFactor(float factor) {
diff --git a/third_party/blink/renderer/core/testing/page_test_base.cc b/third_party/blink/renderer/core/testing/page_test_base.cc index fc33485..6f4e35bb 100644 --- a/third_party/blink/renderer/core/testing/page_test_base.cc +++ b/third_party/blink/renderer/core/testing/page_test_base.cc
@@ -115,7 +115,8 @@ } void PageTestBase::UpdateAllLifecyclePhasesForTest() { - GetDocument().View()->UpdateAllLifecyclePhases(); + GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); } StyleEngine& PageTestBase::GetStyleEngine() {
diff --git a/third_party/blink/renderer/core/testing/sim/sim_compositor.cc b/third_party/blink/renderer/core/testing/sim/sim_compositor.cc index bca9a534..becc31a0 100644 --- a/third_party/blink/renderer/core/testing/sim/sim_compositor.cc +++ b/third_party/blink/renderer/core/testing/sim/sim_compositor.cc
@@ -90,7 +90,8 @@ // There is no WebWidget like RenderWidget would have..? So go right to the // WebViewImpl. web_view_->BeginFrame(last_frame_time_); - web_view_->MainFrameWidget()->UpdateAllLifecyclePhases(); + web_view_->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); *paint_commands_ = PaintFrame(); }
diff --git a/third_party/blink/renderer/modules/accessibility/testing/accessibility_selection_test.cc b/third_party/blink/renderer/modules/accessibility/testing/accessibility_selection_test.cc index 192e391..ad3e0e8 100644 --- a/third_party/blink/renderer/modules/accessibility/testing/accessibility_selection_test.cc +++ b/third_party/blink/renderer/modules/accessibility/testing/accessibility_selection_test.cc
@@ -199,7 +199,8 @@ const Vector<AXSelection> Deserialize(const std::string& html_snippet, HTMLElement& element) { element.SetInnerHTMLFromString(String::FromUTF8(html_snippet.c_str())); - element.GetDocument().View()->UpdateAllLifecyclePhases(); + element.GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); AXObject* root = ax_object_cache_->GetOrCreate(&element); if (!root || root->IsDetached()) return {}; @@ -272,7 +273,8 @@ // Remove the markers, otherwise they would be duplicated if the AXSelection // is re-serialized. node->setData(builder.ToString()); - node->GetDocument().View()->UpdateAllLifecyclePhases(); + node->GetDocument().View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); // // Non-text selection.
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.cc b/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.cc index dd222f4..fba9ac8 100644 --- a/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.cc +++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.cc
@@ -6,7 +6,6 @@ #include <utility> #include "services/service_manager/public/cpp/interface_provider.h" -#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_request.h" #include "third_party/blink/renderer/modules/background_fetch/background_fetch_options.h" #include "third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h" #include "third_party/blink/renderer/modules/background_fetch/background_fetch_type_converters.h" @@ -48,7 +47,7 @@ void BackgroundFetchBridge::MatchRequests( const String& developer_id, const String& unique_id, - base::Optional<WebServiceWorkerRequest> request_to_match, + mojom::blink::FetchAPIRequestPtr request_to_match, mojom::blink::QueryParamsPtr cache_query_params, bool match_all, mojom::blink::BackgroundFetchService::MatchRequestsCallback callback) { @@ -60,7 +59,7 @@ void BackgroundFetchBridge::Fetch( const String& developer_id, - Vector<WebServiceWorkerRequest> requests, + Vector<mojom::blink::FetchAPIRequestPtr> requests, mojom::blink::BackgroundFetchOptionsPtr options, const SkBitmap& icon, mojom::blink::BackgroundFetchUkmDataPtr ukm_data,
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.h b/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.h index f295ce6..1ca427ab 100644 --- a/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.h +++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.h
@@ -17,7 +17,6 @@ namespace blink { class BackgroundFetchRegistration; -class WebServiceWorkerRequest; // The bridge is responsible for establishing and maintaining the Mojo // connection to the BackgroundFetchService. It's keyed on an active Service @@ -51,7 +50,7 @@ // for the sequence of |requests|. The |callback| will be invoked when the // registration has been created. void Fetch(const String& developer_id, - Vector<WebServiceWorkerRequest> requests, + Vector<mojom::blink::FetchAPIRequestPtr> requests, mojom::blink::BackgroundFetchOptionsPtr options, const SkBitmap& icon, mojom::blink::BackgroundFetchUkmDataPtr ukm_data, @@ -69,7 +68,7 @@ void MatchRequests( const String& developer_id, const String& unique_id, - base::Optional<WebServiceWorkerRequest> request_to_match, + mojom::blink::FetchAPIRequestPtr request_to_match, mojom::blink::QueryParamsPtr cache_query_params, bool match_all, mojom::blink::BackgroundFetchService::MatchRequestsCallback callback);
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.cc b/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.cc index 8658e4a..bb8c162 100644 --- a/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.cc +++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.cc
@@ -6,7 +6,6 @@ #include "base/memory/scoped_refptr.h" #include "base/metrics/histogram_macros.h" -#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_request.h" #include "third_party/blink/renderer/bindings/core/v8/request_or_usv_string.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/bindings/modules/v8/request_or_usv_string_or_request_or_usv_string_sequence.h" @@ -97,7 +96,6 @@ } bool ShouldBlockGateWayAttacks(ExecutionContext* execution_context, - const WebServiceWorkerRequest& web_request, const KURL& request_url) { if (RuntimeEnabledFeatures::CorsRFC1918Enabled()) { mojom::IPAddressSpace requestor_space = @@ -176,8 +174,9 @@ } bool has_requests_with_body; - Vector<WebServiceWorkerRequest> web_requests = CreateWebRequestVector( - script_state, requests, exception_state, &has_requests_with_body); + Vector<mojom::blink::FetchAPIRequestPtr> fetch_api_requests = + CreateFetchAPIRequestVector(script_state, requests, exception_state, + &has_requests_with_body); if (exception_state.HadException()) return ScriptPromise(); @@ -205,8 +204,8 @@ // all its security checks) are implemented in the Network Service, such that // the Download Service in the browser process can use it without having to // spin up a renderer process. - for (const WebServiceWorkerRequest& web_request : web_requests) { - KURL request_url(web_request.Url()); + for (const mojom::blink::FetchAPIRequestPtr& request : fetch_api_requests) { + KURL request_url(request->url); if (!request_url.IsValid()) { return RejectWithTypeError(script_state, request_url, @@ -216,7 +215,7 @@ // https://wicg.github.io/background-fetch/#dom-backgroundfetchmanager-fetch // ""If |internalRequest|’s mode is "no-cors", then return a promise // rejected with a TypeError."" - if (web_request.Mode() == network::mojom::FetchRequestMode::kNoCors) { + if (request->mode == network::mojom::FetchRequestMode::kNoCors) { return RejectWithTypeError(script_state, request_url, "the request mode must not be no-cors"); } @@ -249,8 +248,7 @@ "it contains dangling markup"); } - if (ShouldBlockGateWayAttacks(execution_context, web_request, - request_url)) { + if (ShouldBlockGateWayAttacks(execution_context, request_url)) { return RejectWithTypeError(script_state, request_url, "Requestor IP address space doesn't match the " "target address space."); @@ -259,7 +257,7 @@ kurls.insert(request_url); } - const bool has_duplicate_requests = kurls.size() != web_requests.size(); + const bool has_duplicate_requests = kurls.size() != fetch_api_requests.size(); UMA_HISTOGRAM_BOOLEAN("BackgroundFetch.HasDuplicateRequests", has_duplicate_requests); @@ -291,20 +289,21 @@ loader->Start( bridge_.Get(), execution_context, options->icons(), WTF::Bind(&BackgroundFetchManager::DidLoadIcons, WrapPersistent(this), - id, WTF::Passed(std::move(web_requests)), + id, WTF::Passed(std::move(fetch_api_requests)), std::move(options_ptr), WrapPersistent(resolver), WrapWeakPersistent(loader))); return promise; } - DidLoadIcons(id, std::move(web_requests), std::move(options_ptr), resolver, - nullptr, SkBitmap(), -1 /* ideal_to_chosen_icon_size */); + DidLoadIcons(id, std::move(fetch_api_requests), std::move(options_ptr), + resolver, nullptr, SkBitmap(), + -1 /* ideal_to_chosen_icon_size */); return promise; } void BackgroundFetchManager::DidLoadIcons( const String& id, - Vector<WebServiceWorkerRequest> web_requests, + Vector<mojom::blink::FetchAPIRequestPtr> requests, mojom::blink::BackgroundFetchOptionsPtr options, ScriptPromiseResolver* resolver, BackgroundFetchIconLoader* loader, @@ -316,8 +315,7 @@ auto ukm_data = mojom::blink::BackgroundFetchUkmData::New(); ukm_data->ideal_to_chosen_icon_size = ideal_to_chosen_icon_size; bridge_->Fetch( - id, std::move(web_requests), std::move(options), icon, - std::move(ukm_data), + id, std::move(requests), std::move(options), icon, std::move(ukm_data), WTF::Bind(&BackgroundFetchManager::DidFetch, WrapPersistent(this), WrapPersistent(resolver), base::Time::Now())); } @@ -406,14 +404,15 @@ } // static -Vector<WebServiceWorkerRequest> BackgroundFetchManager::CreateWebRequestVector( +Vector<mojom::blink::FetchAPIRequestPtr> +BackgroundFetchManager::CreateFetchAPIRequestVector( ScriptState* script_state, const RequestOrUSVStringOrRequestOrUSVStringSequence& requests, ExceptionState& exception_state, bool* has_requests_with_body) { DCHECK(has_requests_with_body); - Vector<WebServiceWorkerRequest> web_requests; + Vector<mojom::blink::FetchAPIRequestPtr> fetch_api_requests; *has_requests_with_body = false; if (requests.IsRequestOrUSVStringSequence()) { @@ -423,10 +422,10 @@ // Throw a TypeError when the developer has passed an empty sequence. if (!request_vector.size()) { exception_state.ThrowTypeError(kEmptyRequestSequenceErrorMessage); - return Vector<WebServiceWorkerRequest>(); + return Vector<mojom::blink::FetchAPIRequestPtr>(); } - web_requests.resize(request_vector.size()); + fetch_api_requests.resize(request_vector.size()); for (wtf_size_t i = 0; i < request_vector.size(); ++i) { const RequestOrUSVString& request_or_url = request_vector[i]; @@ -438,21 +437,20 @@ request = Request::Create(script_state, request_or_url.GetAsUSVString(), exception_state); if (exception_state.HadException()) - return Vector<WebServiceWorkerRequest>(); + return Vector<mojom::blink::FetchAPIRequestPtr>(); } else { exception_state.ThrowTypeError(kNullRequestErrorMessage); - return Vector<WebServiceWorkerRequest>(); + return Vector<mojom::blink::FetchAPIRequestPtr>(); } DCHECK(request); *has_requests_with_body |= request->HasBody(); // TODO(crbug.com/774054): Set blob data handle when adding support for // requests with body. - request->PopulateWebServiceWorkerRequest(web_requests[i]); - web_requests[i].SetBlobDataHandle( - ExtractBlobHandle(request, exception_state)); + fetch_api_requests[i] = request->CreateFetchAPIRequest(); + fetch_api_requests[i]->blob = ExtractBlobHandle(request, exception_state); if (exception_state.HadException()) - return Vector<WebServiceWorkerRequest>(); + return Vector<mojom::blink::FetchAPIRequestPtr>(); } } else if (requests.IsRequest()) { auto* request = requests.GetAsRequest(); @@ -462,28 +460,28 @@ // requests with body. *has_requests_with_body = request->HasBody(); - web_requests.resize(1); - request->PopulateWebServiceWorkerRequest(web_requests[0]); - web_requests[0].SetBlobDataHandle( - ExtractBlobHandle(requests.GetAsRequest(), exception_state)); + fetch_api_requests.resize(1); + fetch_api_requests[0] = request->CreateFetchAPIRequest(); + fetch_api_requests[0]->blob = + ExtractBlobHandle(requests.GetAsRequest(), exception_state); if (exception_state.HadException()) - return Vector<WebServiceWorkerRequest>(); + return Vector<mojom::blink::FetchAPIRequestPtr>(); } else if (requests.IsUSVString()) { Request* request = Request::Create(script_state, requests.GetAsUSVString(), exception_state); if (exception_state.HadException()) - return Vector<WebServiceWorkerRequest>(); + return Vector<mojom::blink::FetchAPIRequestPtr>(); DCHECK(request); *has_requests_with_body = request->HasBody(); - web_requests.resize(1); - request->PopulateWebServiceWorkerRequest(web_requests[0]); + fetch_api_requests.resize(1); + fetch_api_requests[0] = request->CreateFetchAPIRequest(); } else { exception_state.ThrowTypeError(kNullRequestErrorMessage); - return Vector<WebServiceWorkerRequest>(); + return Vector<mojom::blink::FetchAPIRequestPtr>(); } - return web_requests; + return fetch_api_requests; } void BackgroundFetchManager::DidGetRegistration(
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.h b/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.h index 19b5c40..7001f931 100644 --- a/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.h +++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.h
@@ -28,7 +28,6 @@ class ScriptPromiseResolver; class ScriptState; class ServiceWorkerRegistration; -class WebServiceWorkerRequest; // Implementation of the BackgroundFetchManager JavaScript object, accessible // by developers through ServiceWorkerRegistration.backgroundFetch. @@ -65,17 +64,17 @@ explicit BackgroundFetchManager(ServiceWorkerRegistration* registration); - // Creates a vector of WebServiceWorkerRequest objects for the given set of - // |requests|, which can be either Request objects or URL strings. + // Creates a vector of mojom::blink::FetchAPIRequestPtr objects for the given + // set of |requests|, which can be either Request objects or URL strings. // |has_requests_with_body| will be set if any of the |requests| has a body. - static Vector<WebServiceWorkerRequest> CreateWebRequestVector( + static Vector<mojom::blink::FetchAPIRequestPtr> CreateFetchAPIRequestVector( ScriptState* script_state, const RequestOrUSVStringOrRequestOrUSVStringSequence& requests, ExceptionState& exception_state, bool* has_requests_with_body); void DidLoadIcons(const String& id, - Vector<WebServiceWorkerRequest> web_requests, + Vector<mojom::blink::FetchAPIRequestPtr> requests, mojom::blink::BackgroundFetchOptionsPtr options, ScriptPromiseResolver* resolver, BackgroundFetchIconLoader* loader,
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_manager_test.cc b/third_party/blink/renderer/modules/background_fetch/background_fetch_manager_test.cc index 3ac8887..01592306 100644 --- a/third_party/blink/renderer/modules/background_fetch/background_fetch_manager_test.cc +++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_manager_test.cc
@@ -5,7 +5,6 @@ #include "third_party/blink/renderer/modules/background_fetch/background_fetch_manager.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_request.h" #include "third_party/blink/renderer/bindings/core/v8/request_or_usv_string.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h" @@ -20,14 +19,14 @@ class BackgroundFetchManagerTest : public testing::Test { protected: - // Creates a vector of WebServiceWorkerRequest entries for the given - // |requests| based on the |scope|. Proxied in the fixture to reduce the - // number of friend declarations necessary in the BackgroundFetchManager. - Vector<WebServiceWorkerRequest> CreateWebRequestVector( + // Creates a vector of FetchAPIRequestPtr entries for the given |requests| + // based on the |scope|. Proxied in the fixture to reduce the number of friend + // declarations necessary in the BackgroundFetchManager. + Vector<mojom::blink::FetchAPIRequestPtr> CreateFetchAPIRequestVector( V8TestingScope& scope, const RequestOrUSVStringOrRequestOrUSVStringSequence& requests) { bool has_requests_with_body; - return BackgroundFetchManager::CreateWebRequestVector( + return BackgroundFetchManager::CreateFetchAPIRequestVector( scope.GetScriptState(), requests, scope.GetExceptionState(), &has_requests_with_body); } @@ -38,8 +37,8 @@ RequestOrUSVStringOrRequestOrUSVStringSequence requests; - Vector<WebServiceWorkerRequest> web_requests = - CreateWebRequestVector(scope, requests); + Vector<mojom::blink::FetchAPIRequestPtr> fetch_api_requests = + CreateFetchAPIRequestVector(scope, requests); ASSERT_TRUE(scope.GetExceptionState().HadException()); EXPECT_EQ(scope.GetExceptionState().CodeAs<ESErrorType>(), ESErrorType::kTypeError); @@ -54,15 +53,13 @@ RequestOrUSVStringOrRequestOrUSVStringSequence::FromUSVString( image_url.GetString()); - Vector<WebServiceWorkerRequest> web_requests = - CreateWebRequestVector(scope, requests); + Vector<mojom::blink::FetchAPIRequestPtr> fetch_api_requests = + CreateFetchAPIRequestVector(scope, requests); ASSERT_FALSE(scope.GetExceptionState().HadException()); - ASSERT_EQ(web_requests.size(), 1u); - - WebServiceWorkerRequest& web_request = web_requests[0]; - EXPECT_EQ(web_request.Url(), WebURL(image_url)); - EXPECT_EQ(web_request.Method(), "GET"); + ASSERT_EQ(fetch_api_requests.size(), 1u); + EXPECT_EQ(fetch_api_requests[0]->url, image_url); + EXPECT_EQ(fetch_api_requests[0]->method, "GET"); } TEST_F(BackgroundFetchManagerTest, SingleRequest) { @@ -81,15 +78,13 @@ RequestOrUSVStringOrRequestOrUSVStringSequence requests = RequestOrUSVStringOrRequestOrUSVStringSequence::FromRequest(request); - Vector<WebServiceWorkerRequest> web_requests = - CreateWebRequestVector(scope, requests); + Vector<mojom::blink::FetchAPIRequestPtr> fetch_api_requests = + CreateFetchAPIRequestVector(scope, requests); ASSERT_FALSE(scope.GetExceptionState().HadException()); - ASSERT_EQ(web_requests.size(), 1u); - - WebServiceWorkerRequest& web_request = web_requests[0]; - EXPECT_EQ(web_request.Url(), WebURL(image_url)); - EXPECT_EQ(web_request.Method(), "POST"); + ASSERT_EQ(fetch_api_requests.size(), 1u); + EXPECT_EQ(fetch_api_requests[0]->url, image_url); + EXPECT_EQ(fetch_api_requests[0]->method, "POST"); } TEST_F(BackgroundFetchManagerTest, Sequence) { @@ -124,19 +119,19 @@ RequestOrUSVStringOrRequestOrUSVStringSequence:: FromRequestOrUSVStringSequence(request_sequence); - Vector<WebServiceWorkerRequest> web_requests = - CreateWebRequestVector(scope, requests); + Vector<mojom::blink::FetchAPIRequestPtr> fetch_api_requests = + CreateFetchAPIRequestVector(scope, requests); ASSERT_FALSE(scope.GetExceptionState().HadException()); - ASSERT_EQ(web_requests.size(), 3u); - EXPECT_EQ(web_requests[0].Url(), WebURL(image_url)); - EXPECT_EQ(web_requests[0].Method(), "GET"); + ASSERT_EQ(fetch_api_requests.size(), 3u); + EXPECT_EQ(fetch_api_requests[0]->url, image_url); + EXPECT_EQ(fetch_api_requests[0]->method, "GET"); - EXPECT_EQ(web_requests[1].Url(), WebURL(icon_url)); - EXPECT_EQ(web_requests[1].Method(), "GET"); + EXPECT_EQ(fetch_api_requests[1]->url, icon_url); + EXPECT_EQ(fetch_api_requests[1]->method, "GET"); - EXPECT_EQ(web_requests[2].Url(), WebURL(cat_video_url)); - EXPECT_EQ(web_requests[2].Method(), "DELETE"); + EXPECT_EQ(fetch_api_requests[2]->url, cat_video_url); + EXPECT_EQ(fetch_api_requests[2]->method, "DELETE"); } TEST_F(BackgroundFetchManagerTest, SequenceEmpty) { @@ -147,8 +142,8 @@ RequestOrUSVStringOrRequestOrUSVStringSequence:: FromRequestOrUSVStringSequence(request_sequence); - Vector<WebServiceWorkerRequest> web_requests = - CreateWebRequestVector(scope, requests); + Vector<mojom::blink::FetchAPIRequestPtr> fetch_api_requests = + CreateFetchAPIRequestVector(scope, requests); ASSERT_TRUE(scope.GetExceptionState().HadException()); EXPECT_EQ(scope.GetExceptionState().CodeAs<ESErrorType>(), ESErrorType::kTypeError); @@ -171,8 +166,8 @@ RequestOrUSVStringOrRequestOrUSVStringSequence:: FromRequestOrUSVStringSequence(request_sequence); - Vector<WebServiceWorkerRequest> web_requests = - CreateWebRequestVector(scope, requests); + Vector<mojom::blink::FetchAPIRequestPtr> fetch_api_requests = + CreateFetchAPIRequestVector(scope, requests); ASSERT_TRUE(scope.GetExceptionState().HadException()); EXPECT_EQ(scope.GetExceptionState().CodeAs<ESErrorType>(), ESErrorType::kTypeError); @@ -211,15 +206,16 @@ FromRequestOrUSVStringSequence(request_sequence); // Extract the blobs. - auto web_requests = CreateWebRequestVector(scope, requests); + Vector<mojom::blink::FetchAPIRequestPtr> fetch_api_requests = + CreateFetchAPIRequestVector(scope, requests); ASSERT_FALSE(scope.GetExceptionState().HadException()); - ASSERT_EQ(web_requests.size(), 2u); + ASSERT_EQ(fetch_api_requests.size(), 2u); - ASSERT_TRUE(web_requests[0].GetBlobDataHandle()); - EXPECT_EQ(web_requests[0].GetBlobDataHandle()->size(), body_text.length()); + ASSERT_TRUE(fetch_api_requests[0]->blob); + EXPECT_EQ(fetch_api_requests[0]->blob->size(), body_text.length()); - EXPECT_FALSE(web_requests[1].GetBlobDataHandle()); + EXPECT_FALSE(fetch_api_requests[1]->blob); } } // namespace blink
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.cc b/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.cc index fe85363..ae18e06 100644 --- a/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.cc +++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.cc
@@ -203,28 +203,25 @@ ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); ScriptPromise promise = resolver->Promise(); - // Convert |request| to WebServiceWorkerRequest. - base::Optional<WebServiceWorkerRequest> optional_request; + // Convert |request| to mojom::blink::FetchAPIRequestPtr. + mojom::blink::FetchAPIRequestPtr request_to_match; if (request.has_value()) { - WebServiceWorkerRequest request_to_match; if (request->IsRequest()) { - request->GetAsRequest()->PopulateWebServiceWorkerRequest( - request_to_match); + request_to_match = request->GetAsRequest()->CreateFetchAPIRequest(); } else { Request* new_request = Request::Create( script_state, request->GetAsUSVString(), exception_state); if (exception_state.HadException()) return ScriptPromise(); - new_request->PopulateWebServiceWorkerRequest(request_to_match); + request_to_match = new_request->CreateFetchAPIRequest(); } - optional_request = request_to_match; } DCHECK(registration_); BackgroundFetchBridge::From(registration_) ->MatchRequests( - developer_id_, unique_id_, optional_request, + developer_id_, unique_id_, std::move(request_to_match), std::move(cache_query_params), match_all, WTF::Bind(&BackgroundFetchRegistration::DidGetMatchingRequests, WrapPersistent(this), WrapPersistent(resolver), match_all)); @@ -241,7 +238,7 @@ HeapVector<Member<BackgroundFetchRecord>> to_return; to_return.ReserveInitialCapacity(settled_fetches.size()); for (const auto& fetch : settled_fetches) { - Request* request = Request::Create(script_state, fetch->request); + Request* request = Request::Create(script_state, *(fetch->request)); Response* response = fetch->response ? Response::Create(script_state, *fetch->response)
diff --git a/third_party/blink/renderer/modules/cache_storage/cache.cc b/third_party/blink/renderer/modules/cache_storage/cache.cc index 9fa91cc..9854d56 100644 --- a/third_party/blink/renderer/modules/cache_storage/cache.cc +++ b/third_party/blink/renderer/modules/cache_storage/cache.cc
@@ -10,7 +10,6 @@ #include "services/network/public/mojom/fetch_api.mojom-blink.h" #include "third_party/blink/public/common/cache_storage/cache_storage_utils.h" #include "third_party/blink/public/platform/modules/cache_storage/cache_storage.mojom-blink.h" -#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_response.h" #include "third_party/blink/renderer/bindings/core/v8/callback_promise_adapter.h" #include "third_party/blink/renderer/bindings/core/v8/idl_types.h" #include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h" @@ -317,7 +316,7 @@ Request* request, Response* response) : index_(index), barrier_callback_(barrier_callback) { - request->PopulateWebServiceWorkerRequest(web_request_); + fetch_api_request_ = request->CreateFetchAPIRequest(); fetch_api_response_ = response->PopulateFetchAPIResponse(); } ~BlobHandleCallbackForPut() override = default; @@ -327,7 +326,7 @@ mojom::blink::BatchOperationPtr batch_operation = mojom::blink::BatchOperation::New(); batch_operation->operation_type = mojom::blink::OperationType::kPut; - batch_operation->request = web_request_; + batch_operation->request = std::move(fetch_api_request_); batch_operation->response = std::move(fetch_api_response_); batch_operation->response->blob = handle; barrier_callback_->OnSuccess(index_, std::move(batch_operation)); @@ -348,7 +347,7 @@ const wtf_size_t index_; Member<BarrierCallbackForPut> barrier_callback_; - WebServiceWorkerRequest web_request_; + mojom::blink::FetchAPIRequestPtr fetch_api_request_; mojom::blink::FetchAPIResponsePtr fetch_api_response_; }; @@ -367,7 +366,7 @@ index_(index), barrier_callback_(barrier_callback), mime_type_(response->InternalMIMEType()) { - request->PopulateWebServiceWorkerRequest(web_request_); + fetch_api_request_ = request->CreateFetchAPIRequest(); fetch_api_response_ = response->PopulateFetchAPIResponse(); } ~CodeCacheHandleCallbackForPut() override = default; @@ -376,7 +375,7 @@ mojom::blink::BatchOperationPtr batch_operation = mojom::blink::BatchOperation::New(); batch_operation->operation_type = mojom::blink::OperationType::kPut; - batch_operation->request = web_request_; + batch_operation->request = std::move(fetch_api_request_); batch_operation->response = std::move(fetch_api_response_); std::unique_ptr<BlobData> blob_data = BlobData::Create(); @@ -397,7 +396,7 @@ script_state_, text_decoder->Decode(static_cast<const char*>(array_buffer->Data()), array_buffer->ByteLength()), - web_request_.Url().GetString(), text_decoder->Encoding(), + batch_operation->request->url.GetString(), text_decoder->Encoding(), batch_operation->response->response_type == network::mojom::FetchResponseType::kOpaque ? V8CodeCache::OpaqueMode::kOpaque @@ -434,7 +433,7 @@ Member<BarrierCallbackForPut> barrier_callback_; const String mime_type_; - WebServiceWorkerRequest web_request_; + mojom::blink::FetchAPIRequestPtr fetch_api_request_; mojom::blink::FetchAPIResponsePtr fetch_api_response_; }; @@ -588,9 +587,6 @@ ScriptPromise Cache::MatchImpl(ScriptState* script_state, const Request* request, const CacheQueryOptions* options) { - WebServiceWorkerRequest web_request; - request->PopulateWebServiceWorkerRequest(web_request); - ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); const ScriptPromise promise = resolver->Promise(); if (request->method() != http_names::kGET && !options->ignoreMethod()) { @@ -599,7 +595,7 @@ } cache_ptr_->Match( - web_request, ToQueryParams(options), + request->CreateFetchAPIRequest(), ToQueryParams(options), WTF::Bind( [](ScriptPromiseResolver* resolver, TimeTicks start_time, const CacheQueryOptions* options, @@ -643,12 +639,12 @@ ScriptPromise Cache::MatchAllImpl(ScriptState* script_state, const Request* request, const CacheQueryOptions* options) { - base::Optional<WebServiceWorkerRequest> web_request; + mojom::blink::FetchAPIRequestPtr fetch_api_request; ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); const ScriptPromise promise = resolver->Promise(); if (request) { - request->PopulateWebServiceWorkerRequest(web_request.emplace()); + fetch_api_request = request->CreateFetchAPIRequest(); if (request->method() != http_names::kGET && !options->ignoreMethod()) { resolver->Resolve(HeapVector<Member<Response>>()); @@ -657,7 +653,7 @@ } cache_ptr_->MatchAll( - web_request, ToQueryParams(options), + std::move(fetch_api_request), ToQueryParams(options), WTF::Bind( [](ScriptPromiseResolver* resolver, TimeTicks start_time, const CacheQueryOptions* options, @@ -746,7 +742,7 @@ batch_operations.push_back(mojom::blink::BatchOperation::New()); auto& operation = batch_operations.back(); operation->operation_type = mojom::blink::OperationType::kDelete; - request->PopulateWebServiceWorkerRequest(operation->request); + operation->request = request->CreateFetchAPIRequest(); operation->match_params = ToQueryParams(options); cache_ptr_->Batch( @@ -882,7 +878,7 @@ mojom::blink::BatchOperationPtr batch_operation = mojom::blink::BatchOperation::New(); batch_operation->operation_type = mojom::blink::OperationType::kPut; - requests[i]->PopulateWebServiceWorkerRequest(batch_operation->request); + batch_operation->request = requests[i]->CreateFetchAPIRequest(); batch_operation->response = responses[i]->PopulateFetchAPIResponse(); barrier_callback->OnSuccess(i, std::move(batch_operation)); } @@ -893,12 +889,12 @@ ScriptPromise Cache::KeysImpl(ScriptState* script_state, const Request* request, const CacheQueryOptions* options) { - base::Optional<WebServiceWorkerRequest> web_request; + mojom::blink::FetchAPIRequestPtr fetch_api_request; ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); const ScriptPromise promise = resolver->Promise(); if (request) { - request->PopulateWebServiceWorkerRequest(web_request.emplace()); + fetch_api_request = request->CreateFetchAPIRequest(); if (request->method() != http_names::kGET && !options->ignoreMethod()) { resolver->Resolve(HeapVector<Member<Response>>()); @@ -907,7 +903,7 @@ } cache_ptr_->Keys( - web_request, ToQueryParams(options), + std::move(fetch_api_request), ToQueryParams(options), WTF::Bind( [](ScriptPromiseResolver* resolver, TimeTicks start_time, const CacheQueryOptions* options, @@ -936,7 +932,7 @@ requests.ReserveInitialCapacity(result->get_keys().size()); for (auto& request : result->get_keys()) { requests.push_back( - Request::Create(resolver->GetScriptState(), request)); + Request::Create(resolver->GetScriptState(), *request)); } resolver->Resolve(requests); }
diff --git a/third_party/blink/renderer/modules/cache_storage/cache_storage.cc b/third_party/blink/renderer/modules/cache_storage/cache_storage.cc index c0a0e25..7277c56 100644 --- a/third_party/blink/renderer/modules/cache_storage/cache_storage.cc +++ b/third_party/blink/renderer/modules/cache_storage/cache_storage.cc
@@ -164,9 +164,6 @@ ScriptPromise CacheStorage::MatchImpl(ScriptState* script_state, const Request* request, const CacheQueryOptions* options) { - WebServiceWorkerRequest web_request; - request->PopulateWebServiceWorkerRequest(web_request); - ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); const ScriptPromise promise = resolver->Promise(); @@ -176,7 +173,7 @@ } cache_storage_ptr_->Match( - web_request, Cache::ToQueryParams(options), + request->CreateFetchAPIRequest(), Cache::ToQueryParams(options), WTF::Bind( [](ScriptPromiseResolver* resolver, TimeTicks start_time, const CacheQueryOptions* options,
diff --git a/third_party/blink/renderer/modules/cache_storage/cache_test.cc b/third_party/blink/renderer/modules/cache_storage/cache_test.cc index 0301183..fb5cc6f 100644 --- a/third_party/blink/renderer/modules/cache_storage/cache_test.cc +++ b/third_party/blink/renderer/modules/cache_storage/cache_test.cc
@@ -138,34 +138,34 @@ expected_batch_operations_ = expected_batch_operations; } - void Match(const WebServiceWorkerRequest& request, + void Match(mojom::blink::FetchAPIRequestPtr fetch_api_request, mojom::blink::QueryParamsPtr query_params, MatchCallback callback) override { last_error_web_cache_method_called_ = "dispatchMatch"; - CheckUrlIfProvided(request.Url()); + CheckUrlIfProvided(fetch_api_request->url); CheckQueryParamsIfProvided(query_params); mojom::blink::MatchResultPtr result = mojom::blink::MatchResult::New(); result->set_status(error_); std::move(callback).Run(std::move(result)); } - void MatchAll(const base::Optional<WebServiceWorkerRequest>& request, + void MatchAll(mojom::blink::FetchAPIRequestPtr fetch_api_request, mojom::blink::QueryParamsPtr query_params, MatchAllCallback callback) override { last_error_web_cache_method_called_ = "dispatchMatchAll"; - if (request) - CheckUrlIfProvided(request->Url()); + if (fetch_api_request) + CheckUrlIfProvided(fetch_api_request->url); CheckQueryParamsIfProvided(query_params); mojom::blink::MatchAllResultPtr result = mojom::blink::MatchAllResult::New(); result->set_status(error_); std::move(callback).Run(std::move(result)); } - void Keys(const base::Optional<WebServiceWorkerRequest>& request, + void Keys(mojom::blink::FetchAPIRequestPtr fetch_api_request, mojom::blink::QueryParamsPtr query_params, KeysCallback callback) override { last_error_web_cache_method_called_ = "dispatchKeys"; - if (request && !request->Url().IsEmpty()) { - CheckUrlIfProvided(request->Url()); + if (fetch_api_request && !fetch_api_request->url.IsEmpty()) { + CheckUrlIfProvided(fetch_api_request->url); CheckQueryParamsIfProvided(query_params); } mojom::blink::CacheKeysResultPtr result = @@ -208,8 +208,8 @@ EXPECT_EQ(expected_batch_operations[i]->operation_type, batch_operations[i]->operation_type); const String expected_request_url = - KURL(expected_batch_operations[i]->request.Url()); - EXPECT_EQ(expected_request_url, KURL(batch_operations[i]->request.Url())); + expected_batch_operations[i]->request->url; + EXPECT_EQ(expected_request_url, batch_operations[i]->request->url); if (expected_batch_operations[i]->response) { ASSERT_EQ(expected_batch_operations[i]->response->url_list.size(), batch_operations[i]->response->url_list.size()); @@ -526,7 +526,7 @@ expected_delete_operations.push_back(mojom::blink::BatchOperation::New()); auto& delete_operation = expected_delete_operations.back(); delete_operation->operation_type = mojom::blink::OperationType::kDelete; - request->PopulateWebServiceWorkerRequest(delete_operation->request); + delete_operation->request = request->CreateFetchAPIRequest(); delete_operation->match_params = expected_query_params->Clone(); } test_cache()->SetExpectedBatchOperations(&expected_delete_operations); @@ -549,7 +549,7 @@ expected_put_operations.push_back(mojom::blink::BatchOperation::New()); auto& put_operation = expected_put_operations.back(); put_operation->operation_type = mojom::blink::OperationType::kPut; - request->PopulateWebServiceWorkerRequest(put_operation->request); + put_operation->request = request->CreateFetchAPIRequest(); put_operation->response = response->PopulateFetchAPIResponse(); } test_cache()->SetExpectedBatchOperations(&expected_put_operations); @@ -578,7 +578,7 @@ : response_(std::move(response)) {} // From WebServiceWorkerCache: - void Match(const WebServiceWorkerRequest& request, + void Match(mojom::blink::FetchAPIRequestPtr fetch_api_request, mojom::blink::QueryParamsPtr query_params, MatchCallback callback) override { mojom::blink::MatchResultPtr result = mojom::blink::MatchResult::New(); @@ -620,20 +620,20 @@ class KeysTestCache : public NotImplementedErrorCache { public: - KeysTestCache(Vector<WebServiceWorkerRequest>& requests) - : requests_(requests) {} + KeysTestCache(Vector<mojom::blink::FetchAPIRequestPtr> requests) + : requests_(std::move(requests)) {} - void Keys(const base::Optional<WebServiceWorkerRequest>& request, + void Keys(mojom::blink::FetchAPIRequestPtr fetch_api_request, mojom::blink::QueryParamsPtr query_params, KeysCallback callback) override { mojom::blink::CacheKeysResultPtr result = mojom::blink::CacheKeysResult::New(); - result->set_keys(requests_); + result->set_keys(std::move(requests_)); std::move(callback).Run(std::move(result)); } private: - Vector<WebServiceWorkerRequest>& requests_; + Vector<mojom::blink::FetchAPIRequestPtr> requests_; }; TEST_F(CacheStorageTest, KeysResponseTest) { @@ -647,14 +647,16 @@ expected_urls[0] = url1; expected_urls[1] = url2; - Vector<WebServiceWorkerRequest> web_requests(size_t(2)); - web_requests[0].SetURL(KURL(url1)); - web_requests[0].SetMethod("GET"); - web_requests[1].SetURL(KURL(url2)); - web_requests[1].SetMethod("GET"); + Vector<mojom::blink::FetchAPIRequestPtr> fetch_api_requests(size_t(2)); + fetch_api_requests[0] = mojom::blink::FetchAPIRequest::New(); + fetch_api_requests[0]->url = KURL(url1); + fetch_api_requests[0]->method = String("GET"); + fetch_api_requests[1] = mojom::blink::FetchAPIRequest::New(); + fetch_api_requests[1]->url = KURL(url2); + fetch_api_requests[1]->method = String("GET"); - Cache* cache = - CreateCache(fetcher, std::make_unique<KeysTestCache>(web_requests)); + Cache* cache = CreateCache( + fetcher, std::make_unique<KeysTestCache>(std::move(fetch_api_requests))); ScriptPromise result = cache->keys(GetScriptState(), exception_state); ScriptValue script_value = GetResolveValue(result); @@ -677,7 +679,7 @@ MatchAllAndBatchTestCache(Vector<mojom::blink::FetchAPIResponsePtr> responses) : responses_(std::move(responses)) {} - void MatchAll(const base::Optional<WebServiceWorkerRequest>& request, + void MatchAll(mojom::blink::FetchAPIRequestPtr fetch_api_request, mojom::blink::QueryParamsPtr query_params, MatchAllCallback callback) override { mojom::blink::MatchAllResultPtr result = @@ -776,7 +778,7 @@ mojom::blink::BatchOperation::New(); put_operation->operation_type = mojom::blink::OperationType::kPut; - request->PopulateWebServiceWorkerRequest(put_operation->request); + put_operation->request = request->CreateFetchAPIRequest(); put_operation->response = response->PopulateFetchAPIResponse(); expected_put_operations[0] = std::move(put_operation); }
diff --git a/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.cc b/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.cc index 740d509..ce51f53 100644 --- a/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.cc +++ b/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.cc
@@ -12,8 +12,6 @@ #include "services/network/public/mojom/fetch_api.mojom-blink.h" #include "services/service_manager/public/cpp/interface_provider.h" #include "third_party/blink/public/platform/modules/cache_storage/cache_storage.mojom-blink.h" -#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_request.h" -#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_response.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/web_security_origin.h" #include "third_party/blink/public/platform/web_string.h" @@ -221,13 +219,13 @@ cache_ptr_(std::move(cache_ptr)), callback_(std::move(callback)) {} - void Dispatch(const Vector<WebServiceWorkerRequest>& requests) { + void Dispatch(Vector<mojom::blink::FetchAPIRequestPtr> requests) { for (const auto& request : requests) { cache_ptr_->Match( - request, mojom::blink::QueryParams::New(), + request.Clone(), mojom::blink::QueryParams::New(), WTF::Bind( [](scoped_refptr<ResponsesAccumulator> accumulator, - WebServiceWorkerRequest request, + mojom::blink::FetchAPIRequestPtr request, mojom::blink::MatchResultPtr result) { if (result->is_status()) { accumulator->SendFailure(result->get_status()); @@ -236,20 +234,24 @@ result->get_response()); } }, - scoped_refptr<ResponsesAccumulator>(this), request)); + scoped_refptr<ResponsesAccumulator>(this), request.Clone())); } } void AddRequestResponsePair( - const WebServiceWorkerRequest& request, + const mojom::blink::FetchAPIRequestPtr& request, const mojom::blink::FetchAPIResponsePtr& response) { DCHECK_GT(num_responses_left_, 0); RequestResponse& request_response = responses_.at(responses_.size() - num_responses_left_); - request_response.request_url = request.Url().GetString(); - request_response.request_method = request.Method(); - request_response.request_headers = request.Headers(); + request_response.request_url = request->url.GetString(); + request_response.request_method = request->method; + for (const auto& header : request->headers) { + request_response.request_headers.Set(AtomicString(header.key), + AtomicString(header.value)); + } + request_response.response_status = response->status_code; request_response.response_status_text = response->status_text; request_response.response_time = response->response_time.ToDoubleT(); @@ -337,8 +339,7 @@ void Dispatch(std::unique_ptr<GetCacheKeysForRequestData> self) { cache_ptr_->Keys( - base::Optional<WebServiceWorkerRequest>(), - mojom::blink::QueryParams::New(), + nullptr /* request */, mojom::blink::QueryParams::New(), WTF::Bind( [](DataRequestParams params, std::unique_ptr<GetCacheKeysForRequestData> self, @@ -350,8 +351,7 @@ params.cache_name.Utf8().data(), CacheStorageErrorString(result->get_status()).data()))); } else { - auto& requests = result->get_keys(); - if (requests.IsEmpty()) { + if (result->get_keys().IsEmpty()) { std::unique_ptr<Array<DataEntry>> array = Array<DataEntry>::create(); self->callback_->sendSuccess(std::move(array), false); @@ -359,9 +359,10 @@ } scoped_refptr<ResponsesAccumulator> accumulator = base::AdoptRef(new ResponsesAccumulator( - requests.size(), params, std::move(self->cache_ptr_), + result->get_keys().size(), params, + std::move(self->cache_ptr_), std::move(self->callback_))); - accumulator->Dispatch(result->get_keys()); + accumulator->Dispatch(std::move(result->get_keys())); } }, params_, std::move(self))); @@ -574,8 +575,9 @@ batch_operations.push_back(mojom::blink::BatchOperation::New()); auto& operation = batch_operations.back(); operation->operation_type = mojom::blink::OperationType::kDelete; - operation->request.SetURL(KURL(request)); - operation->request.SetMethod("GET"); + operation->request = mojom::blink::FetchAPIRequest::New(); + operation->request->url = KURL(request); + operation->request->method = String("GET"); mojom::blink::CacheStorageCacheAssociatedPtr cache_ptr; cache_ptr.Bind(std::move(result->get_cache())); @@ -615,11 +617,11 @@ callback->sendFailure(response); return; } - WebServiceWorkerRequest request; - request.SetURL(KURL(request_url)); - request.SetMethod("GET"); + auto request = mojom::blink::FetchAPIRequest::New(); + request->url = KURL(request_url); + request->method = String("GET"); cache_storage->Match( - request, mojom::blink::QueryParams::New(), + std::move(request), mojom::blink::QueryParams::New(), WTF::Bind( [](std::unique_ptr<RequestCachedResponseCallback> callback, mojom::blink::MatchResultPtr result) {
diff --git a/third_party/blink/renderer/modules/csspaint/paint_worklet_test.cc b/third_party/blink/renderer/modules/csspaint/paint_worklet_test.cc index 082359e..86432e3 100644 --- a/third_party/blink/renderer/modules/csspaint/paint_worklet_test.cc +++ b/third_party/blink/renderer/modules/csspaint/paint_worklet_test.cc
@@ -69,7 +69,8 @@ int paint_cnt_to_switch, size_t expected_num_paints_before_switch, TestPaintWorklet* paint_worklet_to_test) { - paint_worklet_to_test->GetFrame()->View()->UpdateAllLifecyclePhases(); + paint_worklet_to_test->GetFrame()->View()->UpdateAllLifecyclePhases( + DocumentLifecycle::LifecycleUpdateReason::kTest); paint_worklet_to_test->SetPaintsToSwitch(paint_cnt_to_switch); size_t previously_selected_global_scope = paint_worklet_to_test->GetActiveGlobalScope();
diff --git a/third_party/blink/renderer/modules/mediastream/input_device_info.cc b/third_party/blink/renderer/modules/mediastream/input_device_info.cc index 514303b..b7edac2 100644 --- a/third_party/blink/renderer/modules/mediastream/input_device_info.cc +++ b/third_party/blink/renderer/modules/mediastream/input_device_info.cc
@@ -5,6 +5,8 @@ #include "third_party/blink/renderer/modules/mediastream/input_device_info.h" #include <algorithm> + +#include "third_party/blink/public/platform/web_media_stream_track.h" #include "third_party/blink/renderer/modules/mediastream/media_track_capabilities.h" namespace blink { @@ -131,6 +133,8 @@ break; } capabilities->setFacingMode(facing_mode); + capabilities->setResizeMode({WebMediaStreamTrack::kResizeModeNone, + WebMediaStreamTrack::kResizeModeRescale}); } return capabilities; }
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_track.cc b/third_party/blink/renderer/modules/mediastream/media_stream_track.cc index 6b48962..a25a3f85 100644 --- a/third_party/blink/renderer/modules/mediastream/media_stream_track.cc +++ b/third_party/blink/renderer/modules/mediastream/media_stream_track.cc
@@ -393,6 +393,8 @@ break; } capabilities->setFacingMode(facing_mode); + capabilities->setResizeMode({WebMediaStreamTrack::kResizeModeNone, + WebMediaStreamTrack::kResizeModeRescale}); } return capabilities; }
diff --git a/third_party/blink/renderer/modules/mediastream/media_track_capabilities.idl b/third_party/blink/renderer/modules/mediastream/media_track_capabilities.idl index b6f68f95..8fa90be 100644 --- a/third_party/blink/renderer/modules/mediastream/media_track_capabilities.idl +++ b/third_party/blink/renderer/modules/mediastream/media_track_capabilities.idl
@@ -8,6 +8,7 @@ DoubleRange aspectRatio; DoubleRange frameRate; sequence<DOMString> facingMode; + sequence<DOMString> resizeMode; sequence<boolean> echoCancellation; // See http://crbug.com/846270. [OriginTrialEnabled=ExperimentalHardwareEchoCancellation] sequence<DOMString> echoCancellationType;
diff --git a/third_party/blink/renderer/modules/peerconnection/call_setup_state_tracker.cc b/third_party/blink/renderer/modules/peerconnection/call_setup_state_tracker.cc index bf4b8ec..1a26852 100644 --- a/third_party/blink/renderer/modules/peerconnection/call_setup_state_tracker.cc +++ b/third_party/blink/renderer/modules/peerconnection/call_setup_state_tracker.cc
@@ -6,6 +6,22 @@ namespace blink { +namespace { + +bool IsRejectedOffererState(OffererState state) { + return state == OffererState::kCreateOfferRejected || + state == OffererState::kSetLocalOfferRejected || + state == OffererState::kSetRemoteAnswerRejected; +} + +bool IsRejectedAnswererState(AnswererState state) { + return state == AnswererState::kSetRemoteOfferRejected || + state == AnswererState::kCreateAnswerRejected || + state == AnswererState::kSetLocalAnswerRejected; +} + +} // namespace + CallSetupStateTracker::CallSetupStateTracker() : valid_offerer_transitions_( {std::make_pair(OffererState::kNotStarted, @@ -65,7 +81,8 @@ AnswererState::kSetLocalAnswerResolved), }), offerer_state_(OffererState::kNotStarted), - answerer_state_(AnswererState::kNotStarted) {} + answerer_state_(AnswererState::kNotStarted), + has_ever_failed_(false) {} OffererState CallSetupStateTracker::offerer_state() const { return offerer_state_; @@ -75,6 +92,20 @@ return answerer_state_; } +CallSetupState CallSetupStateTracker::CallSetupState() const { + if (offerer_state_ == OffererState::kNotStarted && + answerer_state_ == AnswererState::kNotStarted) { + return CallSetupState::kNotStarted; + } + if (offerer_state_ == OffererState::kSetRemoteAnswerResolved || + answerer_state_ == AnswererState::kSetLocalAnswerResolved) { + return CallSetupState::kSucceeded; + } + if (has_ever_failed_) + return CallSetupState::kFailed; + return CallSetupState::kStarted; +} + bool CallSetupStateTracker::NoteOffererStateEvent(OffererState event) { auto transition = std::make_pair(offerer_state_, event); if (valid_offerer_transitions_.find(transition) == @@ -82,6 +113,8 @@ return false; } offerer_state_ = event; + if (IsRejectedOffererState(offerer_state_)) + has_ever_failed_ = true; return true; } @@ -92,6 +125,8 @@ return false; } answerer_state_ = event; + if (IsRejectedAnswererState(answerer_state_)) + has_ever_failed_ = true; return true; }
diff --git a/third_party/blink/renderer/modules/peerconnection/call_setup_state_tracker.h b/third_party/blink/renderer/modules/peerconnection/call_setup_state_tracker.h index 883126a..4202740 100644 --- a/third_party/blink/renderer/modules/peerconnection/call_setup_state_tracker.h +++ b/third_party/blink/renderer/modules/peerconnection/call_setup_state_tracker.h
@@ -64,12 +64,42 @@ kMaxValue = kSetLocalAnswerResolved, }; +// A metric reflecting the most successful attempt towards reaching a connected +// state. It's a simplified view based on a CallSetupStateTracker's OffererState +// and AnswererState. Transition graph: +// +// kNotStarted +// v +// kStarted ----+ +// v | +// kFailed | +// v | +// kSucceded <--+ +// +enum class CallSetupState { + // OffererState and AnswererState are both in kNotStarted. + kNotStarted = 0, + // OffererState or AnswererState have had a value other than kNotStarted, but + // the conditions for any of the other states have not been reached. + kStarted = 1, + // OffererState or AnswererState have or have had one of the "rejected" + // states, and the condition for kSucceeded has not been reached. + kFailed = 2, + // OffererState or AnswererState is in the final "resolved" state - + // OffererState::kSetRemoteAnswerResolved or + // AnswererState::kSetLocalAnswerResolved. + kSucceeded = 3, + + kMaxValue = kSucceeded, +}; + class MODULES_EXPORT CallSetupStateTracker { public: CallSetupStateTracker(); OffererState offerer_state() const; AnswererState answerer_state() const; + CallSetupState CallSetupState() const; bool NoteOffererStateEvent(OffererState event); bool NoteAnswererStateEvent(AnswererState event); @@ -82,6 +112,9 @@ OffererState offerer_state_; AnswererState answerer_state_; + // If the tracker has ever been in any of the "rejected" states. This remains + // true even if the peer connection recovers to a non-"rejected" state. + bool has_ever_failed_; }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/peerconnection/call_setup_state_tracker_unittest.cc b/third_party/blink/renderer/modules/peerconnection/call_setup_state_tracker_unittest.cc index 693a622..ad8b434 100644 --- a/third_party/blink/renderer/modules/peerconnection/call_setup_state_tracker_unittest.cc +++ b/third_party/blink/renderer/modules/peerconnection/call_setup_state_tracker_unittest.cc
@@ -127,6 +127,7 @@ TEST_F(CallSetupStateTrackerTest, InitialState) { EXPECT_EQ(OffererState::kNotStarted, tracker_.offerer_state()); EXPECT_EQ(AnswererState::kNotStarted, tracker_.answerer_state()); + EXPECT_EQ(CallSetupState::kNotStarted, tracker_.CallSetupState()); } TEST_F(CallSetupStateTrackerTest, OffererSuccessfulNegotiation) { @@ -135,6 +136,7 @@ EXPECT_TRUE( tracker_.NoteOffererStateEvent(OffererState::kCreateOfferPending)); EXPECT_EQ(OffererState::kCreateOfferPending, tracker_.offerer_state()); + EXPECT_EQ(CallSetupState::kStarted, tracker_.CallSetupState()); EXPECT_TRUE(VerifyOnlyReachableStates<OffererState>( {OffererState::kCreateOfferResolved, OffererState::kCreateOfferRejected})); @@ -160,18 +162,22 @@ EXPECT_TRUE(VerifyOnlyReachableStates<OffererState>( {OffererState::kSetRemoteAnswerResolved, OffererState::kSetRemoteAnswerRejected})); + EXPECT_EQ(CallSetupState::kStarted, tracker_.CallSetupState()); EXPECT_TRUE( tracker_.NoteOffererStateEvent(OffererState::kSetRemoteAnswerResolved)); EXPECT_EQ(OffererState::kSetRemoteAnswerResolved, tracker_.offerer_state()); + EXPECT_EQ(CallSetupState::kSucceeded, tracker_.CallSetupState()); EXPECT_TRUE(VerifyOnlyReachableStates<OffererState>({})); } TEST_F(CallSetupStateTrackerTest, OffererCreateOfferRejected) { EXPECT_TRUE( tracker_.NoteOffererStateEvent(OffererState::kCreateOfferPending)); + EXPECT_EQ(CallSetupState::kStarted, tracker_.CallSetupState()); EXPECT_TRUE( tracker_.NoteOffererStateEvent(OffererState::kCreateOfferRejected)); EXPECT_EQ(OffererState::kCreateOfferRejected, tracker_.offerer_state()); + EXPECT_EQ(CallSetupState::kFailed, tracker_.CallSetupState()); EXPECT_TRUE(VerifyOnlyReachableStates<OffererState>( {OffererState::kCreateOfferResolved})); } @@ -183,9 +189,11 @@ tracker_.NoteOffererStateEvent(OffererState::kCreateOfferResolved)); EXPECT_TRUE( tracker_.NoteOffererStateEvent(OffererState::kSetLocalOfferPending)); + EXPECT_EQ(CallSetupState::kStarted, tracker_.CallSetupState()); EXPECT_TRUE( tracker_.NoteOffererStateEvent(OffererState::kSetLocalOfferRejected)); EXPECT_EQ(OffererState::kSetLocalOfferRejected, tracker_.offerer_state()); + EXPECT_EQ(CallSetupState::kFailed, tracker_.CallSetupState()); EXPECT_TRUE(VerifyOnlyReachableStates<OffererState>( {OffererState::kSetLocalOfferResolved})); } @@ -201,19 +209,47 @@ tracker_.NoteOffererStateEvent(OffererState::kSetLocalOfferResolved)); EXPECT_TRUE( tracker_.NoteOffererStateEvent(OffererState::kSetRemoteAnswerPending)); + EXPECT_EQ(CallSetupState::kStarted, tracker_.CallSetupState()); EXPECT_TRUE( tracker_.NoteOffererStateEvent(OffererState::kSetRemoteAnswerRejected)); EXPECT_EQ(OffererState::kSetRemoteAnswerRejected, tracker_.offerer_state()); + EXPECT_EQ(CallSetupState::kFailed, tracker_.CallSetupState()); EXPECT_TRUE(VerifyOnlyReachableStates<OffererState>( {OffererState::kSetRemoteAnswerResolved})); } +TEST_F(CallSetupStateTrackerTest, OffererRejectThenSucceed) { + EXPECT_TRUE( + tracker_.NoteOffererStateEvent(OffererState::kCreateOfferPending)); + EXPECT_TRUE( + tracker_.NoteOffererStateEvent(OffererState::kCreateOfferResolved)); + EXPECT_TRUE( + tracker_.NoteOffererStateEvent(OffererState::kSetLocalOfferPending)); + EXPECT_TRUE( + tracker_.NoteOffererStateEvent(OffererState::kSetLocalOfferResolved)); + EXPECT_TRUE( + tracker_.NoteOffererStateEvent(OffererState::kSetRemoteAnswerPending)); + EXPECT_EQ(CallSetupState::kStarted, tracker_.CallSetupState()); + EXPECT_TRUE( + tracker_.NoteOffererStateEvent(OffererState::kSetRemoteAnswerRejected)); + EXPECT_EQ(CallSetupState::kFailed, tracker_.CallSetupState()); + // Pending another operation should not revert the states to "pending" or + // "started". + EXPECT_FALSE( + tracker_.NoteOffererStateEvent(OffererState::kSetRemoteAnswerPending)); + EXPECT_EQ(CallSetupState::kFailed, tracker_.CallSetupState()); + EXPECT_TRUE( + tracker_.NoteOffererStateEvent(OffererState::kSetRemoteAnswerResolved)); + EXPECT_EQ(CallSetupState::kSucceeded, tracker_.CallSetupState()); +} + TEST_F(CallSetupStateTrackerTest, AnswererSuccessfulNegotiation) { EXPECT_TRUE(VerifyOnlyReachableStates<AnswererState>( {AnswererState::kSetRemoteOfferPending})); EXPECT_TRUE( tracker_.NoteAnswererStateEvent(AnswererState::kSetRemoteOfferPending)); EXPECT_EQ(AnswererState::kSetRemoteOfferPending, tracker_.answerer_state()); + EXPECT_EQ(CallSetupState::kStarted, tracker_.CallSetupState()); EXPECT_TRUE(VerifyOnlyReachableStates<AnswererState>( {AnswererState::kSetRemoteOfferResolved, AnswererState::kSetRemoteOfferRejected})); @@ -239,18 +275,22 @@ EXPECT_TRUE(VerifyOnlyReachableStates<AnswererState>( {AnswererState::kSetLocalAnswerResolved, AnswererState::kSetLocalAnswerRejected})); + EXPECT_EQ(CallSetupState::kStarted, tracker_.CallSetupState()); EXPECT_TRUE( tracker_.NoteAnswererStateEvent(AnswererState::kSetLocalAnswerResolved)); EXPECT_EQ(AnswererState::kSetLocalAnswerResolved, tracker_.answerer_state()); + EXPECT_EQ(CallSetupState::kSucceeded, tracker_.CallSetupState()); EXPECT_TRUE(VerifyOnlyReachableStates<AnswererState>({})); } TEST_F(CallSetupStateTrackerTest, AnswererSetRemoteOfferRejected) { EXPECT_TRUE( tracker_.NoteAnswererStateEvent(AnswererState::kSetRemoteOfferPending)); + EXPECT_EQ(CallSetupState::kStarted, tracker_.CallSetupState()); EXPECT_TRUE( tracker_.NoteAnswererStateEvent(AnswererState::kSetRemoteOfferRejected)); EXPECT_EQ(AnswererState::kSetRemoteOfferRejected, tracker_.answerer_state()); + EXPECT_EQ(CallSetupState::kFailed, tracker_.CallSetupState()); EXPECT_TRUE(VerifyOnlyReachableStates<AnswererState>( {AnswererState::kSetRemoteOfferResolved})); } @@ -262,9 +302,11 @@ tracker_.NoteAnswererStateEvent(AnswererState::kSetRemoteOfferResolved)); EXPECT_TRUE( tracker_.NoteAnswererStateEvent(AnswererState::kCreateAnswerPending)); + EXPECT_EQ(CallSetupState::kStarted, tracker_.CallSetupState()); EXPECT_TRUE( tracker_.NoteAnswererStateEvent(AnswererState::kCreateAnswerRejected)); EXPECT_EQ(AnswererState::kCreateAnswerRejected, tracker_.answerer_state()); + EXPECT_EQ(CallSetupState::kFailed, tracker_.CallSetupState()); EXPECT_TRUE(VerifyOnlyReachableStates<AnswererState>( {AnswererState::kCreateAnswerResolved})); } @@ -280,11 +322,63 @@ tracker_.NoteAnswererStateEvent(AnswererState::kCreateAnswerResolved)); EXPECT_TRUE( tracker_.NoteAnswererStateEvent(AnswererState::kSetLocalAnswerPending)); + EXPECT_EQ(CallSetupState::kStarted, tracker_.CallSetupState()); EXPECT_TRUE( tracker_.NoteAnswererStateEvent(AnswererState::kSetLocalAnswerRejected)); EXPECT_EQ(AnswererState::kSetLocalAnswerRejected, tracker_.answerer_state()); + EXPECT_EQ(CallSetupState::kFailed, tracker_.CallSetupState()); EXPECT_TRUE(VerifyOnlyReachableStates<AnswererState>( {AnswererState::kSetLocalAnswerResolved})); } +TEST_F(CallSetupStateTrackerTest, AnswererRejectThenSucceed) { + EXPECT_TRUE( + tracker_.NoteAnswererStateEvent(AnswererState::kSetRemoteOfferPending)); + EXPECT_TRUE( + tracker_.NoteAnswererStateEvent(AnswererState::kSetRemoteOfferResolved)); + EXPECT_TRUE( + tracker_.NoteAnswererStateEvent(AnswererState::kCreateAnswerPending)); + EXPECT_TRUE( + tracker_.NoteAnswererStateEvent(AnswererState::kCreateAnswerResolved)); + EXPECT_TRUE( + tracker_.NoteAnswererStateEvent(AnswererState::kSetLocalAnswerPending)); + EXPECT_EQ(CallSetupState::kStarted, tracker_.CallSetupState()); + EXPECT_TRUE( + tracker_.NoteAnswererStateEvent(AnswererState::kSetLocalAnswerRejected)); + EXPECT_EQ(CallSetupState::kFailed, tracker_.CallSetupState()); + // Pending another operation should not revert the states to "pending" or + // "started". + EXPECT_FALSE( + tracker_.NoteAnswererStateEvent(AnswererState::kSetLocalAnswerPending)); + EXPECT_EQ(CallSetupState::kFailed, tracker_.CallSetupState()); + EXPECT_TRUE( + tracker_.NoteAnswererStateEvent(AnswererState::kSetLocalAnswerResolved)); + EXPECT_EQ(CallSetupState::kSucceeded, tracker_.CallSetupState()); +} + +// Succeeding in one role and subsequently failing in another should not revert +// the call setup state from kSucceeded; the most succeessful attempt would +// still have been successful. +TEST_F(CallSetupStateTrackerTest, OffererSucceedAnswererFail) { + EXPECT_TRUE( + tracker_.NoteOffererStateEvent(OffererState::kCreateOfferPending)); + EXPECT_TRUE( + tracker_.NoteOffererStateEvent(OffererState::kCreateOfferResolved)); + EXPECT_TRUE( + tracker_.NoteOffererStateEvent(OffererState::kSetLocalOfferPending)); + EXPECT_TRUE( + tracker_.NoteOffererStateEvent(OffererState::kSetLocalOfferResolved)); + EXPECT_TRUE( + tracker_.NoteOffererStateEvent(OffererState::kSetRemoteAnswerPending)); + EXPECT_TRUE( + tracker_.NoteOffererStateEvent(OffererState::kSetRemoteAnswerResolved)); + EXPECT_EQ(CallSetupState::kSucceeded, tracker_.CallSetupState()); + EXPECT_TRUE( + tracker_.NoteAnswererStateEvent(AnswererState::kSetRemoteOfferPending)); + EXPECT_TRUE( + tracker_.NoteAnswererStateEvent(AnswererState::kSetRemoteOfferRejected)); + // Still succeeded. + EXPECT_EQ(CallSetupState::kSucceeded, tracker_.CallSetupState()); +} + } // namespace blink
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc index ab5faab3..2e1688a 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
@@ -415,6 +415,7 @@ configuration->iceCandidatePoolSize(); if (configuration->hasRtcAudioJitterBufferMaxPackets()) { + UseCounter::Count(context, WebFeature::kRTCMaxAudioBufferSize); web_configuration.audio_jitter_buffer_max_packets = static_cast<int>(configuration->rtcAudioJitterBufferMaxPackets()); }
diff --git a/third_party/blink/renderer/modules/wake_lock/screen_wake_lock_test.cc b/third_party/blink/renderer/modules/wake_lock/screen_wake_lock_test.cc index f10af7ba1..6e776116 100644 --- a/third_party/blink/renderer/modules/wake_lock/screen_wake_lock_test.cc +++ b/third_party/blink/renderer/modules/wake_lock/screen_wake_lock_test.cc
@@ -79,9 +79,9 @@ frame_test_helpers::LoadFrame( web_view_helper_.GetWebView()->MainFrameImpl(), "http://example.com/foo.html"); - web_view_helper_.GetWebView() - ->MainFrameWidget() - ->UpdateAllLifecyclePhases(); + + web_view_helper_.GetWebView()->MainFrameWidget()->UpdateAllLifecyclePhases( + WebWidget::LifecycleUpdateReason::kTest); } LocalFrame* GetFrame() {
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn index ec33c84..25ec990 100644 --- a/third_party/blink/renderer/platform/BUILD.gn +++ b/third_party/blink/renderer/platform/BUILD.gn
@@ -1211,7 +1211,6 @@ "mojo/bluetooth_struct_traits.h", "mojo/canonical_cookie_mojom_traits.cc", "mojo/canonical_cookie_mojom_traits.h", - "mojo/fetch_api_request_struct_traits.cc", "mojo/interface_invalidator.cc", "mojo/interface_invalidator.h", "mojo/mojo_helper.h",
diff --git a/third_party/blink/renderer/platform/bindings/DEPS b/third_party/blink/renderer/platform/bindings/DEPS index 60bef51..455e089 100644 --- a/third_party/blink/renderer/platform/bindings/DEPS +++ b/third_party/blink/renderer/platform/bindings/DEPS
@@ -11,6 +11,7 @@ "+third_party/blink/renderer/platform/heap", "+third_party/blink/renderer/platform/instance_counters.h", "+third_party/blink/renderer/platform/instrumentation", + "+third_party/blink/renderer/platform/memory_coordinator.h", "+third_party/blink/renderer/platform/platform_export.h", "+third_party/blink/renderer/platform/runtime_enabled_features.h", "+third_party/blink/renderer/platform/scheduler",
diff --git a/third_party/blink/renderer/platform/bindings/parkable_string.cc b/third_party/blink/renderer/platform/bindings/parkable_string.cc index f1f4b4cc..258a459 100644 --- a/third_party/blink/renderer/platform/bindings/parkable_string.cc +++ b/third_party/blink/renderer/platform/bindings/parkable_string.cc
@@ -199,21 +199,32 @@ return length_ * (is_8bit() ? sizeof(LChar) : sizeof(UChar)); } -bool ParkableStringImpl::Park() { +bool ParkableStringImpl::Park(ParkingMode mode) { AssertOnValidThread(); MutexLocker locker(mutex_); DCHECK(may_be_parked_); if (state_ == State::kUnparked && CanParkNow()) { - // |string_|'s data should not be touched except in the compression task. - AsanPoisonString(string_); - // |params| keeps |this| alive until |OnParkingCompleteOnMainThread()|. - auto params = std::make_unique<CompressionTaskParams>( - this, string_.Bytes(), string_.CharactersSizeInBytes(), - Thread::Current()->GetTaskRunner()); - background_scheduler::PostOnBackgroundThread( - FROM_HERE, CrossThreadBind(&ParkableStringImpl::CompressInBackground, - WTF::Passed(std::move(params)))); - state_ = State::kParkingInProgress; + // Parking can proceed synchronously. + if (has_compressed_data()) { + RecordParkingAction(ParkingAction::kParkedInBackground); + state_ = State::kParked; + ParkableStringManager::Instance().OnParked(this, string_.Impl()); + + // Must unpoison the memory before releasing it. + AsanUnpoisonString(string_); + string_ = String(); + } else if (mode == ParkingMode::kAlways) { + // |string_|'s data should not be touched except in the compression task. + AsanPoisonString(string_); + // |params| keeps |this| alive until |OnParkingCompleteOnMainThread()|. + auto params = std::make_unique<CompressionTaskParams>( + this, string_.Bytes(), string_.CharactersSizeInBytes(), + Thread::Current()->GetTaskRunner()); + background_scheduler::PostOnBackgroundThread( + FROM_HERE, CrossThreadBind(&ParkableStringImpl::CompressInBackground, + WTF::Passed(std::move(params)))); + state_ = State::kParkingInProgress; + } } return state_ == State::kParked || state_ == State::kParkingInProgress; @@ -271,7 +282,6 @@ // the string we need, nothing else to do than to abort. CHECK(compression::GzipUncompress(compressed_string_piece, uncompressed_string_piece)); - compressed_ = nullptr; string_ = uncompressed; state_ = State::kUnparked; ParkableStringManager::Instance().OnUnparked(this, string_.Impl()); @@ -303,9 +313,9 @@ if (CanParkNow() && compressed) { RecordParkingAction(ParkingAction::kParkedInBackground); state_ = State::kParked; + compressed_ = std::move(compressed); ParkableStringManager::Instance().OnParked(this, string_.Impl()); - compressed_ = std::move(compressed); // Must unpoison the memory before releasing it. AsanUnpoisonString(string_); string_ = String();
diff --git a/third_party/blink/renderer/platform/bindings/parkable_string.h b/third_party/blink/renderer/platform/bindings/parkable_string.h index ce4688e..d828bcc9 100644 --- a/third_party/blink/renderer/platform/bindings/parkable_string.h +++ b/third_party/blink/renderer/platform/bindings/parkable_string.h
@@ -49,6 +49,7 @@ }; enum class ParkableState { kParkable, kNotParkable }; + enum class ParkingMode { kIfCompressedDataExists, kAlways }; // Not all parkable strings can actually be parked. If |parkable| is // kNotParkable, then one cannot call |Park()|, and the underlying StringImpl @@ -69,19 +70,26 @@ unsigned CharactersSizeInBytes() const; // A parked string cannot be accessed until it has been |Unpark()|-ed. - // Returns true iff the string has been parked. - bool Park(); + // + // Parking may be synchronous, and will be if compressed data is already + // available. If |mode| is |kIfCompressedDataExists|, then parking will always + // be synchronous. + // + // Returns true if the string is being parked or has been parked. + bool Park(ParkingMode mode); // Returns true iff the string can be parked. This does not mean that the // string can be parked now, merely that it is eligible to be parked at some // point. bool may_be_parked() const { return may_be_parked_; } // Returns true if the string is parked. bool is_parked() const; - // Returns the compressed size, must not be called unless the string is - // compressed. + // Returns whether synchronous parking is possible, that is the string was + // parked in the past. + bool has_compressed_data() const { return !!compressed_; } + // Returns the compressed size, must not be called unless the string has a + // compressed representation. size_t compressed_size() const { - DCHECK(is_parked()); - DCHECK(compressed_); + DCHECK(has_compressed_data()); return compressed_->size(); } @@ -124,15 +132,8 @@ #endif } - FRIEND_TEST_ALL_PREFIXES(ParkableStringTest, Park); - FRIEND_TEST_ALL_PREFIXES(ParkableStringTest, AbortParking); - FRIEND_TEST_ALL_PREFIXES(ParkableStringTest, Unpark); FRIEND_TEST_ALL_PREFIXES(ParkableStringTest, LockUnlock); FRIEND_TEST_ALL_PREFIXES(ParkableStringTest, LockParkedString); - FRIEND_TEST_ALL_PREFIXES(ParkableStringTest, TableSimple); - FRIEND_TEST_ALL_PREFIXES(ParkableStringTest, TableMultiple); - FRIEND_TEST_ALL_PREFIXES(ParkableStringTest, AsanPoisoning); - FRIEND_TEST_ALL_PREFIXES(ParkableStringTest, Compression); DISALLOW_COPY_AND_ASSIGN(ParkableStringImpl); };
diff --git a/third_party/blink/renderer/platform/bindings/parkable_string_manager.cc b/third_party/blink/renderer/platform/bindings/parkable_string_manager.cc index 581abd1..caf1761 100644 --- a/third_party/blink/renderer/platform/bindings/parkable_string_manager.cc +++ b/third_party/blink/renderer/platform/bindings/parkable_string_manager.cc
@@ -12,22 +12,35 @@ #include "base/single_thread_task_runner.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/renderer/platform/bindings/parkable_string.h" +#include "third_party/blink/renderer/platform/memory_coordinator.h" #include "third_party/blink/renderer/platform/scheduler/public/thread.h" #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" +#include "third_party/blink/renderer/platform/wtf/vector.h" #include "third_party/blink/renderer/platform/wtf/wtf.h" namespace blink { +class OnPurgeMemoryListener : public GarbageCollected<OnPurgeMemoryListener>, + public MemoryCoordinatorClient { + USING_GARBAGE_COLLECTED_MIXIN(OnPurgeMemoryListener); + + void OnPurgeMemory() override { + ParkableStringManager::Instance().ParkAllIfRendererBackgrounded( + ParkableStringImpl::ParkingMode::kAlways); + } +}; + ParkableStringManager& ParkableStringManager::Instance() { DCHECK(IsMainThread()); DEFINE_STATIC_LOCAL(ParkableStringManager, instance, ()); return instance; } -ParkableStringManager::~ParkableStringManager() {} +ParkableStringManager::~ParkableStringManager() = default; void ParkableStringManager::SetRendererBackgrounded(bool backgrounded) { + DCHECK(IsMainThread()); backgrounded_ = backgrounded; if (backgrounded_) { @@ -37,7 +50,8 @@ task_runner->PostDelayedTask( FROM_HERE, base::BindOnce(&ParkableStringManager::ParkAllIfRendererBackgrounded, - base::Unretained(this)), + base::Unretained(this), + ParkableStringImpl::ParkingMode::kAlways), base::TimeDelta::FromSeconds(kParkingDelayInSeconds)); // We only want to record statistics in the following case: a foreground tab // goes to background, and stays in background until the stats are recorded, @@ -46,11 +60,15 @@ // To that end: // 1. Don't post a recording task if one has been posted and hasn't run yet. // 2. Any background -> foreground transition between now and the - // recording task running cancels stats recording. + // recording task running cancels the task. + // + // Also drop strings that can be dropped cheaply in this task, to prevent + // used-once strings from increasing memory usage. if (!waiting_to_record_stats_) { task_runner->PostDelayedTask( FROM_HERE, - base::BindOnce(&ParkableStringManager::RecordStatistics, + base::BindOnce(&ParkableStringManager:: + DropStringsWithCompressedDataAndRecordStatistics, base::Unretained(this)), base::TimeDelta::FromSeconds(kParkingDelayInSeconds + kStatisticsRecordingDelayInSeconds)); @@ -66,6 +84,7 @@ } bool ParkableStringManager::IsRendererBackgrounded() const { + DCHECK(IsMainThread()); return backgrounded_; } @@ -79,6 +98,7 @@ scoped_refptr<ParkableStringImpl> ParkableStringManager::Add( scoped_refptr<StringImpl>&& string) { + DCHECK(IsMainThread()); StringImpl* raw_ptr = string.get(); auto it = unparked_strings_.find(raw_ptr); if (it != unparked_strings_.end()) @@ -125,8 +145,10 @@ unparked_strings_.insert(new_unparked_string, was_parked_string); } -void ParkableStringManager::ParkAllIfRendererBackgrounded() { +void ParkableStringManager::ParkAllIfRendererBackgrounded( + ParkableStringImpl::ParkingMode mode) { DCHECK(IsMainThread()); + if (!IsRendererBackgrounded()) return; @@ -137,22 +159,39 @@ for (ParkableStringImpl* str : parked_strings_) total_size += str->CharactersSizeInBytes(); - for (ParkableStringImpl* str : unparked_strings_.Values()) { - str->Park(); // Parking is asynchronous. + // Parking may be synchronous, need to copy values first. + // In case of synchronous parking, |ParkableStringImpl::Park()| calls + // |OnParked()|, which moves the string from |unparked_strings_| + // to |parked_strings_|, hence the need to copy values first. + // + // Efficiency: In practice, either we are parking strings for the first time, + // and |unparked_strings_| can contain a few 10s of strings (and we will + // trigger expensive compression), or this is a subsequent one, and + // |unparked_strings_| will have few entries. + WTF::Vector<ParkableStringImpl*> unparked; + unparked.ReserveCapacity(unparked_strings_.size()); + for (ParkableStringImpl* str : unparked_strings_.Values()) + unparked.push_back(str); + + for (ParkableStringImpl* str : unparked) { + str->Park(mode); total_size += str->CharactersSizeInBytes(); } - size_t total_size_kb = total_size / 1000; - UMA_HISTOGRAM_COUNTS_100000("Memory.MovableStringsTotalSizeKb", - total_size_kb); - UMA_HISTOGRAM_COUNTS_1000("Memory.MovableStringsCount", Size()); + // Only collect stats for "full" parking calls. + if (mode == ParkableStringImpl::ParkingMode::kAlways) { + size_t total_size_kb = total_size / 1000; + UMA_HISTOGRAM_COUNTS_100000("Memory.MovableStringsTotalSizeKb", + total_size_kb); + UMA_HISTOGRAM_COUNTS_1000("Memory.MovableStringsCount", Size()); + } } size_t ParkableStringManager::Size() const { return parked_strings_.size() + unparked_strings_.size(); } -void ParkableStringManager::RecordStatistics() { +void ParkableStringManager::DropStringsWithCompressedDataAndRecordStatistics() { DCHECK(IsMainThread()); DCHECK(waiting_to_record_stats_); waiting_to_record_stats_ = false; @@ -162,6 +201,11 @@ // renderer is still backgrounded_. DCHECK(IsRendererBackgrounded()); + // We are in the background, drop all the ParkableStrings we can without + // costing any CPU (as we already have the compressed representation). + ParkAllIfRendererBackgrounded( + ParkableStringImpl::ParkingMode::kIfCompressedDataExists); + size_t total_size = 0, total_before_compression_size = 0; size_t total_compressed_size = 0; for (ParkableStringImpl* str : parked_strings_) { @@ -202,6 +246,10 @@ waiting_to_record_stats_(false), should_record_stats_(false), unparked_strings_(), - parked_strings_() {} + parked_strings_() { + // No need to ever unregister, as the only ParkableStringManager instance + // lives forever. + MemoryCoordinator::Instance().RegisterClient(new OnPurgeMemoryListener()); +} } // namespace blink
diff --git a/third_party/blink/renderer/platform/bindings/parkable_string_manager.h b/third_party/blink/renderer/platform/bindings/parkable_string_manager.h index 4c5f88a..262b9dd 100644 --- a/third_party/blink/renderer/platform/bindings/parkable_string_manager.h +++ b/third_party/blink/renderer/platform/bindings/parkable_string_manager.h
@@ -8,6 +8,7 @@ #include "base/feature_list.h" #include "base/macros.h" #include "base/memory/scoped_refptr.h" +#include "third_party/blink/renderer/platform/bindings/parkable_string.h" #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" #include "third_party/blink/renderer/platform/wtf/hash_functions.h" @@ -18,7 +19,6 @@ namespace blink { class ParkableString; -class ParkableStringImpl; const base::Feature kCompressParkableStringsInBackground{ "CompressParkableStringsInBackground", base::FEATURE_DISABLED_BY_DEFAULT}; @@ -37,7 +37,6 @@ bool IsRendererBackgrounded() const; // Number of parked and unparked strings. Public for testing. size_t Size() const; - void ResetForTesting(); // Whether a string is parkable or not. Can be called from any thread. static bool ShouldPark(const StringImpl& string); @@ -49,6 +48,7 @@ private: friend class ParkableString; friend class ParkableStringImpl; + friend class OnPurgeMemoryListener; scoped_refptr<ParkableStringImpl> Add(scoped_refptr<StringImpl>&&); void Remove(ParkableStringImpl*, StringImpl*); @@ -56,8 +56,9 @@ void OnParked(ParkableStringImpl*, StringImpl*); void OnUnparked(ParkableStringImpl*, StringImpl*); - void ParkAllIfRendererBackgrounded(); - void RecordStatistics(); + void ParkAllIfRendererBackgrounded(ParkableStringImpl::ParkingMode mode); + void DropStringsWithCompressedDataAndRecordStatistics(); + void ResetForTesting(); ParkableStringManager(); @@ -68,6 +69,8 @@ unparked_strings_; HashSet<ParkableStringImpl*, PtrHash<ParkableStringImpl>> parked_strings_; + friend class ParkableStringTest; + FRIEND_TEST_ALL_PREFIXES(ParkableStringTest, SynchronousCompression); DISALLOW_COPY_AND_ASSIGN(ParkableStringManager); };
diff --git a/third_party/blink/renderer/platform/bindings/parkable_string_test.cc b/third_party/blink/renderer/platform/bindings/parkable_string_test.cc index cc5e6f1..b186942 100644 --- a/third_party/blink/renderer/platform/bindings/parkable_string_test.cc +++ b/third_party/blink/renderer/platform/bindings/parkable_string_test.cc
@@ -12,12 +12,16 @@ #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h" #include "third_party/blink/renderer/platform/bindings/parkable_string.h" #include "third_party/blink/renderer/platform/bindings/parkable_string_manager.h" +#include "third_party/blink/renderer/platform/memory_coordinator.h" namespace blink { namespace { constexpr size_t kSizeKb = 20; +// Compressed size of the string returned by |MakeLargeString()|. +// Update if the assertion in the |CheckCompressedSize()| test fails. +constexpr size_t kCompressedSize = 55; String MakeLargeString() { std::vector<char> data(kSizeKb * 1000, 'a'); @@ -50,11 +54,25 @@ } bool ParkAndWait(const ParkableString& string) { - bool return_value = string.Impl()->Park(); + bool return_value = + string.Impl()->Park(ParkableStringImpl::ParkingMode::kAlways); RunPostedTasks(); return return_value; } + ParkableString CreateAndParkAll() { + auto& manager = ParkableStringManager::Instance(); + // Checking that there are no other strings, to make sure this doesn't + // cause side-effects. + CHECK_EQ(0u, manager.Size()); + ParkableString parkable(MakeLargeString().ReleaseImpl()); + manager.SetRendererBackgrounded(true); + EXPECT_FALSE(parkable.Impl()->is_parked()); + WaitForDelayedParking(); + EXPECT_TRUE(parkable.Impl()->is_parked()); + return parkable; + } + void SetUp() override { ParkableStringManager::Instance().ResetForTesting(); scoped_feature_list_.InitAndEnableFeature( @@ -73,6 +91,16 @@ base::test::ScopedFeatureList scoped_feature_list_; }; +// The main aim of this test is to check that the compressed size of a string +// doesn't change. If it does, |kCompressedsize| will need to be updated. +TEST_F(ParkableStringTest, CheckCompressedSize) { + ParkableString parkable(MakeLargeString().ReleaseImpl()); + EXPECT_TRUE(parkable.Impl()->Park(ParkableStringImpl::ParkingMode::kAlways)); + RunPostedTasks(); + EXPECT_TRUE(parkable.Impl()->is_parked()); + EXPECT_EQ(kCompressedSize, parkable.Impl()->compressed_size()); +} + TEST_F(ParkableStringTest, Simple) { ParkableString parkable_abc(String("abc").ReleaseImpl()); @@ -117,46 +145,72 @@ ParkableString parkable(MakeLargeString().ReleaseImpl()); EXPECT_TRUE(parkable.may_be_parked()); EXPECT_FALSE(parkable.Impl()->is_parked()); - EXPECT_TRUE(parkable.Impl()->Park()); + EXPECT_TRUE( + parkable.Impl()->Park(ParkableStringImpl::ParkingMode::kAlways)); parkable = ParkableString(); // release the reference. RunPostedTasks(); // Should not crash. } } TEST_F(ParkableStringTest, AbortParking) { - ParkableString parkable(MakeLargeString().ReleaseImpl()); - ParkableStringImpl* impl = parkable.Impl(); + { + ParkableString parkable(MakeLargeString().ReleaseImpl()); + EXPECT_TRUE(parkable.may_be_parked()); + EXPECT_FALSE(parkable.Impl()->is_parked()); - EXPECT_TRUE(parkable.may_be_parked()); - EXPECT_FALSE(impl->is_parked()); + // The string is locked at the end of parking, should cancel it. + EXPECT_TRUE( + parkable.Impl()->Park(ParkableStringImpl::ParkingMode::kAlways)); + parkable.Impl()->Lock(); + RunPostedTasks(); + EXPECT_FALSE(parkable.Impl()->is_parked()); - // The string is locked at the end of parking, should cancel it. - EXPECT_TRUE(impl->Park()); - impl->Lock(); - RunPostedTasks(); - EXPECT_FALSE(impl->is_parked()); + // Unlock, OK to park. + parkable.Impl()->Unlock(); + EXPECT_TRUE(ParkAndWait(parkable)); + } - // Unlock, OK to park. - impl->Unlock(); - EXPECT_TRUE(ParkAndWait(parkable)); - impl->ToString(); + { + ParkableString parkable(MakeLargeString().ReleaseImpl()); + // |ToString()| cancels parking as |content| is kept alive. + EXPECT_TRUE( + parkable.Impl()->Park(ParkableStringImpl::ParkingMode::kAlways)); + { + String content = parkable.Impl()->ToString(); + RunPostedTasks(); + EXPECT_FALSE(parkable.Impl()->is_parked()); + } + EXPECT_TRUE(ParkAndWait(parkable)); + } - // |ToString()| cancels unparking as |content| is kept alive. - EXPECT_TRUE(impl->Park()); - String content = impl->ToString(); - RunPostedTasks(); - EXPECT_FALSE(impl->is_parked()); - content = String(); - EXPECT_TRUE(ParkAndWait(parkable)); - impl->ToString(); + { + ParkableString parkable(MakeLargeString().ReleaseImpl()); + // Transient |Lock()| or |ToString()| doesn't cancel parking. + EXPECT_TRUE( + parkable.Impl()->Park(ParkableStringImpl::ParkingMode::kAlways)); + parkable.Impl()->Lock(); + parkable.Impl()->ToString(); + parkable.Impl()->Unlock(); + RunPostedTasks(); + EXPECT_TRUE(parkable.Impl()->is_parked()); - // Transient |Lock()| or |ToString()| doesn't cancel parking. - EXPECT_TRUE(impl->Park()); - impl->Lock(); - impl->ToString(); - impl->Unlock(); - RunPostedTasks(); - EXPECT_TRUE(impl->is_parked()); + // Synchronous parking respects locking and external references. + parkable.ToString(); + EXPECT_TRUE(parkable.Impl()->has_compressed_data()); + parkable.Lock(); + EXPECT_FALSE( + parkable.Impl()->Park(ParkableStringImpl::ParkingMode::kAlways)); + parkable.Unlock(); + { + String content = parkable.ToString(); + EXPECT_FALSE( + parkable.Impl()->Park(ParkableStringImpl::ParkingMode::kAlways)); + } + // Parking is synchronous. + EXPECT_TRUE( + parkable.Impl()->Park(ParkableStringImpl::ParkingMode::kAlways)); + EXPECT_TRUE(parkable.Impl()->is_parked()); + } } TEST_F(ParkableStringTest, Unpark) { @@ -209,10 +263,8 @@ } TEST_F(ParkableStringTest, LockParkedString) { - ParkableString parkable(MakeLargeString().Impl()); + ParkableString parkable = CreateAndParkAll(); ParkableStringImpl* impl = parkable.Impl(); - EXPECT_EQ(0, impl->lock_depth_); - EXPECT_TRUE(ParkAndWait(parkable)); parkable.Lock(); // Locking doesn't unpark. EXPECT_TRUE(impl->is_parked()); @@ -339,11 +391,14 @@ // - CompressedSizeKb == 0 // - SavingsKb == 19 // - CompressionRatio == 0 (<1%) + size_t expected_savings = kSizeKb * 1000 - kCompressedSize; histogram_tester.ExpectUniqueSample("Memory.ParkableString.CompressedSizeKb", - 0, 1); - histogram_tester.ExpectUniqueSample("Memory.ParkableString.SavingsKb", 19, 1); + kCompressedSize / 1000, 1); + histogram_tester.ExpectUniqueSample("Memory.ParkableString.SavingsKb", + expected_savings / 1000, 1); histogram_tester.ExpectUniqueSample("Memory.ParkableString.CompressionRatio", - 0, 1); + 100 * kCompressedSize / (kSizeKb * 1000), + 1); // Don't record statistics if the renderer moves to foreground before // recording statistics. @@ -358,8 +413,8 @@ histogram_tester.ExpectUniqueSample("Memory.ParkableString.TotalSizeKb", 2 * kSizeKb, 1); - // Calling |RecordStatistics()| resets the state, can now record stats next - // time. + // Calling |ParkStringsWithCompressedDataAndRecordStatistics()| resets the + // state, can now record stats next time. manager.SetRendererBackgrounded(true); parking_count++; WaitForDelayedParking(); @@ -414,7 +469,7 @@ // Non-regression test for crbug.com/905137. TEST_F(ParkableStringTest, CorrectAsanPoisoning) { ParkableString parkable(MakeLargeString().ReleaseImpl()); - EXPECT_TRUE(parkable.Impl()->Park()); + EXPECT_TRUE(parkable.Impl()->Park(ParkableStringImpl::ParkingMode::kAlways)); // A main thread task is posted once compression is done. while (!scoped_task_environment_.MainThreadHasPendingTask()) { parkable.Lock(); @@ -428,18 +483,19 @@ TEST_F(ParkableStringTest, Compression) { base::HistogramTester histogram_tester; - ParkableString parkable(MakeLargeString().Impl()); + ParkableString parkable = CreateAndParkAll(); ParkableStringImpl* impl = parkable.Impl(); - EXPECT_TRUE(impl->Park()); - EXPECT_FALSE(impl->is_parked()); - RunPostedTasks(); EXPECT_TRUE(impl->is_parked()); - EXPECT_TRUE(impl->compressed_); - EXPECT_LT(impl->compressed_->size(), impl->CharactersSizeInBytes()); - parkable.ToString(); + EXPECT_TRUE(impl->has_compressed_data()); + EXPECT_EQ(kCompressedSize, impl->compressed_size()); + parkable.ToString(); // First decompression. EXPECT_FALSE(impl->is_parked()); - EXPECT_EQ(nullptr, impl->compressed_); + EXPECT_TRUE(impl->has_compressed_data()); + EXPECT_TRUE( + impl->Park(ParkableStringImpl::ParkingMode::kIfCompressedDataExists)); + EXPECT_TRUE(impl->is_parked()); + parkable.ToString(); // Second decompression. histogram_tester.ExpectUniqueSample( "Memory.ParkableString.Compression.SizeKb", kSizeKb, 1); @@ -447,12 +503,13 @@ 1); histogram_tester.ExpectTotalCount( "Memory.ParkableString.Compression.ThroughputMBps", 1); + // |parkable| is decompressed twice. histogram_tester.ExpectUniqueSample( - "Memory.ParkableString.Decompression.SizeKb", kSizeKb, 1); + "Memory.ParkableString.Decompression.SizeKb", kSizeKb, 2); histogram_tester.ExpectTotalCount( - "Memory.ParkableString.Decompression.Latency", 1); + "Memory.ParkableString.Decompression.Latency", 2); histogram_tester.ExpectTotalCount( - "Memory.ParkableString.Decompression.ThroughputMBps", 1); + "Memory.ParkableString.Decompression.ThroughputMBps", 2); } TEST_F(ParkableStringTest, DelayedTasks) { @@ -479,4 +536,28 @@ histogram_tester.ExpectTotalCount("Memory.ParkableString.TotalSizeKb", 1); } +TEST_F(ParkableStringTest, SynchronousCompression) { + ParkableStringManager& manager = ParkableStringManager::Instance(); + ParkableString parkable = CreateAndParkAll(); + + parkable.ToString(); + EXPECT_TRUE(parkable.Impl()->has_compressed_data()); + // No waiting, synchronous compression. + manager.ParkAllIfRendererBackgrounded( + ParkableStringImpl::ParkingMode::kIfCompressedDataExists); + EXPECT_TRUE(parkable.Impl()->is_parked()); + scoped_task_environment_.FastForwardUntilNoTasksRemain(); +} + +TEST_F(ParkableStringTest, OnPurgeMemory) { + ParkableString parkable = CreateAndParkAll(); + + parkable.ToString(); + EXPECT_FALSE(parkable.Impl()->is_parked()); + EXPECT_TRUE(parkable.Impl()->has_compressed_data()); + + MemoryCoordinator::Instance().OnPurgeMemory(); + EXPECT_TRUE(parkable.Impl()->is_parked()); +} + } // namespace blink
diff --git a/third_party/blink/renderer/platform/geometry/layout_unit.h b/third_party/blink/renderer/platform/geometry/layout_unit.h index 3cc81b3..834b3b1 100644 --- a/third_party/blink/renderer/platform/geometry/layout_unit.h +++ b/third_party/blink/renderer/platform/geometry/layout_unit.h
@@ -33,6 +33,7 @@ #include <iosfwd> #include <limits> +#include "base/compiler_specific.h" #include "base/numerics/safe_conversions.h" #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" @@ -45,7 +46,7 @@ #if DCHECK_IS_ON() #define REPORT_OVERFLOW(doesOverflow) \ DLOG_IF(ERROR, !(doesOverflow)) << "LayoutUnit overflow !(" << #doesOverflow \ - << ") in " << WTF_PRETTY_FUNCTION + << ") in " << PRETTY_FUNCTION #else #define REPORT_OVERFLOW(doesOverflow) ((void)0) #endif
diff --git a/third_party/blink/renderer/platform/mojo/blink_typemaps.gni b/third_party/blink/renderer/platform/mojo/blink_typemaps.gni index c7fab1a5..80784cd 100644 --- a/third_party/blink/renderer/platform/mojo/blink_typemaps.gni +++ b/third_party/blink/renderer/platform/mojo/blink_typemaps.gni
@@ -22,7 +22,6 @@ "//third_party/blink/renderer/platform/mojo/string.typemap", "//third_party/blink/renderer/platform/mojo/time.typemap", "//third_party/blink/public/platform/modules/bluetooth/bluetooth.typemap", - "//third_party/blink/public/platform/modules/fetch/fetch_api_request.typemap", "//third_party/blink/public/common/manifest/display_mode.typemap", "//third_party/blink/public/common/screen_orientation/screen_orientation_lock_types.typemap", ]
diff --git a/third_party/blink/renderer/platform/mojo/fetch_api_request_struct_traits.cc b/third_party/blink/renderer/platform/mojo/fetch_api_request_struct_traits.cc deleted file mode 100644 index d09f0386..0000000 --- a/third_party/blink/renderer/platform/mojo/fetch_api_request_struct_traits.cc +++ /dev/null
@@ -1,127 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "third_party/blink/renderer/platform/mojo/fetch_api_request_struct_traits.h" - -#include "mojo/public/cpp/bindings/map_traits_wtf_hash_map.h" -#include "mojo/public/cpp/bindings/string_traits_wtf.h" -#include "services/network/public/mojom/fetch_api.mojom-blink.h" -#include "services/network/public/mojom/referrer_policy.mojom-blink.h" -#include "third_party/blink/renderer/platform/blob/serialized_blob_struct_traits.h" -#include "third_party/blink/renderer/platform/mojo/kurl_struct_traits.h" -#include "third_party/blink/renderer/platform/weborigin/referrer.h" - -namespace mojo { - -// static -blink::KURL StructTraits<blink::mojom::FetchAPIRequestDataView, - blink::WebServiceWorkerRequest>:: - url(const blink::WebServiceWorkerRequest& request) { - return request.Url(); -} - -// static -WTF::String StructTraits<blink::mojom::FetchAPIRequestDataView, - blink::WebServiceWorkerRequest>:: - method(const blink::WebServiceWorkerRequest& request) { - return request.Method(); -} - -// static -WTF::HashMap<WTF::String, WTF::String> -StructTraits<blink::mojom::FetchAPIRequestDataView, - blink::WebServiceWorkerRequest>:: - headers(const blink::WebServiceWorkerRequest& request) { - WTF::HashMap<WTF::String, WTF::String> header_map; - for (const auto& pair : request.Headers()) - header_map.insert(pair.key, pair.value); - return header_map; -} - -// static -blink::mojom::blink::ReferrerPtr -StructTraits<blink::mojom::FetchAPIRequestDataView, - blink::WebServiceWorkerRequest>:: - referrer(const blink::WebServiceWorkerRequest& request) { - blink::KURL url; - const blink::Referrer& referrer = request.GetReferrer(); - if (referrer.referrer != blink::Referrer::NoReferrer()) - url = blink::KURL(blink::KURL(), referrer.referrer); - return blink::mojom::blink::Referrer::New( - url, - static_cast<network::mojom::ReferrerPolicy>(referrer.referrer_policy)); -} - -// static -scoped_refptr<blink::BlobDataHandle> StructTraits< - blink::mojom::FetchAPIRequestDataView, - blink::WebServiceWorkerRequest>::blob(const blink::WebServiceWorkerRequest& - request) { - return request.GetBlobDataHandle(); -} - -// static -WTF::String StructTraits<blink::mojom::FetchAPIRequestDataView, - blink::WebServiceWorkerRequest>:: - integrity(const blink::WebServiceWorkerRequest& request) { - return request.Integrity(); -} - -// static -WTF::String StructTraits<blink::mojom::FetchAPIRequestDataView, - blink::WebServiceWorkerRequest>:: - client_id(const blink::WebServiceWorkerRequest& request) { - return request.ClientId(); -} - -// static -bool StructTraits<blink::mojom::FetchAPIRequestDataView, - blink::WebServiceWorkerRequest>:: - Read(blink::mojom::FetchAPIRequestDataView data, - blink::WebServiceWorkerRequest* out) { - network::mojom::FetchRequestMode mode; - blink::mojom::RequestContextType requestContext; - network::mojom::RequestContextFrameType frameType; - blink::KURL url; - WTF::String method; - WTF::HashMap<WTF::String, WTF::String> headers; - scoped_refptr<blink::BlobDataHandle> blob; - blink::mojom::blink::ReferrerPtr referrer; - network::mojom::FetchCredentialsMode credentialsMode; - network::mojom::FetchRedirectMode redirectMode; - WTF::String integrity; - WTF::String clientId; - - if (!data.ReadMode(&mode) || !data.ReadRequestContextType(&requestContext) || - !data.ReadFrameType(&frameType) || !data.ReadUrl(&url) || - !data.ReadMethod(&method) || !data.ReadHeaders(&headers) || - !data.ReadBlob(&blob) || !data.ReadReferrer(&referrer) || - !data.ReadCredentialsMode(&credentialsMode) || - !data.ReadRedirectMode(&redirectMode) || !data.ReadClientId(&clientId) || - !data.ReadIntegrity(&integrity)) { - return false; - } - - out->SetMode(mode); - out->SetIsMainResourceLoad(data.is_main_resource_load()); - out->SetRequestContext(requestContext); - out->SetFrameType(frameType); - out->SetURL(url); - out->SetMethod(method); - for (const auto& pair : headers) - out->SetHeader(pair.key, pair.value); - out->SetBlobDataHandle(blob); - out->SetReferrer(referrer->url.GetString(), referrer->policy); - out->SetCredentialsMode(credentialsMode); - out->SetCacheMode(data.cache_mode()); - out->SetRedirectMode(redirectMode); - out->SetIntegrity(integrity); - out->SetKeepalive(data.keepalive()); - out->SetClientId(clientId); - out->SetIsReload(data.is_reload()); - out->SetIsHistoryNavigation(data.is_history_navigation()); - return true; -} - -} // namespace mojo
diff --git a/third_party/blink/renderer/platform/mojo/fetch_api_request_struct_traits.h b/third_party/blink/renderer/platform/mojo/fetch_api_request_struct_traits.h deleted file mode 100644 index 09432b9..0000000 --- a/third_party/blink/renderer/platform/mojo/fetch_api_request_struct_traits.h +++ /dev/null
@@ -1,90 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_FETCH_API_REQUEST_STRUCT_TRAITS_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_FETCH_API_REQUEST_STRUCT_TRAITS_H_ - -#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom-blink.h" -#include "third_party/blink/public/platform/web_url_request.h" -#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" - -namespace blink { -class KURL; -} - -namespace mojo { - -template <> -struct StructTraits<::blink::mojom::FetchAPIRequestDataView, - ::blink::WebServiceWorkerRequest> { - static ::network::mojom::FetchRequestMode mode( - const ::blink::WebServiceWorkerRequest& request) { - return request.Mode(); - } - - static bool is_main_resource_load( - const ::blink::WebServiceWorkerRequest& request) { - return request.IsMainResourceLoad(); - } - - static ::blink::mojom::RequestContextType request_context_type( - const ::blink::WebServiceWorkerRequest& request) { - return request.GetRequestContext(); - } - - static ::network::mojom::RequestContextFrameType frame_type( - const ::blink::WebServiceWorkerRequest& request) { - return request.GetFrameType(); - } - - static ::blink::KURL url(const ::blink::WebServiceWorkerRequest&); - - static WTF::String method(const ::blink::WebServiceWorkerRequest&); - - static WTF::HashMap<WTF::String, WTF::String> headers( - const ::blink::WebServiceWorkerRequest&); - - static scoped_refptr<::blink::BlobDataHandle> blob( - const ::blink::WebServiceWorkerRequest&); - - static ::blink::mojom::blink::ReferrerPtr referrer( - const ::blink::WebServiceWorkerRequest&); - - static ::network::mojom::FetchCredentialsMode credentials_mode( - const ::blink::WebServiceWorkerRequest& request) { - return request.CredentialsMode(); - } - - static ::blink::mojom::FetchCacheMode cache_mode( - const ::blink::WebServiceWorkerRequest& request) { - return request.CacheMode(); - } - - static ::network::mojom::FetchRedirectMode redirect_mode( - const ::blink::WebServiceWorkerRequest& request) { - return request.RedirectMode(); - } - - static WTF::String integrity(const ::blink::WebServiceWorkerRequest&); - static bool keepalive(const ::blink::WebServiceWorkerRequest& request) { - return request.Keepalive(); - } - static WTF::String client_id(const ::blink::WebServiceWorkerRequest&); - - static bool is_reload(const ::blink::WebServiceWorkerRequest& request) { - return request.IsReload(); - } - - static bool is_history_navigation( - const ::blink::WebServiceWorkerRequest& request) { - return request.IsHistoryNavigation(); - } - - static bool Read(::blink::mojom::FetchAPIRequestDataView, - ::blink::WebServiceWorkerRequest* output); -}; - -} // namespace mojo - -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_FETCH_API_REQUEST_STRUCT_TRAITS_H_
diff --git a/third_party/blink/renderer/platform/wtf/compiler.h b/third_party/blink/renderer/platform/wtf/compiler.h index 40f79d4..56843da 100644 --- a/third_party/blink/renderer/platform/wtf/compiler.h +++ b/third_party/blink/renderer/platform/wtf/compiler.h
@@ -41,16 +41,6 @@ #endif #endif -/* WTF_PRETTY_FUNCTION */ - -#if defined(COMPILER_GCC) -#define WTF_PRETTY_FUNCTION __PRETTY_FUNCTION__ -#elif defined(COMPILER_MSVC) -#define WTF_PRETTY_FUNCTION __FUNCSIG__ -#else -#define WTF_PRETTY_FUNCTION __func__ -#endif - /* NO_SANITIZE_UNRELATED_CAST - Disable runtime checks related to casts between * unrelated objects (-fsanitize=cfi-unrelated-cast or -fsanitize=vptr). */
diff --git a/third_party/blink/renderer/platform/wtf/stack_util.cc b/third_party/blink/renderer/platform/wtf/stack_util.cc index 21f49cf..248f9396 100644 --- a/third_party/blink/renderer/platform/wtf/stack_util.cc +++ b/third_party/blink/renderer/platform/wtf/stack_util.cc
@@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "build/build_config.h" + #include "third_party/blink/renderer/platform/wtf/stack_util.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" @@ -133,10 +135,17 @@ // On Windows stack limits for the current thread are available in // the thread information block (TIB). Its fields can be accessed through // FS segment register on x86 and GS segment register on x86_64. -#ifdef _WIN64 +// On Windows ARM64, stack limits could be retrieved by calling +// GetCurrentThreadStackLimits. This API doesn't work on x86 and x86_64 here +// because it requires Windows 8+. +#if defined(ARCH_CPU_X86_64) return reinterpret_cast<void*>(__readgsqword(offsetof(NT_TIB64, StackBase))); -#else +#elif defined(ARCH_CPU_X86) return reinterpret_cast<void*>(__readfsdword(offsetof(NT_TIB, StackBase))); +#elif defined(ARCH_CPU_ARM64) + ULONG_PTR lowLimit, highLimit; + ::GetCurrentThreadStackLimits(&lowLimit, &highLimit); + return reinterpret_cast<void*>(highLimit); #endif #else #error Unsupported getStackStart on this platform.
diff --git a/third_party/blink/renderer/platform/wtf/type_traits.h b/third_party/blink/renderer/platform/wtf/type_traits.h index f8003ca..dac7ee25 100644 --- a/third_party/blink/renderer/platform/wtf/type_traits.h +++ b/third_party/blink/renderer/platform/wtf/type_traits.h
@@ -25,6 +25,7 @@ #include <cstddef> #include <type_traits> #include <utility> +#include "base/compiler_specific.h" #include "base/template_util.h" #include "build/build_config.h" #include "third_party/blink/renderer/platform/wtf/compiler.h" @@ -34,7 +35,7 @@ // Returns a string that contains the type name of |T| as a substring. template <typename T> inline const char* GetStringWithTypeName() { - return WTF_PRETTY_FUNCTION; + return PRETTY_FUNCTION; } template <typename T>
diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py index 31915f9a..38ae8e30 100755 --- a/tools/clang/scripts/update.py +++ b/tools/clang/scripts/update.py
@@ -35,7 +35,7 @@ CLANG_REVISION = 'HEAD' # This is incremented when pushing a new build of Clang at the same revision. -CLANG_SUB_REVISION=1 +CLANG_SUB_REVISION=4 PACKAGE_VERSION = "%s-%s" % (CLANG_REVISION, CLANG_SUB_REVISION)
diff --git a/tools/determinism/compare_build_artifacts.py b/tools/determinism/compare_build_artifacts.py index f8f2ba3..45a8a62d 100755 --- a/tools/determinism/compare_build_artifacts.py +++ b/tools/determinism/compare_build_artifacts.py
@@ -183,6 +183,14 @@ lhs = json.load(f) with open(second_filepath, 'rb') as f: rhs = json.load(f) + # The isolated files contain the name of the build dir. Until that's + # fixed (https://crbug.com/907488), change the rhs to use the lhs's + # build dir -- we care more about the hash differences than about + # the name of the build dir. + with open(second_filepath, 'rb') as f: + lhs_cwd = lhs['relative_cwd'] + rhs_cwd = rhs['relative_cwd'] + rhs = json.loads(f.read().replace(rhs_cwd, lhs_cwd)) diff = diff_dict(lhs, rhs) if diff: return '\n' + '\n'.join(' ' + line for line in diff.splitlines())
diff --git a/tools/ipc_fuzzer/fuzzer/fuzzer.cc b/tools/ipc_fuzzer/fuzzer/fuzzer.cc index af3ba548..f7ff720 100644 --- a/tools/ipc_fuzzer/fuzzer/fuzzer.cc +++ b/tools/ipc_fuzzer/fuzzer/fuzzer.cc
@@ -9,6 +9,7 @@ #include <utility> #include <vector> +#include "base/compiler_specific.h" #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/memory/shared_memory_handle.h" @@ -33,14 +34,6 @@ #include "tools/ipc_fuzzer/message_lib/all_messages.h" #include "tools/ipc_fuzzer/message_lib/all_message_null_macros.h" -#if defined(COMPILER_GCC) -#define PRETTY_FUNCTION __PRETTY_FUNCTION__ -#elif defined(COMPILER_MSVC) -#define PRETTY_FUNCTION __FUNCSIG__ -#else -#define PRETTY_FUNCTION __FUNCTION__ -#endif - namespace IPC { class Message; } // namespace IPC
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index a8677dc..6d16f9b 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -14917,6 +14917,8 @@ <int value="500" label="ReportSafeBrowsingData"/> <int value="501" label="DeviceWiFiFastTransitionEnabled"/> <int value="502" label="DeviceDisplayResolution"/> + <int value="503" label="PluginVmAllowed"/> + <int value="504" label="PluginVmImage"/> </enum> <enum name="EnterprisePolicyInvalidations"> @@ -29094,6 +29096,7 @@ <int value="-2134333982" label="ShowArcFilesApp:enabled"/> <int value="-2134244069" label="HttpFormWarning:enabled"/> <int value="-2133892372" label="ResamplingInputEvents:disabled"/> + <int value="-2133277113" label="CCTModuleCustomHeader:disabled"/> <int value="-2132591642" label="enable-input-view"/> <int value="-2124839789" label="OmniboxUIExperimentHideSteadyStateUrlSchemeAndSubdomains:enabled"/> @@ -30216,6 +30219,7 @@ <int value="-147283486" label="enable-network-portal-notification"/> <int value="-146552997" label="enable-affiliation-based-matching"/> <int value="-144134779" label="AndroidPayIntegrationV2:disabled"/> + <int value="-143819280" label="google-password-manager:disabled"/> <int value="-143382681" label="InstantTethering:enabled"/> <int value="-141516902" label="UseModernMediaControls:enabled"/> <int value="-138983372" label="DesktopPWAWindowing:disabled"/> @@ -30803,6 +30807,7 @@ <int value="973601997" label="SafeBrowsingUseLocalBlacklistsV2:disabled"/> <int value="975104092" label="show-taps"/> <int value="976079108" label="TouchpadOverscrollHistoryNavigation:disabled"/> + <int value="976278412" label="google-password-manager:enabled"/> <int value="979445973" label="OmniboxSpareRenderer:enabled"/> <int value="980396200" label="enable-new-korean-ime"/> <int value="981818901" label="AppBanners:enabled"/> @@ -31165,6 +31170,7 @@ <int value="1600926040" label="TranslateCompactUI:enabled"/> <int value="1605611615" label="enable-webrtc-srtp-aes-gcm"/> <int value="1611522475" label="AutofillPrimaryInfoStyleExperiment:disabled"/> + <int value="1612206633" label="CCTModuleCustomHeader:enabled"/> <int value="1612446645" label="enable-weak-memorycache"/> <int value="1612871297" label="WebPayments:disabled"/> <int value="1612974229" label="allow-insecure-localhost"/>
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml index 001a729..d047041 100644 --- a/tools/metrics/ukm/ukm.xml +++ b/tools/metrics/ukm/ukm.xml
@@ -2716,6 +2716,18 @@ Measure of memory consumed by live objects in the main heap of V8. </summary> </metric> + <metric name="V8.Main.Heap.CodeLargeObjectSpace"> + <summary> + Measure of memory consumed by the code large object space of the main heap + of V8. + </summary> + </metric> + <metric name="V8.Main.Heap.CodeLargeObjectSpace.AllocatedObjects"> + <summary> + Measure of memory consumed by live objects in the code large object space + of the main heap of V8. + </summary> + </metric> <metric name="V8.Main.Heap.CodeSpace"> <summary> Measure of memory consumed by the code space of the main heap of V8.
diff --git a/tools/perf/core/perf_data_generator.py b/tools/perf/core/perf_data_generator.py index 4e5858a..670e45f 100755 --- a/tools/perf/core/perf_data_generator.py +++ b/tools/perf/core/perf_data_generator.py
@@ -81,7 +81,7 @@ 'num_shards': 7 } ], - 'platform': 'android-webview', + 'platform': 'android-webview-google', 'dimension': { 'pool': 'chrome.tests.perf-webview-fyi', 'os': 'Android', @@ -120,7 +120,7 @@ 'num_shards': 25 } ], - 'platform': 'android-webview', + 'platform': 'android-webview-google', 'dimension': { 'pool': 'chrome.tests.perf-webview', 'os': 'Android', @@ -904,10 +904,8 @@ browser_name = 'reference' elif tester_config['platform'] == 'android': browser_name = 'android-chromium' - elif tester_config['platform'] == 'android-chrome': - browser_name = 'android-chrome' - elif tester_config['platform'] == 'android-webview': - browser_name = 'android-webview' + elif tester_config['platform'].startswith('android-'): + browser_name = tester_config['platform'] elif (tester_config['platform'] == 'win' and tester_config['target_bits'] == 64): browser_name = 'release_x64' @@ -920,7 +918,7 @@ '--upload-results' ] - if browser_name == 'android-webview': + if browser_name.startswith('android-webview'): test_args.append( '--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk')
diff --git a/tools/perf/core/perf_json_config_validator.py b/tools/perf/core/perf_json_config_validator.py index 274a30f..df7cd111 100644 --- a/tools/perf/core/perf_json_config_validator.py +++ b/tools/perf/core/perf_json_config_validator.py
@@ -80,9 +80,11 @@ def _ValidateBrowserType(builder_name, test_config): browser_options = _ParseBrowserFlags(test_config['args']) if 'WebView' in builder_name or 'webview' in builder_name: - if browser_options.browser != 'android-webview': - raise ValueError("%s must use 'android-webview' browser type" % - builder_name) + if browser_options.browser not in ( + 'android-webview', 'android-webview-google'): + raise ValueError( + "%s must use 'android-webview' or 'android-webview-google' browser" % + builder_name) if not browser_options.webview_embedder_apk: raise ValueError('%s must set --webview-embedder-apk flag' % builder_name) elif 'Android' in builder_name or 'android' in builder_name:
diff --git a/ui/base/cocoa/menu_controller_unittest.mm b/ui/base/cocoa/menu_controller_unittest.mm index 2056bed..6a36473 100644 --- a/ui/base/cocoa/menu_controller_unittest.mm +++ b/ui/base/cocoa/menu_controller_unittest.mm
@@ -554,7 +554,8 @@ base::string16 second = ASCIIToUTF16("second"); delegate.SetDynamicLabel(second); const gfx::Image& icon = - ResourceBundle::GetSharedInstance().GetNativeImageNamed(IDR_THROBBER); + ResourceBundle::GetSharedInstance().GetNativeImageNamed( + IDR_EMOJI_FAVICON); delegate.SetDynamicIcon(icon); // Simulate opening the menu and validate that the item label + icon changes. Validate(menu.get(), [menu menu]);
diff --git a/ui/compositor/compositor.cc b/ui/compositor/compositor.cc index 3e8c3da..53589410 100644 --- a/ui/compositor/compositor.cc +++ b/ui/compositor/compositor.cc
@@ -581,7 +581,7 @@ SendDamagedRectsRecursive(child); } -void Compositor::UpdateLayerTreeHost() { +void Compositor::UpdateLayerTreeHost(bool record_main_frame_metrics) { if (!root_layer()) return; SendDamagedRectsRecursive(root_layer());
diff --git a/ui/compositor/compositor.h b/ui/compositor/compositor.h index 728cbd3..6f46fd5b 100644 --- a/ui/compositor/compositor.h +++ b/ui/compositor/compositor.h
@@ -387,7 +387,7 @@ void BeginMainFrame(const viz::BeginFrameArgs& args) override; void BeginMainFrameNotExpectedSoon() override; void BeginMainFrameNotExpectedUntil(base::TimeTicks time) override; - void UpdateLayerTreeHost() override; + void UpdateLayerTreeHost(bool record_main_frame_metrics) override; void ApplyViewportChanges(const cc::ApplyViewportChangesArgs& args) override { } void RecordWheelAndTouchScrollingCount(bool has_scrolled_by_wheel,
diff --git a/ui/file_manager/file_manager/background/js/BUILD.gn b/ui/file_manager/file_manager/background/js/BUILD.gn index ad9a456..949e0e0 100644 --- a/ui/file_manager/file_manager/background/js/BUILD.gn +++ b/ui/file_manager/file_manager/background/js/BUILD.gn
@@ -209,8 +209,6 @@ deps = [ ":metadata_proxy", "../../common/js:importer_common", - "../../common/js:metrics", - "../../common/js:metrics_events", "../../common/js:util", ] }
diff --git a/ui/file_manager/file_manager/background/js/import_history_unittest.html b/ui/file_manager/file_manager/background/js/import_history_unittest.html index 1f32305..add6617 100644 --- a/ui/file_manager/file_manager/background/js/import_history_unittest.html +++ b/ui/file_manager/file_manager/background/js/import_history_unittest.html
@@ -7,15 +7,10 @@ <html> <body> -<script src="../../../../../third_party/analytics/google-analytics-bundle.js"></script> - <script src="../../../base/js/volume_manager_types.js"></script> <script src="../../common/js/importer_common.js"></script> <script src="../../common/js/lru_cache.js"></script> <script src="../../common/js/test_importer_common.js"></script> -<script src="../../common/js/test_tracker.js"></script> -<script src="../../common/js/metrics_base.js"></script> -<script src="../../common/js/metrics_events.js"></script> <script src="../../common/js/mock_entry.js"></script> <script src="../../../base/js/test_error_reporting.js"></script> <script src="../../common/js/unittest_util.js"></script>
diff --git a/ui/file_manager/file_manager/common/js/metrics_events.js b/ui/file_manager/file_manager/common/js/metrics_events.js index 33ec250..3b2de1ff 100644 --- a/ui/file_manager/file_manager/common/js/metrics_events.js +++ b/ui/file_manager/file_manager/common/js/metrics_events.js
@@ -132,12 +132,6 @@ }; /** @enum {!analytics.EventBuilder} */ -metrics.ImportEvents = { - HISTORY_LOADED: metrics.event.Builders_.IMPORT - .action('History Loaded'), -}; - -/** @enum {!analytics.EventBuilder} */ metrics.Internals = { UNRECOGNIZED_FILE_SYSTEM_PROVIDER: metrics.event.Builders_.INTERNALS .action('Unrecognized File System Provider') @@ -150,6 +144,5 @@ metrics.timing.Variables = { COMPUTE_HASH: 'Compute Content Hash', SEARCH_BY_HASH: 'Search By Hash', - HISTORY_LOAD: 'History Load', EXTRACT_THUMBNAIL_FROM_RAW: 'Extract Thumbnail From RAW' };
diff --git a/ui/gfx/paint_throbber.cc b/ui/gfx/paint_throbber.cc index ae99e39..a56252c2 100644 --- a/ui/gfx/paint_throbber.cc +++ b/ui/gfx/paint_throbber.cc
@@ -193,10 +193,16 @@ float time = 2.0f * (elapsed_time.InMilliseconds() % kAnimationCycleMs) / kAnimationCycleMs; // 1 -> 2 values mirror back to 1 -> 0 values to represent right-to-left. - if (time > 1.0f) + const bool going_back = time > 1.0f; + if (going_back) time = 2.0f - time; + // This animation should be fast in the middle and slow at the edges. + time = Tween::CalculateValue(Tween::EASE_IN_OUT, time); const float min_width = throbber_container_bounds.height(); - const float throbber_width = min_width * 2.5; + // The throbber animation stretches longer when moving in (left to right) than + // when going back. + const float throbber_width = + (going_back ? 0.75f : 1.0f) * throbber_container_bounds.width(); // These bounds keep at least |min_width| of the throbber visible (inside the // throbber bounds). @@ -219,7 +225,7 @@ flags.setAntiAlias(true); // Draw with circular end caps. - canvas->DrawRoundRect(bounds, bounds.height() / 2, flags); + canvas->DrawRect(bounds, flags); } } // namespace gfx
diff --git a/ui/resources/default_100_percent/common/menu_hierarchy_arrow.png b/ui/resources/default_100_percent/common/menu_hierarchy_arrow.png deleted file mode 100644 index e77afae..0000000 --- a/ui/resources/default_100_percent/common/menu_hierarchy_arrow.png +++ /dev/null Binary files differ
diff --git a/ui/resources/default_100_percent/common/menu_overflow_down.png b/ui/resources/default_100_percent/common/menu_overflow_down.png deleted file mode 100644 index f5a7faea..0000000 --- a/ui/resources/default_100_percent/common/menu_overflow_down.png +++ /dev/null Binary files differ
diff --git a/ui/resources/default_100_percent/common/menu_overflow_up.png b/ui/resources/default_100_percent/common/menu_overflow_up.png deleted file mode 100644 index d356baf2..0000000 --- a/ui/resources/default_100_percent/common/menu_overflow_up.png +++ /dev/null Binary files differ
diff --git a/ui/resources/default_100_percent/legacy/throbber.png b/ui/resources/default_100_percent/legacy/throbber.png deleted file mode 100644 index 4d2525c1..0000000 --- a/ui/resources/default_100_percent/legacy/throbber.png +++ /dev/null Binary files differ
diff --git a/ui/resources/default_200_percent/common/menu_hierarchy_arrow.png b/ui/resources/default_200_percent/common/menu_hierarchy_arrow.png deleted file mode 100644 index 58a0007..0000000 --- a/ui/resources/default_200_percent/common/menu_hierarchy_arrow.png +++ /dev/null Binary files differ
diff --git a/ui/resources/default_200_percent/common/menu_overflow_down.png b/ui/resources/default_200_percent/common/menu_overflow_down.png deleted file mode 100644 index 659dab6..0000000 --- a/ui/resources/default_200_percent/common/menu_overflow_down.png +++ /dev/null Binary files differ
diff --git a/ui/resources/default_200_percent/common/menu_overflow_up.png b/ui/resources/default_200_percent/common/menu_overflow_up.png deleted file mode 100644 index 6202dbf..0000000 --- a/ui/resources/default_200_percent/common/menu_overflow_up.png +++ /dev/null Binary files differ
diff --git a/ui/resources/default_200_percent/legacy/throbber.png b/ui/resources/default_200_percent/legacy/throbber.png deleted file mode 100644 index fdd5f7ac..0000000 --- a/ui/resources/default_200_percent/legacy/throbber.png +++ /dev/null Binary files differ
diff --git a/ui/resources/ui_resources.grd b/ui/resources/ui_resources.grd index 3a46c5f..3eec9da 100644 --- a/ui/resources/ui_resources.grd +++ b/ui/resources/ui_resources.grd
@@ -111,13 +111,6 @@ <structure type="chrome_scaled_image" name="IDR_EMOJI_FAVICON" file="common/emoji_menu_item.png" /> <structure type="chrome_scaled_image" name="IDR_FOLDER_CLOSED" file="common/folder_closed.png" /> <structure type="chrome_scaled_image" name="IDR_FOLDER_CLOSED_RTL" file="common/folder_closed_rtl.png" /> - <if expr="is_macosx"> - <structure type="chrome_scaled_image" name="IDR_MENU_OVERFLOW_UP" file="common/menu_overflow_up.png" /> - <structure type="chrome_scaled_image" name="IDR_MENU_OVERFLOW_DOWN" file="common/menu_overflow_down.png" /> - </if> - <if expr="is_macosx or is_ios"> - <structure type="chrome_scaled_image" name="IDR_MENU_HIERARCHY_ARROW" file="mac/menu_hierarchy_arrow.png" /> - </if> <if expr="toolkit_views and not is_macosx"> <structure type="chrome_scaled_image" name="IDR_NOTIFICATION_SETTINGS" file="common/notification_settings.png"/> </if> @@ -146,9 +139,6 @@ <structure type="chrome_scaled_image" name="IDR_TEXT_SELECTION_HANDLE_LEFT" file="common/text_selection_handle_left.png" /> <structure type="chrome_scaled_image" name="IDR_TEXT_SELECTION_HANDLE_RIGHT" file="common/text_selection_handle_right.png" /> </if> - <if expr="is_macosx"> - <structure type="chrome_scaled_image" name="IDR_THROBBER" file="legacy/throbber.png" /> - </if> <if expr="toolkit_views"> <structure type="chrome_scaled_image" name="IDR_TOUCH_DRAG_TIP_COPY" file="common/drag_tip_copy.png" /> <structure type="chrome_scaled_image" name="IDR_TOUCH_DRAG_TIP_MOVE" file="common/drag_tip_move.png" />
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc index 9fd46f65..9dd1a0dc 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
@@ -1819,8 +1819,10 @@ // WindowTreeHost that hosts ash. if (content_window() && content_window()->delegate()) { int flags = event->flags(); + gfx::Point location_in_dip = event->location(); + GetRootTransform().TransformPointReverse(&location_in_dip); int hit_test_code = - content_window()->delegate()->GetNonClientComponent(event->location()); + content_window()->delegate()->GetNonClientComponent(location_in_dip); if (hit_test_code != HTCLIENT && hit_test_code != HTNOWHERE) flags |= ui::EF_IS_NON_CLIENT; event->set_flags(flags);
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc index 130919de..e25fab2 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11_unittest.cc
@@ -79,7 +79,12 @@ const gfx::Rect& client_bounds) const override { return client_bounds; } - int NonClientHitTest(const gfx::Point& point) override { return HTNOWHERE; } + int NonClientHitTest(const gfx::Point& point) override { + // Fake bottom for non client event test. + if (point == gfx::Point(500, 500)) + return HTBOTTOM; + return HTNOWHERE; + } void GetWindowMask(const gfx::Size& size, gfx::Path* window_mask) override { int right = size.width(); int bottom = size.height(); @@ -168,11 +173,15 @@ class DesktopWindowTreeHostX11Test : public ViewsTestBase { public: - DesktopWindowTreeHostX11Test() { - } + DesktopWindowTreeHostX11Test() + : event_source_(ui::PlatformEventSource::GetInstance()) {} ~DesktopWindowTreeHostX11Test() override {} void SetUp() override { + std::vector<int> pointer_devices; + pointer_devices.push_back(kPointerDeviceId); + ui::TouchFactory::GetInstance()->SetPointerDeviceForTest(pointer_devices); + ViewsTestBase::SetUp(); // Make X11 synchronous for our display connection. This does not force the @@ -185,7 +194,17 @@ ViewsTestBase::TearDown(); } + void DispatchSingleEventToWidget(XEvent* event, Widget* widget) { + DCHECK_EQ(GenericEvent, event->type); + XIDeviceEvent* device_event = + static_cast<XIDeviceEvent*>(event->xcookie.data); + device_event->event = + widget->GetNativeWindow()->GetHost()->GetAcceleratedWidget(); + event_source_.Dispatch(event); + } + private: + ui::test::PlatformEventSourceTestAPI event_source_; DISALLOW_COPY_AND_ASSIGN(DesktopWindowTreeHostX11Test); }; @@ -501,19 +520,9 @@ class DesktopWindowTreeHostX11HighDPITest : public DesktopWindowTreeHostX11Test { public: - DesktopWindowTreeHostX11HighDPITest() - : event_source_(ui::PlatformEventSource::GetInstance()) {} + DesktopWindowTreeHostX11HighDPITest() {} ~DesktopWindowTreeHostX11HighDPITest() override {} - void DispatchSingleEventToWidget(XEvent* event, Widget* widget) { - DCHECK_EQ(GenericEvent, event->type); - XIDeviceEvent* device_event = - static_cast<XIDeviceEvent*>(event->xcookie.data); - device_event->event = - widget->GetNativeWindow()->GetHost()->GetAcceleratedWidget(); - event_source_.Dispatch(event); - } - void PretendCapture(views::Widget* capture_widget) { DesktopWindowTreeHostX11* capture_host = nullptr; if (capture_widget) { @@ -529,14 +538,10 @@ void SetUp() override { base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); command_line->AppendSwitchASCII(switches::kForceDeviceScaleFactor, "2"); - std::vector<int> pointer_devices; - pointer_devices.push_back(kPointerDeviceId); - ui::TouchFactory::GetInstance()->SetPointerDeviceForTest(pointer_devices); DesktopWindowTreeHostX11Test::SetUp(); } - ui::test::PlatformEventSourceTestAPI event_source_; DISALLOW_COPY_AND_ASSIGN(DesktopWindowTreeHostX11HighDPITest); }; @@ -597,4 +602,52 @@ second.GetNativeWindow()->RemovePreTargetHandler(&second_recorder); } +TEST_F(DesktopWindowTreeHostX11Test, MouseNCEvents) { + std::unique_ptr<Widget> widget = CreateWidget(new ShapedWidgetDelegate()); + widget->Show(); + + ui::X11EventSource::GetInstance()->DispatchXEvents(); + + widget->SetBounds(gfx::Rect(100, 100, 501, 501)); + ui::X11EventSource::GetInstance()->DispatchXEvents(); + + MouseEventRecorder recorder; + widget->GetNativeWindow()->AddPreTargetHandler(&recorder); + + ui::ScopedXI2Event event; + event.InitGenericButtonEvent(kPointerDeviceId, ui::ET_MOUSE_PRESSED, + gfx::Point(500, 500), ui::EF_LEFT_MOUSE_BUTTON); + + DispatchSingleEventToWidget(event, widget.get()); + ASSERT_EQ(1u, recorder.mouse_events().size()); + EXPECT_EQ(ui::ET_MOUSE_PRESSED, recorder.mouse_events()[0].type()); + EXPECT_TRUE(recorder.mouse_events()[0].flags() & ui::EF_IS_NON_CLIENT); + + widget->GetNativeWindow()->RemovePreTargetHandler(&recorder); +} + +TEST_F(DesktopWindowTreeHostX11HighDPITest, MouseNCEvents) { + std::unique_ptr<Widget> widget = CreateWidget(new ShapedWidgetDelegate()); + widget->Show(); + + ui::X11EventSource::GetInstance()->DispatchXEvents(); + + widget->SetBounds(gfx::Rect(100, 100, 1000, 1000)); + ui::X11EventSource::GetInstance()->DispatchXEvents(); + + MouseEventRecorder recorder; + widget->GetNativeWindow()->AddPreTargetHandler(&recorder); + + ui::ScopedXI2Event event; + event.InitGenericButtonEvent(kPointerDeviceId, ui::ET_MOUSE_PRESSED, + gfx::Point(1001, 1001), + ui::EF_LEFT_MOUSE_BUTTON); + DispatchSingleEventToWidget(event, widget.get()); + ASSERT_EQ(1u, recorder.mouse_events().size()); + EXPECT_EQ(ui::ET_MOUSE_PRESSED, recorder.mouse_events()[0].type()); + EXPECT_TRUE(recorder.mouse_events()[0].flags() & ui::EF_IS_NON_CLIENT); + + widget->GetNativeWindow()->RemovePreTargetHandler(&recorder); +} + } // namespace views
diff --git a/url/gurl_unittest.cc b/url/gurl_unittest.cc index c77cf71..6f876aee 100644 --- a/url/gurl_unittest.cc +++ b/url/gurl_unittest.cc
@@ -771,7 +771,10 @@ EXPECT_FALSE(GURL("http://bar/").SchemeIsBlob()); } -TEST(GURLTest, ContentAndPathForNonStandardURLs) { +// Tests that the 'content' of the URL is properly extracted. This can be +// complex in cases such as multiple schemes (view-source:http:) or for +// javascript URLs. See GURL::GetContent for more details. +TEST(GURLTest, ContentForNonStandardURLs) { struct TestCase { const char* url; const char* expected; @@ -779,12 +782,18 @@ {"null", ""}, {"not-a-standard-scheme:this is arbitrary content", "this is arbitrary content"}, + + // When there are multiple schemes, only the first is excluded from the + // content. Note also that for e.g. 'http://', the '//' is part of the + // content not the scheme. {"view-source:http://example.com/path", "http://example.com/path"}, {"blob:http://example.com/GUID", "http://example.com/GUID"}, {"blob://http://example.com/GUID", "//http://example.com/GUID"}, {"blob:http://user:password@example.com/GUID", "http://user:password@example.com/GUID"}, + // The octothorpe character ('#') marks the end of the URL content, and + // the start of the fragment. It should not be included in the content. {"http://www.example.com/GUID#ref", "www.example.com/GUID"}, {"http://me:secret@example.com/GUID/#ref", "me:secret@example.com/GUID/"}, {"data:text/html,Question?<div style=\"color: #bad\">idea</div>", @@ -804,6 +813,9 @@ } } +// Tests that the URL path is properly extracted for unusual URLs. This can be +// complex in cases such as multiple schemes (view-source:http:) or when +// octothorpes ('#') are involved. TEST(GURLTest, PathForNonStandardURLs) { struct TestCase { const char* url;