diff --git a/DEPS b/DEPS index eb7e510..0388ba0 100644 --- a/DEPS +++ b/DEPS
@@ -162,11 +162,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': 'c096654fa7c64fc2dccf38ca6ddd37f0e906000e', + 'skia_revision': 'f07a36341330877adc12ab61582e13801dd7fe42', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '778af2fde9d4c9e22a56f888396844bdfe1bca0f', + 'v8_revision': '1a76e68814fab189993fa11e0cd534eb49df7977', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -174,7 +174,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': '6d625bfe6e8a74869e2a6389512bb87ec7f8f4c3', + 'angle_revision': '3c049a34714db5d033ba2edc82c8dfe7d911dc48', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -297,7 +297,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': '41f8aa550b4304d6132f8f7f7a6c0ae5eeee319d', + 'dawn_revision': 'c3b613296d26ee9ffa1d0ecdb6e0bc8ab3ff9d7a', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -853,7 +853,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '53ffaae2b80a9db82ac5093b77ec44625eeccf70', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '8de7737d65f367549efce0ad1677b6a3f2e79e10', 'condition': 'checkout_linux', }, @@ -1257,7 +1257,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '55783c1d04037e95075acbed55abb2968a5c5819', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '5a9d89d158eb86d62e11caf7afac82060da98d2f', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1425,7 +1425,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '7c4e67ff117d6c640e6dd17989afe2fb7da7eecb', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'bc646eee208f90dd4297f88793616381f422b957', + Var('webrtc_git') + '/src.git' + '@' + '67309ef93c4f8ff0c62d2d8806f79e69cd553b5c', 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d', @@ -1487,7 +1487,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@ca2ef4313b406944f445630ffc4f712c0fb84b64', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@a4f7741ee65c7dfc7b353ccf806d32b10feb32d4', 'condition': 'checkout_src_internal', },
diff --git a/android_webview/browser/cookie_manager.h b/android_webview/browser/cookie_manager.h index 82d7ccc66..fa763d7 100644 --- a/android_webview/browser/cookie_manager.h +++ b/android_webview/browser/cookie_manager.h
@@ -8,6 +8,7 @@ #include <memory> #include <vector> +#include "base/android/scoped_java_ref.h" #include "base/containers/circular_deque.h" #include "base/lazy_instance.h" #include "base/threading/thread.h"
diff --git a/base/BUILD.gn b/base/BUILD.gn index 3544b79b..27dbec4 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -1249,6 +1249,7 @@ "//base/allocator:buildflags", "//base/third_party/double_conversion", "//base/third_party/dynamic_annotations", + "//build:branding_buildflags", "//third_party/modp_b64", ]
diff --git a/base/files/file_util_posix.cc b/base/files/file_util_posix.cc index 5743863..72beeab 100644 --- a/base/files/file_util_posix.cc +++ b/base/files/file_util_posix.cc
@@ -43,6 +43,7 @@ #include "base/system/sys_info.h" #include "base/threading/scoped_blocking_call.h" #include "base/time/time.h" +#include "build/branding_buildflags.h" #include "build/build_config.h" #if defined(OS_MACOSX) @@ -134,7 +135,7 @@ return StringPrintf(".%s.XXXXXX", base::mac::BaseBundleID()); #endif -#if defined(GOOGLE_CHROME_BUILD) +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) return std::string(".com.google.Chrome.XXXXXX"); #else return std::string(".org.chromium.Chromium.XXXXXX");
diff --git a/base/mac/foundation_util.mm b/base/mac/foundation_util.mm index 8b20ebc6..2a83d4d8 100644 --- a/base/mac/foundation_util.mm +++ b/base/mac/foundation_util.mm
@@ -15,6 +15,7 @@ #include "base/numerics/safe_conversions.h" #include "base/stl_util.h" #include "base/strings/sys_string_conversions.h" +#include "build/branding_buildflags.h" #include "build/build_config.h" #if !defined(OS_IOS) @@ -239,7 +240,7 @@ return base_bundle_id; } -#if defined(GOOGLE_CHROME_BUILD) +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) return "com.google.Chrome"; #else return "org.chromium.Chromium";
diff --git a/base/message_loop/message_loop_unittest.cc b/base/message_loop/message_loop_unittest.cc index 3cae10a..02cb94b5 100644 --- a/base/message_loop/message_loop_unittest.cc +++ b/base/message_loop/message_loop_unittest.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 "base/message_loop/message_loop.h" + #include <stddef.h> #include <stdint.h>
diff --git a/base/message_loop/message_pump_io_ios_unittest.cc b/base/message_loop/message_pump_io_ios_unittest.cc index 4d15d44..aec10012 100644 --- a/base/message_loop/message_pump_io_ios_unittest.cc +++ b/base/message_loop/message_pump_io_ios_unittest.cc
@@ -7,6 +7,7 @@ #include <unistd.h> #include "base/macros.h" +#include "base/message_loop/message_pump_for_io.h" #include "base/posix/eintr_wrapper.h" #include "base/test/gtest_util.h" #include "base/threading/thread.h"
diff --git a/base/threading/thread_perftest.cc b/base/threading/thread_perftest.cc index e19b18b..5e1e65b 100644 --- a/base/threading/thread_perftest.cc +++ b/base/threading/thread_perftest.cc
@@ -12,6 +12,7 @@ #include "base/command_line.h" #include "base/location.h" #include "base/memory/ptr_util.h" +#include "base/message_loop/message_loop_current.h" #include "base/single_thread_task_runner.h" #include "base/strings/stringprintf.h" #include "base/synchronization/condition_variable.h"
diff --git a/base/trace_event/memory_dump_manager.cc b/base/trace_event/memory_dump_manager.cc index 8b1bd7a..d79d405 100644 --- a/base/trace_event/memory_dump_manager.cc +++ b/base/trace_event/memory_dump_manager.cc
@@ -529,7 +529,8 @@ dump_thread_task_runner(std::move(dump_thread_task_runner)) { pending_dump_providers.reserve(dump_providers.size()); pending_dump_providers.assign(dump_providers.rbegin(), dump_providers.rend()); - MemoryDumpArgs args = {req_args.level_of_detail, req_args.dump_guid}; + MemoryDumpArgs args = {req_args.level_of_detail, req_args.determinism, + req_args.dump_guid}; process_memory_dump = std::make_unique<ProcessMemoryDump>(args); }
diff --git a/base/trace_event/memory_dump_manager_unittest.cc b/base/trace_event/memory_dump_manager_unittest.cc index b33b677..c7b413d 100644 --- a/base/trace_event/memory_dump_manager_unittest.cc +++ b/base/trace_event/memory_dump_manager_unittest.cc
@@ -54,6 +54,14 @@ return arg.level_of_detail == MemoryDumpLevelOfDetail::LIGHT; } +MATCHER(IsDeterministicDump, "") { + return arg.determinism == MemoryDumpDeterminism::FORCE_GC; +} + +MATCHER(IsNotDeterministicDump, "") { + return arg.determinism == MemoryDumpDeterminism::NONE; +} + namespace { const char* kMDPName = "TestDumpProvider"; @@ -193,12 +201,14 @@ // memory dump is complete. Returns: // - return value: the |success| from the CreateProcessDump() callback. bool RequestProcessDumpAndWait(MemoryDumpType dump_type, - MemoryDumpLevelOfDetail level_of_detail) { + MemoryDumpLevelOfDetail level_of_detail, + MemoryDumpDeterminism determinism) { RunLoop run_loop; bool success = false; static uint64_t test_guid = 1; test_guid++; - MemoryDumpRequestArgs request_args{test_guid, dump_type, level_of_detail}; + MemoryDumpRequestArgs request_args{test_guid, dump_type, level_of_detail, + determinism}; // The signature of the callback delivered by MemoryDumpManager is: // void ProcessMemoryDumpCallback( @@ -276,7 +286,8 @@ EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(3); for (int i = 0; i < 3; ++i) { EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, - MemoryDumpLevelOfDetail::DETAILED)); + MemoryDumpLevelOfDetail::DETAILED, + MemoryDumpDeterminism::NONE)); } DisableTracing(); @@ -288,7 +299,8 @@ EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0); for (int i = 0; i < 3; ++i) { EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, - MemoryDumpLevelOfDetail::DETAILED)); + MemoryDumpLevelOfDetail::DETAILED, + MemoryDumpDeterminism::NONE)); } DisableTracing(); } @@ -302,7 +314,8 @@ EnableForTracing(); EXPECT_CALL(mdp, OnMemoryDump(IsDetailedDump(), _)); EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, - MemoryDumpLevelOfDetail::DETAILED)); + MemoryDumpLevelOfDetail::DETAILED, + MemoryDumpDeterminism::NONE)); DisableTracing(); mdm_->UnregisterDumpProvider(&mdp); @@ -312,7 +325,34 @@ EnableForTracing(); EXPECT_CALL(mdp, OnMemoryDump(IsLightDump(), _)); EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, - MemoryDumpLevelOfDetail::LIGHT)); + MemoryDumpLevelOfDetail::LIGHT, + MemoryDumpDeterminism::NONE)); + DisableTracing(); + mdm_->UnregisterDumpProvider(&mdp); +} + +// Checks that requesting deterministic dumps actually propagates +// the deterministic option properly to OnMemoryDump() call on dump providers. +TEST_F(MemoryDumpManagerTest, CheckMemoryDumpArgsDeterministic) { + MockMemoryDumpProvider mdp; + + RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get()); + EnableForTracing(); + EXPECT_CALL(mdp, OnMemoryDump(IsDeterministicDump(), _)); + EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, + MemoryDumpLevelOfDetail::DETAILED, + MemoryDumpDeterminism::FORCE_GC)); + DisableTracing(); + mdm_->UnregisterDumpProvider(&mdp); + + // Check that requesting dumps with deterministic option set to false + // actually propagates to OnMemoryDump() call on dump providers. + RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get()); + EnableForTracing(); + EXPECT_CALL(mdp, OnMemoryDump(IsNotDeterministicDump(), _)); + EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, + MemoryDumpLevelOfDetail::LIGHT, + MemoryDumpDeterminism::NONE)); DisableTracing(); mdm_->UnregisterDumpProvider(&mdp); } @@ -328,7 +368,8 @@ EXPECT_CALL(mdp1, OnMemoryDump(_, _)); EXPECT_CALL(mdp2, OnMemoryDump(_, _)).Times(0); EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, - MemoryDumpLevelOfDetail::DETAILED)); + MemoryDumpLevelOfDetail::DETAILED, + MemoryDumpDeterminism::NONE)); DisableTracing(); // Invert: enable mdp2 and disable mdp1. @@ -338,7 +379,8 @@ EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(0); EXPECT_CALL(mdp2, OnMemoryDump(_, _)); EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, - MemoryDumpLevelOfDetail::DETAILED)); + MemoryDumpLevelOfDetail::DETAILED, + MemoryDumpDeterminism::NONE)); DisableTracing(); // Enable both mdp1 and mdp2. @@ -347,7 +389,8 @@ EXPECT_CALL(mdp1, OnMemoryDump(_, _)); EXPECT_CALL(mdp2, OnMemoryDump(_, _)); EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, - MemoryDumpLevelOfDetail::DETAILED)); + MemoryDumpLevelOfDetail::DETAILED, + MemoryDumpDeterminism::NONE)); DisableTracing(); } @@ -368,7 +411,8 @@ EXPECT_CALL(mdp, OnMemoryDump(_, _)); EnableForTracing(); EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, - MemoryDumpLevelOfDetail::DETAILED)); + MemoryDumpLevelOfDetail::DETAILED, + MemoryDumpDeterminism::NONE)); DisableTracing(); } @@ -378,7 +422,8 @@ EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0); EnableForTracing(); EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, - MemoryDumpLevelOfDetail::DETAILED)); + MemoryDumpLevelOfDetail::DETAILED, + MemoryDumpDeterminism::NONE)); DisableTracing(); } @@ -389,7 +434,8 @@ EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0); EnableForTracing(); EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, - MemoryDumpLevelOfDetail::DETAILED)); + MemoryDumpLevelOfDetail::DETAILED, + MemoryDumpDeterminism::NONE)); DisableTracing(); } @@ -401,7 +447,8 @@ EXPECT_CALL(mdp, OnMemoryDump(_, _)); EnableForTracing(); EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, - MemoryDumpLevelOfDetail::DETAILED)); + MemoryDumpLevelOfDetail::DETAILED, + MemoryDumpDeterminism::NONE)); DisableTracing(); } } @@ -439,7 +486,8 @@ while (!threads.empty()) { EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, - MemoryDumpLevelOfDetail::DETAILED)); + MemoryDumpLevelOfDetail::DETAILED, + MemoryDumpDeterminism::NONE)); // Unregister a MDP and destroy one thread at each iteration to check the // live unregistration logic. The unregistration needs to happen on the same @@ -485,13 +533,15 @@ task_runner1->set_enabled(false); EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, - MemoryDumpLevelOfDetail::DETAILED)); + MemoryDumpLevelOfDetail::DETAILED, + MemoryDumpDeterminism::NONE)); EXPECT_EQ(1u, task_runner1->no_of_post_tasks()); EXPECT_EQ(1u, task_runner2->no_of_post_tasks()); task_runner1->set_enabled(true); EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, - MemoryDumpLevelOfDetail::DETAILED)); + MemoryDumpLevelOfDetail::DETAILED, + MemoryDumpDeterminism::NONE)); EXPECT_EQ(2u, task_runner1->no_of_post_tasks()); EXPECT_EQ(2u, task_runner2->no_of_post_tasks()); DisableTracing(); @@ -522,7 +572,8 @@ const int kNumDumps = 2 * GetMaxConsecutiveFailuresCount(); for (int i = 0; i < kNumDumps; i++) { EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, - MemoryDumpLevelOfDetail::DETAILED)); + MemoryDumpLevelOfDetail::DETAILED, + MemoryDumpDeterminism::NONE)); } DisableTracing(); @@ -553,7 +604,8 @@ for (int i = 0; i < 4; i++) { EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, - MemoryDumpLevelOfDetail::DETAILED)); + MemoryDumpLevelOfDetail::DETAILED, + MemoryDumpDeterminism::NONE)); } DisableTracing(); @@ -584,7 +636,8 @@ for (int i = 0; i < 4; i++) { EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, - MemoryDumpLevelOfDetail::DETAILED)); + MemoryDumpLevelOfDetail::DETAILED, + MemoryDumpDeterminism::NONE)); } DisableTracing(); @@ -632,7 +685,8 @@ EnableForTracing(); EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, - MemoryDumpLevelOfDetail::DETAILED)); + MemoryDumpLevelOfDetail::DETAILED, + MemoryDumpDeterminism::NONE)); ASSERT_EQ(1, on_memory_dump_call_count); DisableTracing(); @@ -679,7 +733,8 @@ EnableForTracing(); EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, - MemoryDumpLevelOfDetail::DETAILED)); + MemoryDumpLevelOfDetail::DETAILED, + MemoryDumpDeterminism::NONE)); ASSERT_EQ(1, on_memory_dump_call_count); DisableTracing(); @@ -692,7 +747,8 @@ RegisterDumpProvider(&mdp, nullptr); EXPECT_CALL(mdp, OnMemoryDump(_, _)); EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, - MemoryDumpLevelOfDetail::DETAILED)); + MemoryDumpLevelOfDetail::DETAILED, + MemoryDumpDeterminism::NONE)); } TEST_F(MemoryDumpManagerTest, BackgroundWhitelisting) { @@ -707,7 +763,8 @@ EXPECT_CALL(backgroundMdp, OnMemoryDump(_, _)).Times(1); EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::SUMMARY_ONLY, - MemoryDumpLevelOfDetail::BACKGROUND)); + MemoryDumpLevelOfDetail::BACKGROUND, + MemoryDumpDeterminism::NONE)); DisableTracing(); } @@ -769,7 +826,8 @@ EnableForTracing(); for (int i = 0; i < 2; ++i) { EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, - MemoryDumpLevelOfDetail::DETAILED)); + MemoryDumpLevelOfDetail::DETAILED, + MemoryDumpDeterminism::NONE)); } DisableTracing(); } @@ -822,11 +880,14 @@ stopped_thread->Stop(); EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, - MemoryDumpLevelOfDetail::DETAILED)); + MemoryDumpLevelOfDetail::DETAILED, + MemoryDumpDeterminism::NONE)); EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, - MemoryDumpLevelOfDetail::BACKGROUND)); + MemoryDumpLevelOfDetail::BACKGROUND, + MemoryDumpDeterminism::NONE)); EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::SUMMARY_ONLY, - MemoryDumpLevelOfDetail::BACKGROUND)); + MemoryDumpLevelOfDetail::BACKGROUND, + MemoryDumpDeterminism::NONE)); } } // namespace trace_event
diff --git a/base/trace_event/memory_dump_request_args.h b/base/trace_event/memory_dump_request_args.h index c50a1cb..d62a0dc 100644 --- a/base/trace_event/memory_dump_request_args.h +++ b/base/trace_event/memory_dump_request_args.h
@@ -58,6 +58,12 @@ LAST = DETAILED }; +// Tells the MemoryDumpProvider(s) if they should try to make the result +// more deterministic by forcing garbage collection. +// Keep this consistent with memory_instrumentation.mojo and +// memory_instrumentation_struct_traits.{h,cc} +enum class MemoryDumpDeterminism : uint32_t { NONE, FORCE_GC }; + // Keep this consistent with memory_instrumentation.mojo and // memory_instrumentation_struct_traits.{h,cc} struct BASE_EXPORT MemoryDumpRequestArgs { @@ -68,6 +74,7 @@ MemoryDumpType dump_type; MemoryDumpLevelOfDetail level_of_detail; + MemoryDumpDeterminism determinism; }; // Args for ProcessMemoryDump and passed to OnMemoryDump calls for memory dump @@ -75,6 +82,8 @@ struct MemoryDumpArgs { // Specifies how detailed the dumps should be. MemoryDumpLevelOfDetail level_of_detail; + // Specifies whether the dumps should be more deterministic. + MemoryDumpDeterminism determinism; // Globally unique identifier. In multi-process dumps, all processes issue a // local dump with the same guid. This allows the trace importers to
diff --git a/base/win/windows_types.h b/base/win/windows_types.h index a57277a..60c4ffe 100644 --- a/base/win/windows_types.h +++ b/base/win/windows_types.h
@@ -244,6 +244,8 @@ #define DeleteFile DeleteFileW #define DispatchMessage DispatchMessageW #define DrawText DrawTextW +#define FindFirstFile FindFirstFileW +#define FindNextFile FindNextFileW #define GetComputerName GetComputerNameW #define GetCurrentDirectory GetCurrentDirectoryW #define GetCurrentTime() GetTickCount() @@ -253,6 +255,7 @@ #define LoadIcon LoadIconW #define LoadImage LoadImageW #define PostMessage PostMessageW +#define RemoveDirectory RemoveDirectoryW #define ReplaceFile ReplaceFileW #define ReportEvent ReportEventW #define SendMessage SendMessageW
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index 7bd8ab14..25944cf 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -8901476404455095504 \ No newline at end of file +8901447639518533984 \ No newline at end of file
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index de90e86..0d6122f 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -8901478046424570128 \ No newline at end of file +8901448833775125712 \ No newline at end of file
diff --git a/cc/layers/texture_layer_unittest.cc b/cc/layers/texture_layer_unittest.cc index 0f5a97da..f47ff407 100644 --- a/cc/layers/texture_layer_unittest.cc +++ b/cc/layers/texture_layer_unittest.cc
@@ -14,6 +14,7 @@ #include "base/callback.h" #include "base/location.h" #include "base/memory/ptr_util.h" +#include "base/run_loop.h" #include "base/sequenced_task_runner.h" #include "base/single_thread_task_runner.h" #include "base/synchronization/lock.h"
diff --git a/cc/paint/paint_canvas.h b/cc/paint/paint_canvas.h index ff5a69b..32918efd 100644 --- a/cc/paint/paint_canvas.h +++ b/cc/paint/paint_canvas.h
@@ -176,7 +176,6 @@ virtual void drawPicture(sk_sp<const PaintRecord> record) = 0; virtual bool isClipEmpty() const = 0; - virtual bool isClipRect() const = 0; virtual const SkMatrix& getTotalMatrix() const = 0; // Used for printing
diff --git a/cc/paint/record_paint_canvas.cc b/cc/paint/record_paint_canvas.cc index d53569f7..b6c58cb 100644 --- a/cc/paint/record_paint_canvas.cc +++ b/cc/paint/record_paint_canvas.cc
@@ -296,11 +296,6 @@ return GetCanvas()->isClipEmpty(); } -bool RecordPaintCanvas::isClipRect() const { - DCHECK(InitializedWithRecordingBounds()); - return GetCanvas()->isClipRect(); -} - const SkMatrix& RecordPaintCanvas::getTotalMatrix() const { return GetCanvas()->getTotalMatrix(); }
diff --git a/cc/paint/record_paint_canvas.h b/cc/paint/record_paint_canvas.h index 24fb177..27256f5 100644 --- a/cc/paint/record_paint_canvas.h +++ b/cc/paint/record_paint_canvas.h
@@ -102,7 +102,6 @@ void drawPicture(sk_sp<const PaintRecord> record) override; bool isClipEmpty() const override; - bool isClipRect() const override; const SkMatrix& getTotalMatrix() const override; void Annotate(AnnotationType type,
diff --git a/cc/paint/skia_paint_canvas.cc b/cc/paint/skia_paint_canvas.cc index d014d7e..72d34e9 100644 --- a/cc/paint/skia_paint_canvas.cc +++ b/cc/paint/skia_paint_canvas.cc
@@ -328,10 +328,6 @@ return canvas_->isClipEmpty(); } -bool SkiaPaintCanvas::isClipRect() const { - return canvas_->isClipRect(); -} - const SkMatrix& SkiaPaintCanvas::getTotalMatrix() const { return canvas_->getTotalMatrix(); }
diff --git a/cc/paint/skia_paint_canvas.h b/cc/paint/skia_paint_canvas.h index 6c567ce..3dc12517 100644 --- a/cc/paint/skia_paint_canvas.h +++ b/cc/paint/skia_paint_canvas.h
@@ -126,7 +126,6 @@ void drawPicture(sk_sp<const PaintRecord> record) override; bool isClipEmpty() const override; - bool isClipRect() const override; const SkMatrix& getTotalMatrix() const override; void Annotate(AnnotationType type,
diff --git a/chrome/android/chrome_junit_test_java_sources.gni b/chrome/android/chrome_junit_test_java_sources.gni index 8b207ec..59a03e5 100644 --- a/chrome/android/chrome_junit_test_java_sources.gni +++ b/chrome/android/chrome_junit_test_java_sources.gni
@@ -18,6 +18,7 @@ "junit/src/org/chromium/chrome/browser/autofill/AutofillUiUtilsTest.java", "junit/src/org/chromium/chrome/browser/background_sync/BackgroundSyncBackgroundTaskSchedulerTest.java", "junit/src/org/chromium/chrome/browser/background_sync/BackgroundSyncBackgroundTaskTest.java", + "junit/src/org/chromium/chrome/browser/background_sync/BackgroundSyncGooglePlayServicesCheckerTest.java", "junit/src/org/chromium/chrome/browser/background_sync/PeriodicBackgroundSyncChromeWakeUpTaskTest.java", "junit/src/org/chromium/chrome/browser/background_task_scheduler/NativeBackgroundTaskTest.java", "junit/src/org/chromium/chrome/browser/browserservices/ClearDataDialogResultRecorderTest.java",
diff --git a/chrome/android/chrome_test_java_sources.gni b/chrome/android/chrome_test_java_sources.gni index 900993a..7f884d3 100644 --- a/chrome/android/chrome_test_java_sources.gni +++ b/chrome/android/chrome_test_java_sources.gni
@@ -303,6 +303,7 @@ "javatests/src/org/chromium/chrome/browser/password_manager/OnboardingDialogIntegrationTest.java", "javatests/src/org/chromium/chrome/browser/password_manager/PasswordGenerationDialogTest.java", "javatests/src/org/chromium/chrome/browser/password_manager/PasswordManagerDialogTest.java", + "javatests/src/org/chromium/chrome/browser/payments/micro/MicrotransactionRenderTest.java", "javatests/src/org/chromium/chrome/browser/payments/AndroidPaymentAppFinderTest.java", "javatests/src/org/chromium/chrome/browser/payments/CurrencyFormatterTest.java", "javatests/src/org/chromium/chrome/browser/payments/MockPackageManagerDelegate.java",
diff --git a/chrome/android/features/start_surface/internal/java/res/layout/ss_feed_header.xml b/chrome/android/features/start_surface/internal/java/res/layout/ss_feed_header.xml new file mode 100644 index 0000000..83daf1f --- /dev/null +++ b/chrome/android/features/start_surface/internal/java/res/layout/ss_feed_header.xml
@@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2019 The Chromium Authors. All rights reserved. + Use of this source code is governed by a BSD-style license that can be + found in the LICENSE file. --> + +<org.chromium.chrome.browser.ntp.snippets.SectionHeaderView + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:minHeight="@dimen/snippets_article_header_height" + android:orientation="horizontal" + android:paddingTop="8dp" + android:paddingBottom="8dp" + android:gravity="center_vertical"> + + <TextView + android:id="@+id/header_title" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:paddingStart="6dp" + android:textAlignment="viewStart" + android:textAppearance="@style/TextAppearance.BlackTitle2" /> + + <TextView + android:id="@+id/header_status" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textAppearance="@style/TextAppearance.BlueLink2" /> + +</org.chromium.chrome.browser.ntp.snippets.SectionHeaderView>
diff --git a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceCoordinator.java b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceCoordinator.java index 0cb06b0..b5f1bb9 100644 --- a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceCoordinator.java +++ b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceCoordinator.java
@@ -18,6 +18,7 @@ import org.chromium.chrome.browser.feed.FeedProcessScopeFactory; import org.chromium.chrome.browser.feed.FeedSurfaceCoordinator; import org.chromium.chrome.browser.feed.StreamLifecycleManager; +import org.chromium.chrome.browser.ntp.snippets.SectionHeaderView; import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.start_surface.R; @@ -29,6 +30,7 @@ private final ChromeActivity mActivity; private final PropertyModelChangeProcessor mPropertyModelChangeProcessor; private final FeedSurfaceCreator mFeedSurfaceCreator; + private final boolean mHasHeader; // mExploreSurfaceNavigationDelegate is lightweight, we keep it across FeedSurfaceCoordinators // after creating it during the first show. @@ -46,10 +48,11 @@ ExploreSurfaceCoordinator(ChromeActivity activity, ViewGroup parentView, @Nullable ViewGroup headerContainerView, PropertyModel containerPropertyModel) { mActivity = activity; + mHasHeader = (headerContainerView != null); mPropertyModelChangeProcessor = PropertyModelChangeProcessor.create(containerPropertyModel, new ExploreSurfaceViewBinder.ViewHolder(parentView, - headerContainerView == null + !mHasHeader ? null : (NestedScrollView) LayoutInflater.from(activity).inflate( R.layout.ss_explore_scroll_container, parentView, false), @@ -58,7 +61,7 @@ mFeedSurfaceCreator = new FeedSurfaceCreator() { @Override public FeedSurfaceCoordinator createFeedSurfaceCoordinator() { - return internalCreateFeedSurfaceCoordinator(); + return internalCreateFeedSurfaceCoordinator(mHasHeader); } }; } @@ -74,7 +77,7 @@ // Implements FeedSurfaceCoordinator.FeedSurfaceDelegate. @Override public StreamLifecycleManager createStreamLifecycleManager(Stream stream, Activity activity) { - return new ExploreSurfaceStreamLifecycleManager(stream, activity); + return new ExploreSurfaceStreamLifecycleManager(stream, activity, mHasHeader); } @Override @@ -82,9 +85,10 @@ return false; } - private FeedSurfaceCoordinator internalCreateFeedSurfaceCoordinator() { - if (mExploreSurfaceNavigationDelegate == null) + private FeedSurfaceCoordinator internalCreateFeedSurfaceCoordinator(boolean hasHeader) { + if (mExploreSurfaceNavigationDelegate == null) { mExploreSurfaceNavigationDelegate = new ExploreSurfaceNavigationDelegate(mActivity); + } ExploreSurfaceActionHandler exploreSurfaceActionHandler = new ExploreSurfaceActionHandler(mExploreSurfaceNavigationDelegate, @@ -92,8 +96,15 @@ FeedProcessScopeFactory.getFeedOfflineIndicator(), OfflinePageBridge.getForProfile(Profile.getLastUsedProfile()), FeedProcessScopeFactory.getFeedLoggingBridge()); - return new FeedSurfaceCoordinator( - mActivity, null, null, null, exploreSurfaceActionHandler, false, this); + + SectionHeaderView sectionHeaderView = null; + if (hasHeader) { + LayoutInflater inflater = LayoutInflater.from(mActivity); + sectionHeaderView = + (SectionHeaderView) inflater.inflate(R.layout.ss_feed_header, null, false); + } + return new FeedSurfaceCoordinator(mActivity, null, null, null, sectionHeaderView, + exploreSurfaceActionHandler, false, this); // TODO(crbug.com/982018): Customize surface background for incognito and dark mode. // TODO(crbug.com/982018): Hide signin promo UI in incognito mode. }
diff --git a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceStreamLifecycleManager.java b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceStreamLifecycleManager.java index 2e98e757..b227dd0 100644 --- a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceStreamLifecycleManager.java +++ b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceStreamLifecycleManager.java
@@ -9,19 +9,40 @@ import com.google.android.libraries.feed.api.client.stream.Stream; import org.chromium.chrome.browser.feed.StreamLifecycleManager; +import org.chromium.chrome.browser.preferences.Pref; +import org.chromium.chrome.browser.preferences.PrefServiceBridge; /** Explore surface feed stream lifecycle manager. */ class ExploreSurfaceStreamLifecycleManager extends StreamLifecycleManager { + private final boolean mHasHeader; /** * The constructor. * @param stream The {@link Stream} this manager manages. * @param activity The activity the {@link Stream} associates with. */ - ExploreSurfaceStreamLifecycleManager(Stream stream, Activity activity) { + ExploreSurfaceStreamLifecycleManager(Stream stream, Activity activity, boolean hasHeader) { super(stream, activity); + mHasHeader = hasHeader; start(); } + @Override + protected boolean canShow() { + return super.canShow() && shouldShowFeed(); + } + + @Override + protected boolean canActivate() { + return super.canShow() && shouldShowFeed(); + } + + private boolean shouldShowFeed() { + // If there is a header to opt out from article suggestions, we don't call + // Stream#onShow to prevent feed services from being warmed up if the user + // has opted out during the previous session. + return (!mHasHeader + || PrefServiceBridge.getInstance().getBoolean(Pref.NTP_ARTICLES_LIST_VISIBLE)); + } // TODO(crbug.com/982018): Save and restore instance state when opening the feeds in normal // Tabs. -} \ No newline at end of file +}
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutPerfTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutPerfTest.java index c2c0ec8..70ab0918 100644 --- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutPerfTest.java +++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutPerfTest.java
@@ -106,12 +106,6 @@ mTabNumCap = 0; } assertTrue(FeatureUtilities.isTabToGtsAnimationEnabled()); - - CriteriaHelper.pollUiThread(Criteria.equals(true, - mActivityTestRule.getActivity() - .getTabModelSelector() - .getTabModelFilterProvider() - .getCurrentTabModelFilter()::isTabModelRestored)); } @Test
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java index 724e057..4501645 100644 --- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java +++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceLayoutTest.java
@@ -4,10 +4,6 @@ package org.chromium.chrome.features.start_surface; -import static android.support.test.espresso.Espresso.onView; -import static android.support.test.espresso.action.ViewActions.click; -import static android.support.test.espresso.matcher.ViewMatchers.withId; - import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; @@ -21,16 +17,15 @@ import android.graphics.Bitmap; import android.os.Build; import android.provider.Settings; -import android.support.annotation.Nullable; import android.support.test.InstrumentationRegistry; -import android.support.test.espresso.NoMatchingViewException; -import android.support.test.espresso.ViewAssertion; +import android.support.test.espresso.Espresso; +import android.support.test.espresso.action.ViewActions; import android.support.test.espresso.contrib.RecyclerViewActions; +import android.support.test.espresso.matcher.ViewMatchers; import android.support.test.filters.MediumTest; -import android.support.test.filters.SmallTest; -import android.support.v7.widget.RecyclerView; import android.text.TextUtils; -import android.view.View; + +import androidx.annotation.Nullable; import org.junit.Assert; import org.junit.Before; @@ -80,6 +75,7 @@ "force-fieldtrials=Study/Group"}) @Restriction(UiRestriction.RESTRICTION_TYPE_PHONE) public class StartSurfaceLayoutTest { + private static final String TAG = "SSLayoutTest"; private static final String BASE_PARAMS = "force-fieldtrial-params=" + "Study.Group:soft-cleanup-delay/0/cleanup-delay/0/skip-slow-zooming/false" + "/zooming-min-sdk-version/19/zooming-min-memory-mb/512"; @@ -100,7 +96,6 @@ @Before public void setUp() throws InterruptedException { FeatureUtilities.setGridTabSwitcherEnabledForTesting(true); - EmbeddedTestServer testServer = EmbeddedTestServer.createAndStartServer(InstrumentationRegistry.getContext()); mActivityTestRule.startMainActivityFromLauncher(); @@ -118,12 +113,6 @@ mActivityTestRule.getActivity().getTabContentManager().setCaptureMinRequestTimeForTesting( 0); - - CriteriaHelper.pollUiThread(Criteria.equals(true, - mActivityTestRule.getActivity() - .getTabModelSelector() - .getTabModelFilterProvider() - .getCurrentTabModelFilter()::isTabModelRestored)); } @Test @@ -351,9 +340,8 @@ if (mActivityTestRule.getActivity() .getTabContentManager() .getPendingReadbacksForTesting() - > 0) { + > 0) break; - } // Restart Chrome. // Although we're destroying the activity, the Application will still live on since its @@ -427,8 +415,9 @@ waitForCaptureRateControl(); } int count = getCaptureCount(); - onView(withId(org.chromium.chrome.tab_ui.R.id.tab_list_view)) - .perform(RecyclerViewActions.actionOnItemAtPosition(targetIndex, click())); + Espresso.onView(ViewMatchers.withId(org.chromium.chrome.tab_ui.R.id.tab_list_view)) + .perform(RecyclerViewActions.actionOnItemAtPosition( + targetIndex, ViewActions.click())); CriteriaHelper.pollUiThread(() -> { boolean doneHiding = !mActivityTestRule.getActivity().getLayoutManager().overviewVisible(); @@ -543,57 +532,14 @@ Assert.assertEquals(0, mAllBitmaps.size() - count); } - @Test - @SmallTest - @CommandLineFlags.Add({BASE_PARAMS}) - public void testIncognitoEnterGts() throws Exception { - mActivityTestRule.newIncognitoTabFromMenu(); - onView(withId(org.chromium.chrome.R.id.tab_switcher_button)).perform(click()); - - onView(withId(org.chromium.chrome.tab_ui.R.id.tab_list_view)) - .check(TabCountAssertion.havingTabCount(1)); - - onView(withId(org.chromium.chrome.tab_ui.R.id.tab_list_view)) - .perform(RecyclerViewActions.actionOnItemAtPosition(0, click())); - - CriteriaHelper.pollInstrumentationThread( - () -> !mActivityTestRule.getActivity().getLayoutManager().overviewVisible()); - - onView(withId(org.chromium.chrome.R.id.tab_switcher_button)).perform(click()); - - onView(withId(org.chromium.chrome.tab_ui.R.id.tab_list_view)) - .check(TabCountAssertion.havingTabCount(1)); - } - - private static class TabCountAssertion implements ViewAssertion { - private int mExpectedCount; - - public static TabCountAssertion havingTabCount(int tabCount) { - return new TabCountAssertion(tabCount); - } - - public TabCountAssertion(int expectedCount) { - mExpectedCount = expectedCount; - } - - @Override - public void check(View view, NoMatchingViewException noMatchException) { - if (noMatchException != null) throw noMatchException; - - RecyclerView.Adapter adapter = ((RecyclerView) view).getAdapter(); - assertEquals(mExpectedCount, adapter.getItemCount()); - } - } - private void enterGTS() throws InterruptedException { Tab currentTab = mActivityTestRule.getActivity().getTabModelSelector().getCurrentTab(); // Native tabs need to be invalidated first to trigger thumbnail taking, so skip them. boolean checkThumbnail = !currentTab.isNativePage(); - if (checkThumbnail) { + if (checkThumbnail) mActivityTestRule.getActivity().getTabContentManager().removeTabThumbnail( currentTab.getId()); - } int count = getCaptureCount(); waitForCaptureRateControl();
diff --git a/chrome/android/features/tab_ui/java/res/drawable/ic_arrow_right.xml b/chrome/android/features/tab_ui/java/res/drawable/ic_arrow_right.xml new file mode 100644 index 0000000..a0de3e9 --- /dev/null +++ b/chrome/android/features/tab_ui/java/res/drawable/ic_arrow_right.xml
@@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2019 The Chromium Authors. All rights reserved. + Use of this source code is governed by a BSD-style license that can be + found in the LICENSE file. --> + +<vector xmlns:tools="http://schemas.android.com/tools" tools:targetApi="21" + android:autoMirrored="true" android:height="24dp" + android:viewportHeight="24" android:viewportWidth="24" + android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@color/default_icon_color" android:pathData="M8.59,16.59L13.17,12L8.59,7.41L10,6l6,6l-6,6L8.59,16.59z"/> +</vector>
diff --git a/chrome/android/features/tab_ui/java/res/layout/tasks_view_layout.xml b/chrome/android/features/tab_ui/java/res/layout/tasks_view_layout.xml index 6350e1cd..1f87ec2a 100644 --- a/chrome/android/features/tab_ui/java/res/layout/tasks_view_layout.xml +++ b/chrome/android/features/tab_ui/java/res/layout/tasks_view_layout.xml
@@ -26,6 +26,10 @@ android:id="@+id/tab_switcher_title" android:layout_width="match_parent" android:layout_height="wrap_content" + android:paddingStart="12dp" + android:paddingEnd="4dp" + android:paddingTop="8dp" + android:paddingBottom="8dp" android:visibility="gone" android:background="@color/modern_primary_color" android:orientation="horizontal"> @@ -34,23 +38,28 @@ android:layout_height="wrap_content" android:layout_weight="1.0" android:layout_gravity="center_vertical" - android:paddingTop="@dimen/tasks_view_items_vertical_spacing" - android:paddingBottom="@dimen/tasks_view_items_vertical_spacing" - android:paddingStart="24dp" - android:paddingEnd="16dp" - android:textAlignment="viewStart" - android:textAppearance="@style/TextAppearance.BlackCaption" + android:gravity="center_vertical" + android:paddingStart="6dp" + android:singleLine="true" + android:textAppearance="@style/TextAppearance.BlackTitle2" android:text="@string/tab_switcher_carousel_title" /> - <org.chromium.ui.widget.ChromeImageButton + <org.chromium.ui.widget.ChromeImageView android:id="@+id/more_tabs" - style="@style/ToolbarButton" - android:layout_height="wrap_content" - android:src="@drawable/breadcrumb_arrow" - tools:tint="@color/standard_mode_tint" + android:layout_width="48dp" + android:layout_height="48dp" + android:layout_gravity="center_vertical|end" + android:layout_marginTop="-16dp" + android:layout_marginBottom="-16dp" + android:scaleType="center" + android:src="@drawable/ic_arrow_right" + android:tint="@color/default_icon_color" + android:tintMode="src_in" + android:paddingTop="16dp" + android:paddingBottom="16dp" android:contentDescription="@string/accessibility_tab_switcher_carousel_more_tabs"/> </LinearLayout> <FrameLayout android:id="@+id/tab_switcher_container" android:layout_width="match_parent" android:layout_height="match_parent" /> -</org.chromium.chrome.browser.tasks.TasksView> \ No newline at end of file +</org.chromium.chrome.browser.tasks.TasksView>
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_groups/TabGroupModelFilter.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_groups/TabGroupModelFilter.java index 9657a526..89eaf472 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_groups/TabGroupModelFilter.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_groups/TabGroupModelFilter.java
@@ -101,7 +101,7 @@ * group. */ private class TabGroup { - private static final int INVALID_GROUP_ID = -1; + private final static int INVALID_GROUP_ID = -1; private final Set<Integer> mTabIds; private int mLastShownTabId; private int mGroupId; @@ -174,6 +174,7 @@ private int mActualGroupCount; private Tab mAbsentSelectedTab; private boolean mShouldRecordUma = true; + private boolean mTabRestoreCompleted; private boolean mIsResetting; public TabGroupModelFilter(TabModel tabModel) { @@ -187,6 +188,7 @@ RecordHistogram.recordCountHistogram("TabGroups.UserGroupCount", mActualGroupCount); Tab currentTab = TabModelUtils.getCurrentTab(getTabModel()); if (currentTab != null) recordSessionsCount(currentTab); + mTabRestoreCompleted = true; removeObserver(this); } }); @@ -652,7 +654,7 @@ public void didMoveTab(Tab tab, int newIndex, int curIndex) { // Ignore didMoveTab calls in tab restoring stage. For incognito mode, bypass this check // since there is no restoring stage. - if (!isTabModelRestored()) return; + if (!mTabRestoreCompleted && !isIncognito()) return; // Need to cache the flags before resetting the internal data map. boolean isMergeTabToGroup = isMergeTabToGroup(tab); boolean isMoveTabOutOfGroup = isMoveTabOutOfGroup(tab);
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java index 62631c0..3123116 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java
@@ -739,13 +739,7 @@ * The selected border should re-appear in the final fading-in stage. */ void prepareOverview() { - if (!FeatureUtilities.isTabToGtsAnimationEnabled() - || !mTabModelSelector.getTabModelFilterProvider() - .getCurrentTabModelFilter() - .isTabModelRestored()) { - return; - } - + if (!FeatureUtilities.isTabToGtsAnimationEnabled()) return; assert mVisible; int count = 0; for (int i = 0; i < mModel.size(); i++) { @@ -822,7 +816,7 @@ } /** - * @see TabSwitcherMediator.ResetHandler#softCleanup + * @see GridTabSwitcherMediator.ResetHandler#softCleanup */ void softCleanup() { assert !mVisible;
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMediator.java index ab3f495..8d630fd 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMediator.java
@@ -119,7 +119,7 @@ private boolean mShouldIgnoreNextSelect; private int mModelIndexWhenShown; - private int mTabIdWhenShown; + private int mTabIdwhenShown; private int mIndexInNewModelWhenSwitched; private boolean mIsSelectingInTabSwitcher; @@ -225,15 +225,6 @@ onTabSelecting(tab.getId()); } } - - @Override - public void restoreCompleted() { - if (!mContainerViewModel.get(IS_VISIBLE)) return; - - mResetHandler.resetWithTabList( - mTabModelSelector.getTabModelFilterProvider().getCurrentTabModelFilter(), - false, mShowTabsInMruOrder); - } }; mFullscreenManager.addListener(mFullscreenListener); @@ -344,7 +335,7 @@ Tab fromTab = TabModelUtils.getTabById(mTabModelSelector.getCurrentModel(), lastId); assert fromTab != null; if (mModelIndexWhenShown == mTabModelSelector.getCurrentModelIndex()) { - if (tab.getId() == mTabIdWhenShown) { + if (tab.getId() == mTabIdwhenShown) { RecordUserAction.record("MobileTabReturnedToCurrentTab"); RecordHistogram.recordSparseHistogram( "Tabs.TabOffsetOfSwitch." + TabSwitcherCoordinator.COMPONENT_NAME, 0); @@ -420,10 +411,7 @@ mHandler.removeCallbacks(mSoftClearTabListRunnable); mHandler.removeCallbacks(mClearTabListRunnable); boolean quick = false; - if (FeatureUtilities.isTabToGtsAnimationEnabled() - && mTabModelSelector.getTabModelFilterProvider() - .getCurrentTabModelFilter() - .isTabModelRestored()) { + if (FeatureUtilities.isTabToGtsAnimationEnabled()) { quick = mResetHandler.resetWithTabList( mTabModelSelector.getTabModelFilterProvider().getCurrentTabModelFilter(), false, mShowTabsInMruOrder); @@ -441,17 +429,13 @@ @Override public void showOverview(boolean animate) { - if (mTabModelSelector.getTabModelFilterProvider() - .getCurrentTabModelFilter() - .isTabModelRestored()) { - mResetHandler.resetWithTabList( - mTabModelSelector.getTabModelFilterProvider().getCurrentTabModelFilter(), - FeatureUtilities.isTabToGtsAnimationEnabled(), mShowTabsInMruOrder); - } + mResetHandler.resetWithTabList( + mTabModelSelector.getTabModelFilterProvider().getCurrentTabModelFilter(), + FeatureUtilities.isTabToGtsAnimationEnabled(), mShowTabsInMruOrder); if (!animate) mContainerViewModel.set(ANIMATE_VISIBILITY_CHANGES, false); setVisibility(true); mModelIndexWhenShown = mTabModelSelector.getCurrentModelIndex(); - mTabIdWhenShown = mTabModelSelector.getCurrentTabId(); + mTabIdwhenShown = mTabModelSelector.getCurrentTabId(); mContainerViewModel.set(ANIMATE_VISIBILITY_CHANGES, true); if (mIphProvider != null) { mIphProvider.maybeShowIPH(mTabModelSelector.isIncognitoSelected());
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_groups/TabGroupModelFilterUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_groups/TabGroupModelFilterUnitTest.java index 7233aa9..8d15da7 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_groups/TabGroupModelFilterUnitTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_groups/TabGroupModelFilterUnitTest.java
@@ -272,23 +272,6 @@ } @Test - // TODO(mattsimmons): This is actually testing behavior of the superclass but there's no unit - // tests for the superclass today. If one ever exists, this should move to that test. - public void isTabModelRestored() { - setupTabGroupModelFilter(false, false); - assertThat(mTabGroupModelFilter.isTabModelRestored(), equalTo(false)); - - setupTabGroupModelFilter(true, false); - assertThat(mTabGroupModelFilter.isTabModelRestored(), equalTo(true)); - - setupTabGroupModelFilter(false, true); - assertThat(mTabGroupModelFilter.isTabModelRestored(), equalTo(true)); - - setupTabGroupModelFilter(true, true); - assertThat(mTabGroupModelFilter.isTabModelRestored(), equalTo(true)); - } - - @Test public void addTab_ToExistingGroup() { Tab newTab = prepareTab(NEW_TAB_ID, NEW_TAB_ID, TAB1_ID); doReturn(TabLaunchType.FROM_CHROME_UI).when(newTab).getLaunchType();
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMediatorUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMediatorUnitTest.java index 63a1567..10771ef 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMediatorUnitTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMediatorUnitTest.java
@@ -434,60 +434,6 @@ } @Test - public void updatesResetHandlerOnRestoreCompleted() { - initAndAssertAllProperties(); - mMediator.showOverview(true); - assertThat(mModel.get(TabListContainerProperties.IS_VISIBLE), equalTo(true)); - - mTabModelObserverCaptor.getValue().restoreCompleted(); - - // MRU will be false unless the start surface is enabled. - verify(mResetHandler).resetWithTabList(mTabModelFilter, false, false); - } - - @Test - public void showOverviewDoesNotUpdateResetHandlerBeforeRestoreCompleted() { - initAndAssertAllProperties(); - doReturn(false).when(mTabModelFilter).isTabModelRestored(); - mMediator.showOverview(true); - - // MRU will be false unless the start surface is enabled. - verify(mResetHandler, never()).resetWithTabList(mTabModelFilter, true, false); - } - - @Test - public void prepareOverviewDoesNotUpdateResetHandlerBeforeRestoreCompleted() { - initAndAssertAllProperties(); - doReturn(false).when(mTabModelFilter).isTabModelRestored(); - mMediator.prepareOverview(); - - // MRU will be false unless the start surface is enabled. - verify(mResetHandler, never()).resetWithTabList(mTabModelFilter, false, false); - } - - @Test - public void showOverviewUpdatesResetHandlerAfterRestoreCompleted() { - initAndAssertAllProperties(); - doReturn(true).when(mTabModelFilter).isTabModelRestored(); - - mMediator.showOverview(true); - - // MRU will be false unless the start surface is enabled. - verify(mResetHandler).resetWithTabList(mTabModelFilter, true, false); - } - - @Test - public void prepareOverviewUpdatesResetHandlerAfterRestoreCompleted() { - initAndAssertAllProperties(); - doReturn(true).when(mTabModelFilter).isTabModelRestored(); - - mMediator.prepareOverview(); - - // MRU will be false unless the start surface is enabled. - verify(mResetHandler).resetWithTabList(mTabModelFilter, false, false); - } - - @Test @DisableFeatures(ChromeFeatureList.TAB_GROUPS_UI_IMPROVEMENTS_ANDROID) public void openDialogButton_FlagDisabled() { FeatureUtilities.setTabGroupsAndroidEnabledForTesting(false);
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedNewTabPage.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedNewTabPage.java index 9ea8762..f222919 100644 --- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedNewTabPage.java +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedNewTabPage.java
@@ -28,6 +28,7 @@ import org.chromium.chrome.browser.ntp.NewTabPageLayout; import org.chromium.chrome.browser.ntp.NewTabPageUma; import org.chromium.chrome.browser.ntp.SnapScrollHelper; +import org.chromium.chrome.browser.ntp.snippets.SectionHeaderView; import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; import org.chromium.chrome.browser.search_engines.TemplateUrlServiceFactory; import org.chromium.chrome.browser.tabmodel.TabModelSelector; @@ -82,12 +83,15 @@ FeedProcessScopeFactory.getFeedOfflineIndicator(), OfflinePageBridge.getForProfile(mTab.getProfile()), FeedProcessScopeFactory.getFeedLoggingBridge()); - mNewTabPageLayout = (NewTabPageLayout) LayoutInflater.from(mTab.getActivity()) - .inflate(R.layout.new_tab_page_layout, null); + LayoutInflater inflater = LayoutInflater.from(mTab.getActivity()); + mNewTabPageLayout = (NewTabPageLayout) inflater.inflate(R.layout.new_tab_page_layout, null); + SectionHeaderView sectionHeaderView = (SectionHeaderView) inflater.inflate( + R.layout.new_tab_page_snippets_expandable_header, null, false); mCoordinator = new FeedSurfaceCoordinator(mTab.getActivity(), host.createHistoryNavigationDelegate(), new SnapScrollHelper(mNewTabPageManager, mNewTabPageLayout), mNewTabPageLayout, - actionApi, mTab.getActivity().getNightModeStateProvider().isInNightMode(), this); + sectionHeaderView, actionApi, + mTab.getActivity().getNightModeStateProvider().isInNightMode(), this); // Record the timestamp at which the new tab page's construction started. NewTabPageUma.trackTimeToFirstDraw(mCoordinator.getView(), mConstructedTimeNs); @@ -162,4 +166,4 @@ public View getSectionHeaderViewForTesting() { return mCoordinator.getSectionHeaderView(); } -} \ No newline at end of file +}
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java index 8431f5b..3c45efc 100644 --- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceCoordinator.java
@@ -269,6 +269,7 @@ * @param historyNavigationDelegate The {@link HistoryNavigationDelegate} for the root view. * @param snapScrollHelper The {@link SnapScrollHelper} for the New Tab Page. * @param ntpHeader The extra header on top of the feeds for the New Tab Page. + * @param sectionHeaderView The {@link SectionHeaderView} for the feed. * @param actionApi The {@link ActionApi} implementation to handle actions. * @param showDarkBackground Whether is shown on dark background. * @param delegate The constructing {@link FeedSurfaceDelegate}. @@ -276,9 +277,11 @@ public FeedSurfaceCoordinator(ChromeActivity activity, @Nullable HistoryNavigationDelegate historyNavigationDelegate, @Nullable SnapScrollHelper snapScrollHelper, @Nullable View ntpHeader, - ActionApi actionApi, boolean showDarkBackground, FeedSurfaceDelegate delegate) { + @Nullable SectionHeaderView sectionHeaderView, ActionApi actionApi, + boolean showDarkBackground, FeedSurfaceDelegate delegate) { mActivity = activity; mNtpHeader = ntpHeader; + mSectionHeaderView = sectionHeaderView; mActionApi = actionApi; mShowDarkBackground = showDarkBackground; mDelegate = delegate; @@ -378,10 +381,6 @@ mStream = streamScope.getStream(); mStreamLifecycleManager = mDelegate.createStreamLifecycleManager(mStream, mActivity); - LayoutInflater inflater = LayoutInflater.from(mActivity); - mSectionHeaderView = (SectionHeaderView) inflater.inflate( - R.layout.new_tab_page_snippets_expandable_header, mRootView, false); - View view = mStream.getView(); view.setBackgroundResource(R.color.modern_primary_color); mRootView.addView(view); @@ -389,12 +388,13 @@ ViewResizer.createAndAttach(view, mUiConfig, mDefaultMargin, mWideMargin); if (mNtpHeader != null) UiUtils.removeViewFromParent(mNtpHeader); - UiUtils.removeViewFromParent(mSectionHeaderView); + if (mSectionHeaderView != null) UiUtils.removeViewFromParent(mSectionHeaderView); if (mSigninPromoView != null) UiUtils.removeViewFromParent(mSigninPromoView); + if (mNtpHeader != null) { mStream.setHeaderViews(Arrays.asList(new NonDismissibleHeader(mNtpHeader), new NonDismissibleHeader(mSectionHeaderView))); - } else { + } else if (mSectionHeaderView != null) { mStream.setHeaderViews(Arrays.asList(new NonDismissibleHeader(mSectionHeaderView))); } mStream.addScrollListener(new FeedLoggingBridge.ScrollEventReporter( @@ -482,11 +482,14 @@ /** Update header views in the Stream. */ void updateHeaderViews(boolean isPromoVisible) { if (mNtpHeader != null) { + assert mSectionHeaderView != null; mStream.setHeaderViews( isPromoVisible ? Arrays.asList(new NonDismissibleHeader(mNtpHeader), new NonDismissibleHeader(mSectionHeaderView), new SignInPromoHeader()) : Arrays.asList(new NonDismissibleHeader(mNtpHeader), new NonDismissibleHeader(mSectionHeaderView))); + } else if (mSectionHeaderView == null) { + if (isPromoVisible) mStream.setHeaderViews(Arrays.asList(new SignInPromoHeader())); } else { mStream.setHeaderViews(isPromoVisible ? Arrays.asList(new NonDismissibleHeader(mSectionHeaderView),
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java index 8df5990..17893fc 100644 --- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java
@@ -50,6 +50,7 @@ private @Nullable SignInPromo mSignInPromo; private boolean mFeedEnabled; + private boolean mHasHeader; private boolean mTouchEnabled = true; private boolean mStreamContentChanged; private int mThumbnailWidth; @@ -67,6 +68,7 @@ mSigninManager = IdentityServicesProvider.getSigninManager(); mPrefChangeRegistrar = new PrefChangeRegistrar(); + mHasHeader = mCoordinator.getSectionHeaderView() != null; mPrefChangeRegistrar.addObserver(Pref.NTP_ARTICLES_SECTION_ENABLED, this::updateContent); initialize(); // Create the content. @@ -95,19 +97,22 @@ private void updateContent() { mFeedEnabled = FeedProcessScopeFactory.isFeedProcessEnabled(); if ((mFeedEnabled && mCoordinator.getStream() != null) - || (!mFeedEnabled && mCoordinator.getScrollViewForPolicy() != null)) + || (!mFeedEnabled && mCoordinator.getScrollViewForPolicy() != null)) { return; + } if (mFeedEnabled) { mCoordinator.createStream(); - if (mSnapScrollHelper != null) + if (mSnapScrollHelper != null) { mSnapScrollHelper.setView(mCoordinator.getStream().getView()); + } initializePropertiesForStream(); } else { destroyPropertiesForStream(); mCoordinator.createScrollViewForPolicy(); - if (mSnapScrollHelper != null) + if (mSnapScrollHelper != null) { mSnapScrollHelper.setView(mCoordinator.getScrollViewForPolicy()); + } initializePropertiesForPolicy(); } } @@ -140,13 +145,19 @@ boolean suggestionsVisible = PrefServiceBridge.getInstance().getBoolean(Pref.NTP_ARTICLES_LIST_VISIBLE); - Resources res = mCoordinator.getSectionHeaderView().getResources(); - mSectionHeader = - new SectionHeader(res.getString(R.string.ntp_article_suggestions_section_header), - suggestionsVisible, this::onSectionHeaderToggled); - mPrefChangeRegistrar.addObserver(Pref.NTP_ARTICLES_LIST_VISIBLE, this::updateSectionHeader); - mCoordinator.getSectionHeaderView().setHeader(mSectionHeader); - stream.setStreamContentVisibility(mSectionHeader.isExpanded()); + + if (mHasHeader) { + Resources res = mCoordinator.getSectionHeaderView().getResources(); + mSectionHeader = new SectionHeader( + res.getString(R.string.ntp_article_suggestions_section_header), + suggestionsVisible, this::onSectionHeaderToggled); + mPrefChangeRegistrar.addObserver( + Pref.NTP_ARTICLES_LIST_VISIBLE, this::updateSectionHeader); + mCoordinator.getSectionHeaderView().setHeader(mSectionHeader); + } + // Show feed if there is no header that would allow user to hide feed. + // This is currently only relevant for the two panes start surface. + stream.setStreamContentVisibility(mHasHeader ? mSectionHeader.isExpanded() : true); if (SignInPromo.shouldCreatePromo()) { mSignInPromo = new FeedSignInPromo(mSigninManager);
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/NtpStreamLifecycleManager.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/NtpStreamLifecycleManager.java index 95c99f4f..7f02d80b 100644 --- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/NtpStreamLifecycleManager.java +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/NtpStreamLifecycleManager.java
@@ -12,6 +12,8 @@ import org.chromium.base.VisibleForTesting; import org.chromium.chrome.browser.ntp.NewTabPage; +import org.chromium.chrome.browser.preferences.Pref; +import org.chromium.chrome.browser.preferences.PrefServiceBridge; import org.chromium.chrome.browser.tab.EmptyTabObserver; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.Tab.TabHidingType; @@ -81,13 +83,19 @@ /** @return Whether the {@link Stream} can be shown. */ @Override protected boolean canShow() { - return super.canShow() && !mTab.isHidden(); + // We don't call Stream#onShow to prevent feed services from being warmed up if the user + // has opted out from article suggestions during the previous session. + return super.canShow() + && PrefServiceBridge.getInstance().getBoolean(Pref.NTP_ARTICLES_LIST_VISIBLE) + && !mTab.isHidden(); } /** @return Whether the {@link Stream} can be activated. */ @Override protected boolean canActivate() { - return super.canActivate() && mTab.isUserInteractable(); + return super.canActivate() + && PrefServiceBridge.getInstance().getBoolean(Pref.NTP_ARTICLES_LIST_VISIBLE) + && mTab.isUserInteractable(); } /**
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/StreamLifecycleManager.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/StreamLifecycleManager.java index 3921ddfb..2aced8e 100644 --- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/StreamLifecycleManager.java +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/StreamLifecycleManager.java
@@ -89,11 +89,8 @@ /** @return Whether the {@link Stream} can be shown. */ protected boolean canShow() { final int state = ApplicationStatus.getStateForActivity(mActivity); - // We don't call Stream#onShow to prevent feed services from being warmed up if the user - // has opted out from article suggestions during the previous session. return (mStreamState == StreamState.CREATED || mStreamState == StreamState.HIDDEN) - && (state == ActivityState.STARTED || state == ActivityState.RESUMED) - && FeedProcessScopeFactory.areArticlesVisibleDuringSession(); + && (state == ActivityState.STARTED || state == ActivityState.RESUMED); } /** Calls {@link Stream#onShow()}. */ @@ -107,8 +104,7 @@ /** @return Whether the {@link Stream} can be activated. */ protected boolean canActivate() { return (mStreamState == StreamState.SHOWN || mStreamState == StreamState.INACTIVE) - && ApplicationStatus.getStateForActivity(mActivity) == ActivityState.RESUMED - && FeedProcessScopeFactory.areArticlesVisibleDuringSession(); + && ApplicationStatus.getStateForActivity(mActivity) == ActivityState.RESUMED; } /** Calls {@link Stream#onActive()}. */ @@ -132,8 +128,9 @@ /** Calls {@link Stream#onHide()}. */ protected void hide() { if (mStreamState == StreamState.HIDDEN || mStreamState == StreamState.CREATED - || mStreamState == StreamState.DESTROYED) + || mStreamState == StreamState.DESTROYED) { return; + } // Make sure the Stream is inactive before setting it to hidden state. deactivate(); @@ -169,4 +166,4 @@ protected String restoreInstanceState() { return null; } -} \ No newline at end of file +}
diff --git a/chrome/android/java/res/layout/microtransaction_toolbar.xml b/chrome/android/java/res/layout/microtransaction_toolbar.xml index 1f22722..cc5b2fc 100644 --- a/chrome/android/java/res/layout/microtransaction_toolbar.xml +++ b/chrome/android/java/res/layout/microtransaction_toolbar.xml
@@ -4,7 +4,6 @@ found in the LICENSE file. --> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:background="@color/sheet_bg_color" android:layout_height="wrap_content" android:layout_width="match_parent">
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/background_sync/GooglePlayServicesChecker.java b/chrome/android/java/src/org/chromium/chrome/browser/background_sync/GooglePlayServicesChecker.java index e0944f8fa..f7efb83 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/background_sync/GooglePlayServicesChecker.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/background_sync/GooglePlayServicesChecker.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.background_sync; import org.chromium.base.Log; +import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.metrics.RecordHistogram; import org.chromium.chrome.browser.externalauth.ExternalAuthUtils; @@ -15,7 +16,6 @@ */ final class GooglePlayServicesChecker { private static final String TAG = "PlayServicesChecker"; - private GooglePlayServicesChecker() {} /** @@ -25,14 +25,16 @@ * wait until Play Services is updated before attempting them. */ @CalledByNative - private static boolean shouldDisableBackgroundSync() { + @VisibleForTesting + protected static boolean shouldDisableBackgroundSync() { boolean isAvailable = true; if (!ExternalAuthUtils.canUseGooglePlayServices()) { Log.i(TAG, "Disabling Background Sync because Play Services is not up to date."); isAvailable = false; } + RecordHistogram.recordBooleanHistogram( "BackgroundSync.LaunchTask.PlayServicesAvailable", isAvailable); - return isAvailable; + return !isAvailable; } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordEntryEditor.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordEntryEditor.java index 6cd8497..b98b8d6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordEntryEditor.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordEntryEditor.java
@@ -134,10 +134,7 @@ mPasswordLabel.setError(getContext().getString( R.string.pref_edit_dialog_field_required_validation_message)); } else { - PasswordEditingDelegateProvider.getInstance() - .getPasswordEditingDelegate() - .editSavedPasswordEntry( - mUsernameText.getText().toString(), mPasswordText.getText().toString()); + // TODO(crbug.com/377410): Save the changes if everything was ok. getActivity().finish(); } } @@ -147,10 +144,4 @@ super.onSaveInstanceState(savedInstanceState); savedInstanceState.putBoolean(VIEW_BUTTON_PRESSED, mViewButtonPressed); } - - @Override - public void onDestroy() { - super.onDestroy(); - PasswordEditingDelegateProvider.getInstance().getPasswordEditingDelegate().destroy(); - } } \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordEntryViewer.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordEntryViewer.java index 86cb1b4..e212d36 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordEntryViewer.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordEntryViewer.java
@@ -199,9 +199,6 @@ if (mCopyButtonPressed) copyPassword(); } PasswordManagerHandlerProvider.getInstance().addObserver(this); - PasswordManagerHandlerProvider.getInstance() - .getPasswordManagerHandler() - .updatePasswordLists(); } @Override @@ -437,13 +434,13 @@ @Override public void passwordListAvailable(int count) { if (mException) return; - TextView passwordTextView = mView.findViewById(R.id.password_entry_viewer_password); + TextView passwordsLinkTextView = mView.findViewById(R.id.passwords_link); SavedPasswordEntry SavedPasswordEntry = PasswordManagerHandlerProvider.getInstance() .getPasswordManagerHandler() .getSavedPasswordEntry(mID); setRowText(R.id.url_row, SavedPasswordEntry.getUrl()); setRowText(R.id.username_row, SavedPasswordEntry.getUserName()); - passwordTextView.setText(SavedPasswordEntry.getPassword()); + passwordsLinkTextView.setText(SavedPasswordEntry.getPassword()); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/sync/AccountManagementFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/sync/AccountManagementFragment.java index b312c9c..b65a74d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/sync/AccountManagementFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/sync/AccountManagementFragment.java
@@ -391,15 +391,15 @@ final DialogFragment clearDataProgressDialog = new ClearDataProgressDialog(); IdentityServicesProvider.getSigninManager().signOut( - SignoutReason.USER_CLICKED_SIGNOUT_SETTINGS, - null, new SigninManager.WipeDataHooks() { + SignoutReason.USER_CLICKED_SIGNOUT_SETTINGS, new SigninManager.SignOutCallback() { @Override public void preWipeData() { clearDataProgressDialog.show( getFragmentManager(), CLEAR_DATA_PROGRESS_DIALOG_TAG); } + @Override - public void postWipeData() { + public void signOutComplete() { if (clearDataProgressDialog.isAdded()) { clearDataProgressDialog.dismissAllowingStateLoss(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/sync/SyncAndServicesPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/sync/SyncAndServicesPreferences.java index 8f53420..3ae9d01 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/sync/SyncAndServicesPreferences.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/sync/SyncAndServicesPreferences.java
@@ -528,7 +528,8 @@ // TODO(https://crbug.com/873116): Pass the correct reason for the signout. IdentityServicesProvider.getSigninManager().signOut( SignoutReason.USER_CLICKED_SIGNOUT_SETTINGS, - () -> IdentityServicesProvider.getSigninManager().signIn(account, null, null)); + () -> IdentityServicesProvider.getSigninManager().signIn(account, null, null), + false); return; }
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 2447505..aa0e24ff 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
@@ -226,7 +226,7 @@ // signed-out. clearNewSignedInAccountName(); performResignin(newName); - }); + }, false); } private void performResignin(String newName) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java index 5ce6493d..ad24c41 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninManager.java
@@ -99,18 +99,18 @@ } /** - * Hooks for wiping data during sign out. + * Callbacks for the sign-out flow. */ - public interface WipeDataHooks { + public interface SignOutCallback { /** - * Called before data is wiped. + * Called before the data wiping is started. */ - void preWipeData(); + default void preWipeData() {} /** - * Called after data is wiped. + * Called after the data is wiped. */ - void postWipeData(); + void signOutComplete(); } /** @@ -171,20 +171,16 @@ * cleared atomically, and all final fields to be set upon initialization. */ private static class SignOutState { - final Runnable mCallback; - final WipeDataHooks mWipeDataHooks; + final @Nullable SignOutCallback mSignOutCallback; final boolean mShouldWipeUserData; /** - * @param callback Called after sign-out finishes and all data has been cleared. - * @param wipeDataHooks Hooks to call before/after data wiping phase of sign-out. + * @param signOutCallback Hooks to call before/after data wiping phase of sign-out. * @param shouldWipeUserData Flag to wipe user data as requested by the user and enforced * for managed users. */ - SignOutState(@Nullable Runnable callback, @Nullable WipeDataHooks wipeDataHooks, - boolean shouldWipeUserData) { - this.mCallback = callback; - this.mWipeDataHooks = wipeDataHooks; + SignOutState(@Nullable SignOutCallback signOutCallback, boolean shouldWipeUserData) { + this.mSignOutCallback = signOutCallback; this.mShouldWipeUserData = shouldWipeUserData; } } @@ -587,40 +583,30 @@ } /** - * Invokes signOut with no callback or wipeDataHooks. + * Invokes signOut with no callback. */ public void signOut(@SignoutReason int signoutSource) { - signOut(signoutSource, null, null, false); + signOut(signoutSource, null, false); } /** - * Invokes signOut() with no wipeDataHooks. - */ - public void signOut(@SignoutReason int signoutSource, Runnable callback) { - signOut(signoutSource, callback, null, false); - } - - /** - * Signs out of Chrome. - * <p/> - * This method clears the signed-in username, stops sync and sends out a + * Signs out of Chrome. This method clears the signed-in username, stops sync and sends out a * sign-out notification on the native side. * * @param signoutSource describes the event driving the signout (e.g. * {@link SignoutReason.USER_CLICKED_SIGNOUT_SETTINGS}). - * @param callback Will be invoked after sign-out completes, if not null. - * @param wipeDataHooks Hooks to call before/after data wiping phase of sign-out. + * @param signOutCallback Callback to notify about the sign-out progress. * @param forceWipeUserData Whether user selected to wipe all device data. */ - public void signOut(@SignoutReason int signoutSource, Runnable callback, - WipeDataHooks wipeDataHooks, boolean forceWipeUserData) { + public void signOut(@SignoutReason int signoutSource, SignOutCallback signOutCallback, + boolean forceWipeUserData) { // Only one signOut at a time! assert mSignOutState == null; // Grab the management domain before nativeSignOut() potentially clears it. String managementDomain = getManagementDomain(); - mSignOutState = new SignOutState( - callback, wipeDataHooks, forceWipeUserData || managementDomain != null); + mSignOutState = + new SignOutState(signOutCallback, forceWipeUserData || managementDomain != null); Log.d(TAG, "Signing out, management domain: " + managementDomain); // User data will be wiped in disableSyncAndWipeData(), called from @@ -668,7 +654,7 @@ // native (since otherwise SigninManager.signOut would have created // it). As sign out from native can only happen from policy code, // the account is managed and the user data must be wiped. - mSignOutState = new SignOutState(null, null, true); + mSignOutState = new SignOutState(null, true); } Log.d(TAG, "On native signout, wipe user data: " + mSignOutState.mShouldWipeUserData); @@ -676,28 +662,19 @@ // Native sign-out must happen before resetting the account so data is deleted correctly. // http://crbug.com/589028 ChromeSigninController.get().setSignedInAccountName(null); - if (mSignOutState.mWipeDataHooks != null) mSignOutState.mWipeDataHooks.preWipeData(); - disableSyncAndWipeData(mSignOutState.mShouldWipeUserData, this::onProfileDataWiped); + if (mSignOutState.mSignOutCallback != null) mSignOutState.mSignOutCallback.preWipeData(); + disableSyncAndWipeData(mSignOutState.mShouldWipeUserData, this::finishSignOut); mAccountTrackerService.invalidateAccountSeedStatus(true); } - @VisibleForTesting - protected void onProfileDataWiped() { + void finishSignOut() { // Should be set at start of sign-out flow. assert mSignOutState != null; - if (mSignOutState.mWipeDataHooks != null) mSignOutState.mWipeDataHooks.postWipeData(); - finishSignOut(); - } - - private void finishSignOut() { - // Should be set at start of sign-out flow. - assert mSignOutState != null; - - if (mSignOutState.mCallback != null) { - PostTask.postTask(UiThreadTaskTraits.DEFAULT, mSignOutState.mCallback); - } + SignOutCallback signOutCallback = mSignOutState.mSignOutCallback; mSignOutState = null; + + if (signOutCallback != null) signOutCallback.signOutComplete(); notifyCallbacksWaitingForOperation(); for (SignInStateObserver observer : mSignInStateObservers) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelFilter.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelFilter.java index fa2b5ac0..06ec0d0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelFilter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelFilter.java
@@ -26,7 +26,6 @@ Collections.unmodifiableList(new ArrayList<Tab>()); private TabModel mTabModel; protected ObserverList<TabModelObserver> mFilteredObservers = new ObserverList<>(); - private boolean mTabRestoreCompleted; public TabModelFilter(TabModel tabModel) { mTabModel = tabModel; @@ -89,7 +88,7 @@ * @return An unmodifiable list of {@link Tab}s that are not related to any tabs */ @NonNull - public final List<Tab> getTabsWithNoOtherRelatedTabs() { + final public List<Tab> getTabsWithNoOtherRelatedTabs() { List<Tab> tabs = new ArrayList<>(); for (int i = 0; i < mTabModel.getCount(); i++) { Tab tab = mTabModel.getTabAt(i); @@ -142,13 +141,6 @@ protected abstract void resetFilterStateInternal(); /** - * @return Whether the tab model is fully restored. - */ - public boolean isTabModelRestored() { - return mTabRestoreCompleted || isIncognito(); - } - - /** * Concrete class requires to define what's the behavior when {@link TabModel} removed a * {@link Tab}. * @param tab {@link Tab} had removed. @@ -272,8 +264,6 @@ @Override public void restoreCompleted() { - mTabRestoreCompleted = true; - if (getCount() != 0) reorder(); for (TabModelObserver observer : mFilteredObservers) {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java index 63c1a18..011d20e 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
@@ -949,11 +949,11 @@ } /** - * Tap on the peeking Bar to expand the panel, then taps on the base page to close it. + * Tap on the peeking Bar to expand the panel, then close it. */ private void tapBarToExpandAndClosePanel() throws InterruptedException { tapPeekingBarToExpandAndAssert(); - tapBasePageToClosePanel(); + closePanel(); } /** @@ -1836,7 +1836,7 @@ pressAppMenuKey(); assertAppMenuVisibility(false); - tapBasePageToClosePanel(); + closePanel(); pressAppMenuKey(); assertAppMenuVisibility(true);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/micro/MicrotransactionRenderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/micro/MicrotransactionRenderTest.java new file mode 100644 index 0000000..e2490c4 --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/micro/MicrotransactionRenderTest.java
@@ -0,0 +1,348 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.payments.micro; + +import android.support.annotation.Nullable; +import android.support.graphics.drawable.VectorDrawableCompat; +import android.support.test.filters.SmallTest; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ProgressBar; +import android.widget.RelativeLayout; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.chromium.base.test.util.Feature; +import org.chromium.chrome.R; +import org.chromium.chrome.test.ChromeJUnit4ClassRunner; +import org.chromium.chrome.test.ui.DummyUiActivityTestCase; +import org.chromium.chrome.test.util.RenderTestRule; +import org.chromium.content_public.browser.test.util.TestThreadUtils; +import org.chromium.ui.modelutil.PropertyModel; +import org.chromium.ui.modelutil.PropertyModelChangeProcessor; + +/** Tests for the microtransaction view binder. */ +@RunWith(ChromeJUnit4ClassRunner.class) +public class MicrotransactionRenderTest extends DummyUiActivityTestCase { + @Rule + public RenderTestRule mRenderTestRule = + new RenderTestRule("components/test/data/payments/render_tests"); + + private PropertyModel mModel; + private MicrotransactionView mView; + private RelativeLayout mLayout; + private PropertyModelChangeProcessor mProcessor; + + @Override + public void setUpTest() throws Exception { + super.setUpTest(); + // Initial button state: + mModel = + new PropertyModel.Builder(MicrotransactionProperties.ALL_KEYS) + .with(MicrotransactionProperties.ACCOUNT_BALANCE, "$18.00") + .with(MicrotransactionProperties.AMOUNT, "$1.00") + .with(MicrotransactionProperties.CURRENCY, "USD") + .with(MicrotransactionProperties.IS_SHOWING_LINE_ITEMS, true) + .with(MicrotransactionProperties.IS_SHOWING_PAY_BUTTON, true) + .with(MicrotransactionProperties.IS_SHOWING_PROCESSING_SPINNER, false) + .with(MicrotransactionProperties.PAYMENT_APP_ICON, + VectorDrawableCompat.create(getActivity().getResources(), + R.drawable.ic_done_googblue_36dp, getActivity().getTheme())) + .with(MicrotransactionProperties.PAYMENT_APP_NAME, "App Name") + .with(MicrotransactionProperties.STATUS_TEXT_RESOURCE, + R.string.payment_request_payment_method_section_name) + .build(); + + mView = new MicrotransactionView(getActivity()); + mProcessor = PropertyModelChangeProcessor.create( + mModel, mView, MicrotransactionViewBinder::bind); + + mLayout = new RelativeLayout(getActivity()); + RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); + mLayout.addView(mView.getContentView(), params); + mLayout.addView(mView.getToolbarView(), params); + + TestThreadUtils.runOnUiThreadBlocking(() -> { + getActivity().setContentView(mLayout, + new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT)); + }); + } + + @Override + public void tearDownTest() throws Exception { + mProcessor.destroy(); + } + + @Test + @SmallTest + @Feature({"Microtransaction", "RenderTest"}) + public void testButtonInitial() throws Throwable { + mRenderTestRule.render(mLayout, "button_initial"); + } + + @Test + @SmallTest + @Feature({"Microtransaction", "RenderTest"}) + public void testButtonInitialExpanded() throws Throwable { + TestThreadUtils.runOnUiThreadBlocking( + () -> mModel.set(MicrotransactionProperties.PAYMENT_APP_NAME_ALPHA, 1f)); + mRenderTestRule.render(mLayout, "button_initial_expanded"); + } + + @Test + @SmallTest + @Feature({"Microtransaction", "RenderTest"}) + public void testButtonProcessing() throws Throwable { + TestThreadUtils.runOnUiThreadBlocking(() -> showButtonProcessing()); + mRenderTestRule.render(mLayout, "button_processing"); + } + + @Test + @SmallTest + @Feature({"Microtransaction", "RenderTest"}) + public void testButtonProcessingExpanded() throws Throwable { + TestThreadUtils.runOnUiThreadBlocking(() -> { + mModel.set(MicrotransactionProperties.PAYMENT_APP_NAME_ALPHA, 1f); + showButtonProcessing(); + }); + mRenderTestRule.render(mLayout, "button_processing_expanded"); + } + + private void showButtonProcessing() { + mModel.set(MicrotransactionProperties.IS_SHOWING_LINE_ITEMS, false); + mModel.set(MicrotransactionProperties.IS_SHOWING_PAY_BUTTON, false); + mModel.set(MicrotransactionProperties.IS_SHOWING_PROCESSING_SPINNER, true); + mModel.set(MicrotransactionProperties.STATUS_TEXT, null); + mModel.set(MicrotransactionProperties.STATUS_TEXT_RESOURCE, + R.string.payments_processing_message); + + stopSpinner(mView.mToolbarProcessingSpinner); + stopSpinner(mView.mContentProcessingSpinner); + } + + private void stopSpinner(View view) { + ProgressBar spinner = (ProgressBar) view; + spinner.setIndeterminate(false); + spinner.setMax(2); + spinner.setProgress(1); + } + + @Test + @SmallTest + @Feature({"Microtransaction", "RenderTest"}) + public void testButtonErrorResource() throws Throwable { + TestThreadUtils.runOnUiThreadBlocking(() -> { + showEmphasizedStatus(R.string.payment_fingerprint_not_recognized, null, + R.drawable.ic_error_googred_36dp, R.color.microtransaction_error_tint); + mModel.set(MicrotransactionProperties.IS_SHOWING_LINE_ITEMS, false); + }); + mRenderTestRule.render(mLayout, "button_error_resource"); + } + + @Test + @SmallTest + @Feature({"Microtransaction", "RenderTest"}) + public void testButtonErrorResourceExpanded() throws Throwable { + TestThreadUtils.runOnUiThreadBlocking(() -> { + mModel.set(MicrotransactionProperties.PAYMENT_APP_NAME_ALPHA, 1f); + showEmphasizedStatus(R.string.payment_fingerprint_not_recognized, null, + R.drawable.ic_error_googred_36dp, R.color.microtransaction_error_tint); + mModel.set(MicrotransactionProperties.IS_SHOWING_LINE_ITEMS, false); + }); + mRenderTestRule.render(mLayout, "button_error_resource_expanded"); + } + + @Test + @SmallTest + @Feature({"Microtransaction", "RenderTest"}) + public void testButtonErrorString() throws Throwable { + TestThreadUtils.runOnUiThreadBlocking(() -> { + showEmphasizedStatus(null, "Finger moved too fast. Try again.", + R.drawable.ic_error_googred_36dp, R.color.microtransaction_error_tint); + mModel.set(MicrotransactionProperties.IS_SHOWING_LINE_ITEMS, false); + }); + mRenderTestRule.render(mLayout, "button_error_string"); + } + + @Test + @SmallTest + @Feature({"Microtransaction", "RenderTest"}) + public void testButtonErrorStringExpanded() throws Throwable { + TestThreadUtils.runOnUiThreadBlocking(() -> { + mModel.set(MicrotransactionProperties.PAYMENT_APP_NAME_ALPHA, 1f); + showEmphasizedStatus(null, "Finger moved too fast. Try again.", + R.drawable.ic_error_googred_36dp, R.color.microtransaction_error_tint); + mModel.set(MicrotransactionProperties.IS_SHOWING_LINE_ITEMS, false); + }); + mRenderTestRule.render(mLayout, "button_error_string_expanded"); + } + + @Test + @SmallTest + @Feature({"Microtransaction", "RenderTest"}) + public void testButtonSuccess() throws Throwable { + TestThreadUtils.runOnUiThreadBlocking(() -> { + showEmphasizedStatus(R.string.payment_complete_message, null, + R.drawable.ic_done_googblue_36dp, R.color.microtransaction_emphasis_tint); + mModel.set(MicrotransactionProperties.IS_SHOWING_LINE_ITEMS, false); + }); + mRenderTestRule.render(mLayout, "button_success"); + } + + @Test + @SmallTest + @Feature({"Microtransaction", "RenderTest"}) + public void testButtonSuccessExpanded() throws Throwable { + TestThreadUtils.runOnUiThreadBlocking(() -> { + mModel.set(MicrotransactionProperties.PAYMENT_APP_NAME_ALPHA, 1f); + showEmphasizedStatus(R.string.payment_complete_message, null, + R.drawable.ic_done_googblue_36dp, R.color.microtransaction_emphasis_tint); + mModel.set(MicrotransactionProperties.IS_SHOWING_LINE_ITEMS, false); + }); + mRenderTestRule.render(mLayout, "button_success_expanded"); + } + + @Test + @SmallTest + @Feature({"Microtransaction", "RenderTest"}) + public void testFingerprintInitial() throws Throwable { + TestThreadUtils.runOnUiThreadBlocking(() -> showFingerprintInitial()); + mRenderTestRule.render(mLayout, "fingerprint_initial"); + } + + @Test + @SmallTest + @Feature({"Microtransaction", "RenderTest"}) + public void testFingerprintInitialExpanded() throws Throwable { + TestThreadUtils.runOnUiThreadBlocking(() -> { + mModel.set(MicrotransactionProperties.PAYMENT_APP_NAME_ALPHA, 1f); + showFingerprintInitial(); + }); + mRenderTestRule.render(mLayout, "fingerprint_initial_expanded"); + } + + private void showFingerprintInitial() { + mModel.set(MicrotransactionProperties.IS_SHOWING_PAY_BUTTON, false); + mModel.set(MicrotransactionProperties.STATUS_ICON, R.drawable.ic_fingerprint_grey500_36dp); + mModel.set( + MicrotransactionProperties.STATUS_ICON_TINT, R.color.microtransaction_default_tint); + mModel.set(MicrotransactionProperties.STATUS_TEXT_RESOURCE, + R.string.payment_touch_sensor_to_pay); + } + + @Test + @SmallTest + @Feature({"Microtransaction", "RenderTest"}) + public void testFingerprintProcessing() throws Throwable { + TestThreadUtils.runOnUiThreadBlocking(() -> showFingerprintProcessing()); + mRenderTestRule.render(mLayout, "fingerprint_processing"); + } + + @Test + @SmallTest + @Feature({"Microtransaction", "RenderTest"}) + public void testFingerprintProcessingExpanded() throws Throwable { + TestThreadUtils.runOnUiThreadBlocking(() -> { + mModel.set(MicrotransactionProperties.PAYMENT_APP_NAME_ALPHA, 1f); + showFingerprintProcessing(); + }); + mRenderTestRule.render(mLayout, "fingerprint_processing_expanded"); + } + + private void showFingerprintProcessing() { + mModel.set(MicrotransactionProperties.IS_SHOWING_PAY_BUTTON, false); + mModel.set(MicrotransactionProperties.STATUS_TEXT, null); + mModel.set(MicrotransactionProperties.STATUS_TEXT_RESOURCE, + R.string.payments_processing_message); + mModel.set(MicrotransactionProperties.STATUS_ICON, R.drawable.ic_fingerprint_grey500_36dp); + mModel.set(MicrotransactionProperties.STATUS_ICON_TINT, + R.color.microtransaction_emphasis_tint); + } + + @Test + @SmallTest + @Feature({"Microtransaction", "RenderTest"}) + public void testFingerprintErrorResource() throws Throwable { + TestThreadUtils.runOnUiThreadBlocking(() -> { + showEmphasizedStatus(R.string.payment_fingerprint_not_recognized, null, + R.drawable.ic_error_googred_36dp, R.color.microtransaction_error_tint); + }); + mRenderTestRule.render(mLayout, "fingerprint_error_resource"); + } + + @Test + @SmallTest + @Feature({"Microtransaction", "RenderTest"}) + public void testFingerprintErrorResourceExpanded() throws Throwable { + TestThreadUtils.runOnUiThreadBlocking(() -> { + mModel.set(MicrotransactionProperties.PAYMENT_APP_NAME_ALPHA, 1f); + showEmphasizedStatus(R.string.payment_fingerprint_not_recognized, null, + R.drawable.ic_error_googred_36dp, R.color.microtransaction_error_tint); + }); + mRenderTestRule.render(mLayout, "fingerprint_error_resource_expanded"); + } + + @Test + @SmallTest + @Feature({"Microtransaction", "RenderTest"}) + public void testFingerprintErrorString() throws Throwable { + TestThreadUtils.runOnUiThreadBlocking(() -> { + showEmphasizedStatus(null, "Finger moved too fast. Try again.", + R.drawable.ic_error_googred_36dp, R.color.microtransaction_error_tint); + }); + mRenderTestRule.render(mLayout, "fingerprint_error_string"); + } + + @Test + @SmallTest + @Feature({"Microtransaction", "RenderTest"}) + public void testFingerprintErrorStringExpanded() throws Throwable { + TestThreadUtils.runOnUiThreadBlocking(() -> { + mModel.set(MicrotransactionProperties.PAYMENT_APP_NAME_ALPHA, 1f); + showEmphasizedStatus(null, "Finger moved too fast. Try again.", + R.drawable.ic_error_googred_36dp, R.color.microtransaction_error_tint); + }); + mRenderTestRule.render(mLayout, "fingerprint_error_string_expanded"); + } + + @Test + @SmallTest + @Feature({"Microtransaction", "RenderTest"}) + public void testFingerprintSuccess() throws Throwable { + TestThreadUtils.runOnUiThreadBlocking(() -> { + showEmphasizedStatus(R.string.payment_complete_message, null, + R.drawable.ic_done_googblue_36dp, R.color.microtransaction_emphasis_tint); + }); + mRenderTestRule.render(mLayout, "fingerprint_success"); + } + + @Test + @SmallTest + @Feature({"Microtransaction", "RenderTest"}) + public void testFingerprintSuccessExpanded() throws Throwable { + TestThreadUtils.runOnUiThreadBlocking(() -> { + mModel.set(MicrotransactionProperties.PAYMENT_APP_NAME_ALPHA, 1f); + showEmphasizedStatus(R.string.payment_complete_message, null, + R.drawable.ic_done_googblue_36dp, R.color.microtransaction_emphasis_tint); + }); + mRenderTestRule.render(mLayout, "fingerprint_success_expanded"); + } + + private void showEmphasizedStatus(@Nullable Integer messageResourceId, + @Nullable CharSequence message, @Nullable Integer iconResourceId, + @Nullable Integer iconTint) { + mModel.set(MicrotransactionProperties.IS_SHOWING_PAY_BUTTON, false); + mModel.set(MicrotransactionProperties.STATUS_TEXT, message); + mModel.set(MicrotransactionProperties.STATUS_TEXT_RESOURCE, messageResourceId); + mModel.set(MicrotransactionProperties.IS_STATUS_EMPHASIZED, true); + mModel.set(MicrotransactionProperties.STATUS_ICON, iconResourceId); + mModel.set(MicrotransactionProperties.STATUS_ICON_TINT, iconTint); + mModel.set(MicrotransactionProperties.IS_SHOWING_PROCESSING_SPINNER, false); + } +}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferencesTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferencesTest.java index d14af979..9e548ed 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferencesTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferencesTest.java
@@ -37,8 +37,6 @@ import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.nullValue; import static org.hamcrest.Matchers.sameInstance; -import static org.mockito.Mockito.timeout; -import static org.mockito.Mockito.verify; import static org.chromium.chrome.test.util.ViewUtils.VIEW_GONE; import static org.chromium.chrome.test.util.ViewUtils.VIEW_INVISIBLE; @@ -76,19 +74,17 @@ import org.hamcrest.Matcher; import org.junit.After; import org.junit.Assert; +import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; import org.chromium.base.Callback; import org.chromium.base.CollectionUtil; import org.chromium.base.IntStringCallback; import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.ScalableTimeout; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.history.HistoryActivity; @@ -105,7 +101,6 @@ import org.chromium.chrome.test.util.browser.Features; import org.chromium.components.signin.ChromeSigninController; import org.chromium.components.sync.ModelType; -import org.chromium.content_public.browser.test.util.CriteriaHelper; import org.chromium.content_public.browser.test.util.TestThreadUtils; import java.io.File; @@ -124,9 +119,6 @@ @RunWith(BaseJUnit4ClassRunner.class) public class SavePasswordsPreferencesTest { private static final long UI_UPDATING_TIMEOUT_MS = 3000; - @Mock - private PasswordEditingDelegate mMockPasswordEditingDelegate; - @Rule public final ChromeBrowserTestRule mBrowserTestRule = new ChromeBrowserTestRule(); @@ -233,15 +225,6 @@ @Override public void showPasswordEntryEditingView(Context context, int index) { mLastEntryIndex = index; - Bundle fragmentArgs = new Bundle(); - fragmentArgs.putString( - PasswordEntryEditor.CREDENTIAL_URL, getSavedPasswordEntry(index).getUrl()); - fragmentArgs.putString(PasswordEntryEditor.CREDENTIAL_NAME, - getSavedPasswordEntry(index).getUserName()); - fragmentArgs.putString(PasswordEntryEditor.CREDENTIAL_PASSWORD, - getSavedPasswordEntry(index).getPassword()); - PreferencesLauncher.launchSettingsPage( - context, PasswordEntryEditor.class, fragmentArgs); } } @@ -273,10 +256,6 @@ */ private final ManualCallbackDelayer mManualDelayer = new ManualCallbackDelayer(); - public SavePasswordsPreferencesTest() { - MockitoAnnotations.initMocks(this); - } - private void overrideProfileSyncService( final boolean usingPassphrase, final boolean syncingPasswords) { TestThreadUtils.runOnUiThreadBlocking(() -> { @@ -744,8 +723,6 @@ @Features.EnableFeatures(ChromeFeatureList.PASSWORD_EDITING_ANDROID) public void testSelectedStoredPasswordIndexIsSameAsInShowPasswordEntryEditingView() throws Exception { - PasswordEditingDelegateProvider.getInstance().setPasswordEditingDelegate( - mMockPasswordEditingDelegate); setPasswordSourceWithMultipleEntries( // Initialize preferences new SavedPasswordEntry[] {new SavedPasswordEntry("https://example.com", "example user", "example password"), @@ -769,8 +746,6 @@ @Feature({"Preferences"}) @Features.EnableFeatures(ChromeFeatureList.PASSWORD_EDITING_ANDROID) public void testPasswordDataDisplayedInEditingActivity() throws Exception { - PasswordEditingDelegateProvider.getInstance().setPasswordEditingDelegate( - mMockPasswordEditingDelegate); Bundle fragmentArgs = new Bundle(); fragmentArgs.putString(PasswordEntryEditor.CREDENTIAL_URL, "https://example.com"); fragmentArgs.putString(PasswordEntryEditor.CREDENTIAL_NAME, "test user"); @@ -784,16 +759,17 @@ } /** - * Check that the password editing method from the PasswordEditingDelegate was called when the - * save button in the password editing activity was clicked. + * Check that the changes of password data in the password editing activity are preserved and + * shown in the password viewing activity and in the list of passwords after the save button + * was clicked. */ + // TODO(izuzic): Remove @Ignore when saving of changes is enabled again. + @Ignore("The test is ignored because saving the changes of credentials is currently disabled.") @Test @SmallTest @Feature({"Preferences"}) @Features.EnableFeatures(ChromeFeatureList.PASSWORD_EDITING_ANDROID) - public void testPasswordEditingMethodWasCalled() throws Exception { - PasswordEditingDelegateProvider.getInstance().setPasswordEditingDelegate( - mMockPasswordEditingDelegate); + public void testChangeOfStoredPasswordDataIsPreserved() throws Exception { setPasswordSource(new SavedPasswordEntry("https://example.com", "test user", "password")); PreferencesTest.startPreferences(InstrumentationRegistry.getInstrumentation(), @@ -807,38 +783,6 @@ Espresso.onView(withSaveMenuIdOrText()).perform(click()); - verify(mMockPasswordEditingDelegate).editSavedPasswordEntry("test user new", "password"); - - // Verify that the delegate was destroyed when the password editing activity finished. - waitForEvent().destroy(); - } - - /** - * Check that the changes of password data are shown in the password viewing activity and in the - * list of passwords after the save button was clicked. - */ - @Test - @SmallTest - @Feature({"Preferences"}) - @Features.EnableFeatures(ChromeFeatureList.PASSWORD_EDITING_ANDROID) - public void testChangeOfStoredPasswordDataIsPropagated() throws Exception { - PasswordEditingDelegateProvider.getInstance().setPasswordEditingDelegate( - mMockPasswordEditingDelegate); - setPasswordSource(new SavedPasswordEntry("https://example.com", "test user", "password")); - - PreferencesTest.startPreferences(InstrumentationRegistry.getInstrumentation(), - SavePasswordsPreferences.class.getName()); - - Espresso.onView(withText(containsString("test user"))).perform(click()); - - Espresso.onView(withEditMenuIdOrText()).perform(click()); - - // Performing a change of saved credentials. - mHandler.mSavedPasswords.set( - 0, new SavedPasswordEntry("https://example.com", "test user new", "password")); - - Espresso.onView(withSaveMenuIdOrText()).perform(click()); - // Check if the password viewing activity has the updated data. Espresso.onView(withText("test user new")).check(matches(isDisplayed())); @@ -856,8 +800,6 @@ @Feature({"Preferences"}) @Features.EnableFeatures(ChromeFeatureList.PASSWORD_EDITING_ANDROID) public void testStoredPasswordCanBeUnmaskedAndMaskedAgain() throws Exception { - PasswordEditingDelegateProvider.getInstance().setPasswordEditingDelegate( - mMockPasswordEditingDelegate); Bundle fragmentArgs = new Bundle(); fragmentArgs.putString(SavePasswordsPreferences.PASSWORD_LIST_NAME, "test user"); fragmentArgs.putString(SavePasswordsPreferences.PASSWORD_LIST_URL, "https://example.com"); @@ -2195,9 +2137,4 @@ allOf(withId(R.id.search_src_text), withText("Zeu")))); Espresso.onView(withId(R.id.search_src_text)).check(matches(withText("Zeu"))); } - - PasswordEditingDelegate waitForEvent() { - return verify(mMockPasswordEditingDelegate, - timeout(ScalableTimeout.scaleTimeout(CriteriaHelper.DEFAULT_MAX_TIME_TO_POLL))); - } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncTestRule.java b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncTestRule.java index f66174ab..2ac73ae 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncTestRule.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/SyncTestRule.java
@@ -186,12 +186,7 @@ final Semaphore s = new Semaphore(0); TestThreadUtils.runOnUiThreadBlocking(() -> { IdentityServicesProvider.getSigninManager().signOut( - SignoutReason.SIGNOUT_TEST, new Runnable() { - @Override - public void run() { - s.release(); - } - }); + SignoutReason.SIGNOUT_TEST, s::release, false); }); Assert.assertTrue(s.tryAcquire(SyncTestUtil.TIMEOUT_MS, TimeUnit.MILLISECONDS)); Assert.assertNull(SigninTestUtil.getCurrentAccount());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tasks/ReturnToChromeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tasks/ReturnToChromeTest.java index 99436c2..1b2d259 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/tasks/ReturnToChromeTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tasks/ReturnToChromeTest.java
@@ -4,11 +4,11 @@ package org.chromium.chrome.browser.tasks; -import static org.junit.Assert.assertEquals; - import static org.chromium.chrome.browser.tasks.ReturnToChromeExperimentsUtil.TAB_SWITCHER_ON_RETURN_MS; import android.app.Activity; +import android.content.Context; +import android.os.SystemClock; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; @@ -22,20 +22,13 @@ import org.chromium.base.ApplicationStatus; import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.Restriction; import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.browser.ChromeTabbedActivity; -import org.chromium.chrome.browser.util.FeatureUtilities; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; -import org.chromium.chrome.test.util.MenuUtils; -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.TestThreadUtils; -import org.chromium.net.test.EmbeddedTestServer; -import org.chromium.ui.test.util.UiRestriction; import java.util.concurrent.TimeoutException; @@ -44,7 +37,6 @@ * has passed. */ @RunWith(ChromeJUnit4ClassRunner.class) -@Restriction(UiRestriction.RESTRICTION_TYPE_PHONE) public class ReturnToChromeTest { @Rule public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule(); @@ -53,12 +45,10 @@ @Before public void setUp() throws Exception { - FeatureUtilities.setGridTabSwitcherEnabledForTesting(true); + Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); mActivityTestRule.startMainActivityFromLauncher(); mActivity = mActivityTestRule.getActivity(); - - setupTabs(); } /** @@ -74,7 +64,7 @@ "force-fieldtrial-params=FakeStudyName.Enabled:" + TAB_SWITCHER_ON_RETURN_MS + "/100000"}) public void - testTabSwitcherModeNotTriggeredWithinThreshold() throws Exception { + testObserverModeNotTriggeredWithoutDelay() throws Exception { finishActivityCompletely(); mActivityTestRule.startMainActivityFromLauncher(); @@ -83,51 +73,25 @@ Assert.assertFalse(mActivity.getLayoutManager().overviewVisible()); } - /** - * Test that overview mode is triggered if the delay is shorter than the interval between - * stop and start. - */ @Test @SmallTest @Feature({"ReturnToChrome"}) + @DisabledTest(message = "crbug.com/955436") @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE, "enable-features=" + ChromeFeatureList.TAB_SWITCHER_ON_RETURN + "<FakeStudyName", "force-fieldtrials=FakeStudyName/Enabled", - "force-fieldtrial-params=FakeStudyName.Enabled:" + TAB_SWITCHER_ON_RETURN_MS + "/0"}) + "force-fieldtrial-params=FakeStudyName.Enabled:" + TAB_SWITCHER_ON_RETURN_MS + "/1"}) public void - testTabSwitcherModeTriggeredBeyondThreshold() throws Exception { + testObserverModeTriggeredWithDelay() throws Exception { finishActivityCompletely(); + // Sleep past the timeout. + SystemClock.sleep(30); + mActivityTestRule.startMainActivityFromLauncher(); mActivity = mActivityTestRule.getActivity(); Assert.assertTrue(mActivity.getLayoutManager().overviewVisible()); - - CriteriaHelper.pollUiThread(Criteria.equals(true, - mActivityTestRule.getActivity() - .getTabModelSelector() - .getTabModelFilterProvider() - .getCurrentTabModelFilter()::isTabModelRestored)); - - assertEquals(2, mActivityTestRule.getActivity().getTabModelSelector().getTotalTabCount()); - } - - private void setupTabs() throws InterruptedException { - TestThreadUtils.runOnUiThreadBlocking( - () -> mActivityTestRule.getActivity().getTabModelSelector().closeAllTabs()); - EmbeddedTestServer testServer = - EmbeddedTestServer.createAndStartServer(InstrumentationRegistry.getContext()); - final String url = testServer.getURL("/chrome/test/data/android/navigate/simple.html"); - - // Add 2 tabs. - MenuUtils.invokeCustomMenuActionSync(InstrumentationRegistry.getInstrumentation(), - mActivity, org.chromium.chrome.R.id.new_tab_menu_id); - mActivityTestRule.loadUrl(url); - MenuUtils.invokeCustomMenuActionSync(InstrumentationRegistry.getInstrumentation(), - mActivity, org.chromium.chrome.R.id.new_tab_menu_id); - mActivityTestRule.loadUrl(url); - - assertEquals(2, mActivity.getTabModelSelector().getTotalTabCount()); } private void finishActivityCompletely() throws InterruptedException, TimeoutException {
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/background_sync/BackgroundSyncGooglePlayServicesCheckerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/background_sync/BackgroundSyncGooglePlayServicesCheckerTest.java new file mode 100644 index 0000000..80572be --- /dev/null +++ b/chrome/android/junit/src/org/chromium/chrome/browser/background_sync/BackgroundSyncGooglePlayServicesCheckerTest.java
@@ -0,0 +1,46 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.background_sync; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import com.google.android.gms.common.ConnectionResult; +import com.google.android.gms.common.GoogleApiAvailability; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; +import org.robolectric.shadows.gms.Shadows; +import org.robolectric.shadows.gms.common.ShadowGoogleApiAvailability; + +import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.base.test.util.Feature; +import org.chromium.chrome.test.support.DisableHistogramsRule; + +/** Unit tests for GooglePlayServicesChecker. */ +@RunWith(BaseRobolectricTestRunner.class) +@Config(manifest = Config.NONE, shadows = {ShadowGoogleApiAvailability.class}) +public class BackgroundSyncGooglePlayServicesCheckerTest { + @Rule + public DisableHistogramsRule mDisableHistogramsRule = new DisableHistogramsRule(); + + @Test + @Feature("BackgroundSync") + public void testDisableLogicWhenGooglePlayServicesReturnsSuccess() { + Shadows.shadowOf(GoogleApiAvailability.getInstance()) + .setIsGooglePlayServicesAvailable(ConnectionResult.SUCCESS); + assertFalse(GooglePlayServicesChecker.shouldDisableBackgroundSync()); + } + + @Test + @Feature("BackgroundSync") + public void testDisableLogicWhenGooglePlayServicesReturnsError() { + Shadows.shadowOf(GoogleApiAvailability.getInstance()) + .setIsGooglePlayServicesAvailable(ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED); + assertTrue(GooglePlayServicesChecker.shouldDisableBackgroundSync()); + } +}
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/feed/NtpStreamLifecycleManagerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/feed/NtpStreamLifecycleManagerTest.java index f79c735..937bd8f 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/feed/NtpStreamLifecycleManagerTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/feed/NtpStreamLifecycleManagerTest.java
@@ -120,12 +120,6 @@ // Verify that onHide is called after tab is hidden. mNtpStreamLifecycleManager.getTabObserverForTesting().onHidden(mTab, CHANGED_TABS); verify(mStream, times(1)).onHide(); - - // Verify that onShow is called when articles are set hidden by the user within the same - // session. - when(mPrefServiceBridge.getBoolean(Pref.NTP_ARTICLES_LIST_VISIBLE)).thenReturn(false); - mNtpStreamLifecycleManager.getTabObserverForTesting().onShown(mTab, FROM_NEW); - verify(mStream, times(2)).onShow(); } @Test
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninManagerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninManagerTest.java index c0499d14..3e04124 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninManagerTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/signin/SigninManagerTest.java
@@ -146,7 +146,7 @@ doReturn(null).when(mNativeMock).getManagementDomain(anyLong()); // Trigger the sign out flow - mSigninManager.signOut(SignoutReason.SIGNOUT_TEST, null, null, true); + mSigninManager.signOut(SignoutReason.SIGNOUT_TEST, null, true); // PrimaryAccountCleared should be called *before* clearing any account data. // http://crbug.com/589028 @@ -200,7 +200,7 @@ mSigninManager.runAfterOperationInProgress(callCount::incrementAndGet); assertEquals(0, callCount.get()); - mSigninManager.onProfileDataWiped(); + mSigninManager.finishSignOut(); assertFalse(mSigninManager.isOperationInProgress()); assertEquals(1, callCount.get()); }
diff --git a/chrome/app/chromium_strings.grd b/chrome/app/chromium_strings.grd index eaee8343..7b0aac0e 100644 --- a/chrome/app/chromium_strings.grd +++ b/chrome/app/chromium_strings.grd
@@ -1137,10 +1137,10 @@ Please wait while Chromium installs the latest system updates. </message> <message name="IDS_CHECKING_FOR_UPDATE_MSG" desc="Chrome OS OOBE: message shown during checking for update stage."> - Chromium updates automatically so you always have the freshest version. + Future versions of Chromium will install automatically. </message> <message name="IDS_UPDATE_MSG" desc="Chrome OS OOBE: message shown during update stage."> - Chromium updates automatically so you always have the freshest version. When this download completes, Chromium will restart and you'll be on your way. + Future versions of Chromium will install automatically. When this download completes, Chromium will restart and you'll be on your way. </message> <message name="IDS_EULA_SCREEN_ACCESSIBLE_TITLE" desc="Title to be spoken on opening the OOBE EULA screen"> Chromium OS terms
diff --git a/chrome/app/google_chrome_strings.grd b/chrome/app/google_chrome_strings.grd index e6eb76f..e86e35e 100644 --- a/chrome/app/google_chrome_strings.grd +++ b/chrome/app/google_chrome_strings.grd
@@ -1156,10 +1156,10 @@ Please wait while Chrome installs the latest system updates. </message> <message name="IDS_CHECKING_FOR_UPDATE_MSG" desc="Chrome OS OOBE: message shown during checking for update stage."> - Chrome updates automatically so you always have the freshest version. + Future versions of Chrome will install automatically. </message> <message name="IDS_UPDATE_MSG" desc="Chrome OS OOBE: message shown during update stage."> - Chrome updates automatically so you always have the freshest version. When this download completes, Chrome will restart and you'll be on your way. + Future versions of Chrome will install automatically. When this download completes, Chrome will restart and you'll be on your way. </message> <message name="IDS_EULA_SCREEN_ACCESSIBLE_TITLE" desc="Title to be spoken on opening the OOBE EULA screen"> Chrome OS terms
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index a4bbd33..1bfb5916 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -2961,6 +2961,8 @@ "apps/app_service/app_icon_source.h", "apps/app_service/app_launch_params.cc", "apps/app_service/app_launch_params.h", + "apps/app_service/app_service_metrics.cc", + "apps/app_service/app_service_metrics.h", "apps/app_service/app_service_proxy.cc", "apps/app_service/app_service_proxy.h", "apps/app_service/app_service_proxy_factory.cc",
diff --git a/chrome/browser/apps/app_service/app_service_metrics.cc b/chrome/browser/apps/app_service/app_service_metrics.cc new file mode 100644 index 0000000..53d117d6 --- /dev/null +++ b/chrome/browser/apps/app_service/app_service_metrics.cc
@@ -0,0 +1,70 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/apps/app_service/app_service_metrics.h" + +#include "base/metrics/histogram_macros.h" +#include "chrome/browser/chromeos/extensions/default_web_app_ids.h" +#include "chrome/browser/chromeos/file_manager/app_id.h" +#include "chrome/common/extensions/extension_constants.h" +#include "chrome/services/app_service/public/mojom/app_service.mojom.h" +#include "extensions/common/constants.h" + +namespace apps { + +void RecordDefaultAppLaunch(DefaultAppName default_app_name, + apps::mojom::LaunchSource launch_source) { + switch (launch_source) { + case apps::mojom::LaunchSource::kUnknown: + case apps::mojom::LaunchSource::kFromParentalControls: + return; + case apps::mojom::LaunchSource::kFromAppListGrid: + UMA_HISTOGRAM_ENUMERATION("Apps.DefaultAppLaunch.FromAppListGrid", + default_app_name); + break; + case apps::mojom::LaunchSource::kFromAppListGridContextMenu: + UMA_HISTOGRAM_ENUMERATION( + "Apps.DefaultAppLaunch.FromAppListGridContextMenu", default_app_name); + break; + case apps::mojom::LaunchSource::kFromAppListQuery: + UMA_HISTOGRAM_ENUMERATION("Apps.DefaultAppLaunch.FromAppListQuery", + default_app_name); + break; + case apps::mojom::LaunchSource::kFromAppListQueryContextMenu: + UMA_HISTOGRAM_ENUMERATION( + "Apps.DefaultAppLaunch.FromAppListQueryContextMenu", + default_app_name); + break; + case apps::mojom::LaunchSource::kFromAppListRecommendation: + UMA_HISTOGRAM_ENUMERATION( + "Apps.DefaultAppLaunch.FromAppListRecommendation", default_app_name); + break; + case apps::mojom::LaunchSource::kFromShelf: + UMA_HISTOGRAM_ENUMERATION("Apps.DefaultAppLaunch.FromShelf", + default_app_name); + break; + } +} + +void RecordAppLaunch(const std::string& app_id, + apps::mojom::LaunchSource launch_source) { + if (app_id == extension_misc::kCalculatorAppId) + RecordDefaultAppLaunch(DefaultAppName::kCalculator, launch_source); + else if (app_id == extension_misc::kTextEditorAppId) + RecordDefaultAppLaunch(DefaultAppName::kText, launch_source); + else if (app_id == extension_misc::kGeniusAppId) + RecordDefaultAppLaunch(DefaultAppName::kGetHelp, launch_source); + else if (app_id == file_manager::kGalleryAppId) + RecordDefaultAppLaunch(DefaultAppName::kGallery, launch_source); + else if (app_id == file_manager::kVideoPlayerAppId) + RecordDefaultAppLaunch(DefaultAppName::kVideoPlayer, launch_source); + else if (app_id == file_manager::kAudioPlayerAppId) + RecordDefaultAppLaunch(DefaultAppName::kAudioPlayer, launch_source); + else if (app_id == chromeos::default_web_apps::kCanvasAppId) + RecordDefaultAppLaunch(DefaultAppName::kChromeCanvas, launch_source); + else if (app_id == extension_misc::kCameraAppId) + RecordDefaultAppLaunch(DefaultAppName::kCamera, launch_source); +} + +} // namespace apps
diff --git a/chrome/browser/apps/app_service/app_service_metrics.h b/chrome/browser/apps/app_service/app_service_metrics.h new file mode 100644 index 0000000..40286a4 --- /dev/null +++ b/chrome/browser/apps/app_service/app_service_metrics.h
@@ -0,0 +1,39 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_APPS_APP_SERVICE_APP_SERVICE_METRICS_H_ +#define CHROME_BROWSER_APPS_APP_SERVICE_APP_SERVICE_METRICS_H_ + +#include <map> +#include <string> + +#include "chrome/services/app_service/public/mojom/types.mojom.h" + +namespace apps { + +// The app's histogram name. This is used for logging so do not change the +// order of this enum. +enum class DefaultAppName { + kCalculator = 0, + kText = 1, + kGetHelp = 2, + kGallery = 3, + kVideoPlayer = 4, + kAudioPlayer = 5, + kChromeCanvas = 6, + kCamera = 7, + // Add any new values above this one, and update kMaxValue to the highest + // enumerator value. + kMaxValue = kCamera, +}; + +void RecordDefaultAppLaunch(DefaultAppName default_app_name, + apps::mojom::LaunchSource launch_source); + +void RecordAppLaunch(const std::string& app_id, + apps::mojom::LaunchSource launch_source); + +} // namespace apps + +#endif // CHROME_BROWSER_APPS_APP_SERVICE_APP_SERVICE_METRICS_H_
diff --git a/chrome/browser/apps/app_service/app_service_proxy.cc b/chrome/browser/apps/app_service/app_service_proxy.cc index 7035c23..43998aa 100644 --- a/chrome/browser/apps/app_service/app_service_proxy.cc +++ b/chrome/browser/apps/app_service/app_service_proxy.cc
@@ -10,6 +10,7 @@ #include "base/location.h" #include "base/threading/thread_task_runner_handle.h" #include "chrome/browser/apps/app_service/app_icon_source.h" +#include "chrome/browser/apps/app_service/app_service_metrics.h" #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/services/app_service/public/mojom/constants.mojom.h" @@ -167,6 +168,7 @@ if (app_service_.is_bound()) { cache_.ForOneApp(app_id, [this, event_flags, launch_source, display_id](const apps::AppUpdate& update) { + RecordAppLaunch(update.AppId(), launch_source); app_service_->Launch(update.AppType(), update.AppId(), event_flags, launch_source, display_id); });
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc index 613647d8..33a17d7 100644 --- a/chrome/browser/chrome_browser_main.cc +++ b/chrome/browser/chrome_browser_main.cc
@@ -26,7 +26,7 @@ #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/memory/scoped_refptr.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_loop_current.h" #include "base/metrics/field_trial.h" #include "base/metrics/histogram_macros.h" #include "base/path_service.h"
diff --git a/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service.cc b/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service.cc index 64ab502a..8593cc0 100644 --- a/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service.cc +++ b/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service.cc
@@ -358,9 +358,14 @@ using chromeos::input_method::InputMethodDescriptors; using chromeos::input_method::InputMethodManager; + InputMethodManager* imm = InputMethodManager::Get(); + if (!imm || !imm->GetActiveIMEState()) { + LOG(WARNING) << "InputMethodManager is not ready yet."; + return; + } + base::AutoReset<bool> in_updating(&is_updating_imm_entry_, true); - scoped_refptr<InputMethodManager::State> state = - InputMethodManager::Get()->GetActiveIMEState(); + scoped_refptr<InputMethodManager::State> state = imm->GetActiveIMEState(); const std::string active_ime_id = state->GetCurrentInputMethod().id(); // Remove the old registered entry.
diff --git a/chrome/browser/chromeos/backdrop_wallpaper_handlers/backdrop_wallpaper_handlers.cc b/chrome/browser/chromeos/backdrop_wallpaper_handlers/backdrop_wallpaper_handlers.cc index fee1e26..be8962d 100644 --- a/chrome/browser/chromeos/backdrop_wallpaper_handlers/backdrop_wallpaper_handlers.cc +++ b/chrome/browser/chromeos/backdrop_wallpaper_handlers/backdrop_wallpaper_handlers.cc
@@ -306,8 +306,8 @@ "Backdrop wallpaper service." trigger: "When ChromeOS Wallpaper Picker extension is open, " - "GOOGLE_CHROME_BUILD is defined and user turns on the surprise me " - "feature." + "BUILDFLAG(GOOGLE_CHROME_BRANDING) is defined and user turns on " + "the surprise me feature." data: "The Backdrop protocol buffer messages. No user data is included." destination: GOOGLE_OWNED_SERVICE
diff --git a/chrome/browser/chromeos/login/demo_mode/demo_mode_test_helper.cc b/chrome/browser/chromeos/login/demo_mode/demo_mode_test_helper.cc index 89dbe77..f2493ef 100644 --- a/chrome/browser/chromeos/login/demo_mode/demo_mode_test_helper.cc +++ b/chrome/browser/chromeos/login/demo_mode/demo_mode_test_helper.cc
@@ -10,6 +10,7 @@ #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/logging.h" +#include "base/run_loop.h" #include "base/test/scoped_path_override.h" #include "chrome/browser/browser_process_platform_part.h" #include "chrome/browser/chromeos/login/demo_mode/demo_resources.h"
diff --git a/chrome/browser/chromeos/login/lock/screen_locker.cc b/chrome/browser/chromeos/login/lock/screen_locker.cc index 8e85530e..bab0c73 100644 --- a/chrome/browser/chromeos/login/lock/screen_locker.cc +++ b/chrome/browser/chromeos/login/lock/screen_locker.cc
@@ -15,7 +15,7 @@ #include "base/location.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_loop_current.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/user_metrics.h" #include "base/single_thread_task_runner.h"
diff --git a/chrome/browser/chromeos/login/login_ui_keyboard_browsertest.cc b/chrome/browser/chromeos/login/login_ui_keyboard_browsertest.cc index 1580773..3af9d62 100644 --- a/chrome/browser/chromeos/login/login_ui_keyboard_browsertest.cc +++ b/chrome/browser/chromeos/login/login_ui_keyboard_browsertest.cc
@@ -6,7 +6,7 @@ #include "base/bind.h" #include "base/command_line.h" #include "base/location.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_loop_current.h" #include "base/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" #include "chrome/browser/browser_process.h"
diff --git a/chrome/browser/chromeos/login/wizard_controller.cc b/chrome/browser/chromeos/login/wizard_controller.cc index d54f43a..e00d22d 100644 --- a/chrome/browser/chromeos/login/wizard_controller.cc +++ b/chrome/browser/chromeos/login/wizard_controller.cc
@@ -1341,6 +1341,10 @@ if (!GetOobeUI()) return; + // Check for tests configuration. + if (StartupUtils::IsEulaAccepted() || StartupUtils::IsOobeCompleted()) + return; + const auto* skip_screen_key = oobe_configuration_.FindKeyOfType( configuration::kSkipHIDDetection, base::Value::Type::BOOLEAN); const bool skip_screen = skip_screen_key && skip_screen_key->GetBool();
diff --git a/chrome/browser/defaults.cc b/chrome/browser/defaults.cc index be70bcf..179fcfd 100644 --- a/chrome/browser/defaults.cc +++ b/chrome/browser/defaults.cc
@@ -2,9 +2,11 @@ // 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 "chrome/browser/defaults.h" +#include "build/branding_buildflags.h" +#include "build/build_config.h" + namespace browser_defaults { #if defined(OS_CHROMEOS) || defined(OS_MACOSX) @@ -27,7 +29,7 @@ const bool kAlwaysCreateTabbedBrowserOnSessionRestore = true; #endif -#if defined(GOOGLE_CHROME_BUILD) +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) #if defined(OS_CHROMEOS) const bool kShowHelpMenuItemIcon = true; #else
diff --git a/chrome/browser/extensions/chrome_extensions_interface_registration.cc b/chrome/browser/extensions/chrome_extensions_interface_registration.cc index 225be8a..b334d2e0 100644 --- a/chrome/browser/extensions/chrome_extensions_interface_registration.cc +++ b/chrome/browser/extensions/chrome_extensions_interface_registration.cc
@@ -143,7 +143,7 @@ extension->permissions_data()->HasAPIPermission( APIPermission::kMediaRouterPrivate)) { registry->AddInterface( - base::Bind(&media_router::MediaRouterDesktop::BindToRequest, + base::Bind(&media_router::MediaRouterDesktop::BindToReceiver, base::RetainedRef(extension), context)); }
diff --git a/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc b/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc index ab59df1..14289ab0 100644 --- a/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc +++ b/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc
@@ -6,13 +6,19 @@ #include <memory> #include <string> +#include <utility> #include <vector> #include "base/bind.h" #include "base/json/json_string_value_serializer.h" +#include "base/logging.h" +#include "base/path_service.h" +#include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" #include "base/system/sys_info.h" #include "base/task/post_task.h" +#include "build/branding_buildflags.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/data_reduction_proxy/data_reduction_proxy_chrome_settings.h" @@ -45,6 +51,9 @@ #if defined(OS_WIN) #include "base/win/win_util.h" +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) +#include "chrome/browser/google/google_update_win.h" +#endif #include "ui/base/win/hidden_window.h" #endif @@ -74,6 +83,12 @@ constexpr char kUsbKeyboardDetected[] = "usb_keyboard_detected"; constexpr char kIsEnrolledToDomain[] = "enrolled_to_domain"; constexpr char kInstallerBrandCode[] = "installer_brand_code"; +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) +constexpr char kUpdateErrorCode[] = "update_error_code"; +constexpr char kUpdateHresult[] = "update_hresult"; +constexpr char kInstallResultCode[] = "install_result_code"; +constexpr char kInstallLocation[] = "install_location"; +#endif #endif #if defined(OS_CHROMEOS) @@ -192,6 +207,38 @@ } #endif // defined(OS_CHROMEOS) +#if defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) +// Returns true if the path identified by |key| with the PathService is a parent +// or ancestor of |child|. +bool IsParentOf(int key, const base::FilePath& child) { + base::FilePath path; + return base::PathService::Get(key, &path) && path.IsParent(child); +} + +// Returns a string representing the overall install location of the browser. +// "Program Files" and "Program Files (x86)" are both considered "per-machine" +// locations (for all users), whereas anything in a user's local app data dir is +// considered a "per-user" location. This function returns an answer that gives, +// in essence, the broad category of location without checking that the browser +// is operating out of the exact expected install directory. It is interesting +// to know via feedback reports if updates are failing with +// CANNOT_UPGRADE_CHROME_IN_THIS_DIRECTORY, which checks the exact directory, +// yet the reported install_location is not "unknown". +std::string DetermineInstallLocation() { + base::FilePath exe_path; + + if (base::PathService::Get(base::FILE_EXE, &exe_path)) { + if (IsParentOf(base::DIR_PROGRAM_FILESX86, exe_path) || + IsParentOf(base::DIR_PROGRAM_FILES, exe_path)) { + return "per-machine"; + } + if (IsParentOf(base::DIR_LOCAL_APP_DATA, exe_path)) + return "per-user"; + } + return "unknown"; +} +#endif // defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) + } // namespace ChromeInternalLogSource::ChromeInternalLogSource() @@ -230,6 +277,7 @@ PopulateUsbKeyboardDetected(response.get()); PopulateEnrolledToDomain(response.get()); PopulateInstallerBrandCode(response.get()); + PopulateLastUpdateState(response.get()); #endif if (ProfileManager::GetLastUsedProfile()->IsChild()) @@ -410,6 +458,29 @@ response->emplace(kInstallerBrandCode, brand.empty() ? "Unknown brand code" : brand); } -#endif + +void ChromeInternalLogSource::PopulateLastUpdateState( + SystemLogsResponse* response) { +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) + const base::Optional<UpdateState> update_state = GetLastUpdateState(); + if (!update_state) + return; // There is nothing to include if no update check has completed. + + response->emplace(kUpdateErrorCode, + base::NumberToString(update_state->error_code)); + response->emplace(kInstallLocation, DetermineInstallLocation()); + + if (update_state->error_code == GOOGLE_UPDATE_NO_ERROR) + return; // There is nothing more to include if the last check succeeded. + + response->emplace(kUpdateHresult, + base::StringPrintf("0x%08lX", update_state->hresult)); + if (update_state->installer_exit_code) { + response->emplace(kInstallResultCode, + base::NumberToString(*update_state->installer_exit_code)); + } +#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING) +} +#endif // defined(OS_WIN) } // namespace system_logs
diff --git a/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.h b/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.h index 5f74d5a..79681f1 100644 --- a/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.h +++ b/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.h
@@ -38,6 +38,7 @@ void PopulateUsbKeyboardDetected(SystemLogsResponse* response); void PopulateEnrolledToDomain(SystemLogsResponse* response); void PopulateInstallerBrandCode(SystemLogsResponse* response); + void PopulateLastUpdateState(SystemLogsResponse* response); #endif #if defined(OS_CHROMEOS)
diff --git a/chrome/browser/google/google_update_win.cc b/chrome/browser/google/google_update_win.cc index 9c44a72..756024b 100644 --- a/chrome/browser/google/google_update_win.cc +++ b/chrome/browser/google/google_update_win.cc
@@ -8,7 +8,6 @@ #include <stdint.h> #include <string.h> -#include <string> #include <utility> #include <vector> @@ -18,11 +17,13 @@ #include "base/location.h" #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" +#include "base/no_destructor.h" #include "base/path_service.h" #include "base/sequenced_task_runner.h" #include "base/sequenced_task_runner_helpers.h" #include "base/single_thread_task_runner.h" #include "base/stl_util.h" +#include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" @@ -194,6 +195,12 @@ nullptr, IID_PPV_ARGS(google_update->GetAddressOf())); } +// Returns the process-wide storage for the state of the last update check. +base::Optional<UpdateState>* GetLastUpdateStateStorage() { + static base::NoDestructor<base::Optional<UpdateState>> storage; + return storage.get(); +} + // UpdateCheckDriver ----------------------------------------------------------- // A driver that is created and destroyed on the caller's thread and drives @@ -239,14 +246,15 @@ // steps that failed. HRESULT BeginUpdateCheckInternal(GoogleUpdateErrorCode* error_code); - // Sets status_ to UPGRADE_ERROR, error_code_ to |error_code|, hresult_ to - // |hresult|, installer_exit_code_ to |installer_exit_code|, and - // html_error_message_ to a composition of all values suitable for display - // to the user. This call should be followed by deletion of the driver, - // which will result in callers being notified via their delegates. + // Sets status_ to UPGRADE_ERROR, update_state_.error_code to |error_code|, + // update_state_.hresult to |hresult|, update_state_.installer_exit_code to + // |installer_exit_code|, and html_error_message_ to a composition of all + // values suitable for display to the user. This call should be followed by + // deletion of the driver, which will result in callers being notified via + // their delegates. void OnUpgradeError(GoogleUpdateErrorCode error_code, HRESULT hresult, - int installer_exit_code, + base::Optional<int> installer_exit_code, const base::string16& error_string); // Returns true if |current_state| and |state_value| can be obtained from the @@ -264,14 +272,13 @@ // https://code.google.com/p/omaha/source/browse/trunk/base/error.h). In case // Chrome's installer failed during execution, |installer_exit_code| may be // populated with its process exit code (see enum installer::InstallStatus in - // chrome/installer/util/util_constants.h); otherwise, it will be -1. - // |error_string| will be populated with a completion message if one is - // provided by Google Update. + // chrome/installer/util/util_constants.h). |error_string| will be populated + // with a completion message if one is provided by Google Update. bool IsErrorState(const Microsoft::WRL::ComPtr<ICurrentState>& current_state, CurrentState state_value, GoogleUpdateErrorCode* error_code, HRESULT* hresult, - int* installer_exit_code, + base::Optional<int>* installer_exit_code, base::string16* error_string) const; // Returns true if |current_state| and |state_value| constitute a final state @@ -349,11 +356,8 @@ // The results of the update check to be logged via UMA and/or reported to the // caller. GoogleUpdateUpgradeStatus status_; - GoogleUpdateErrorCode error_code_; + UpdateState update_state_; base::string16 html_error_message_; - base::string16 new_version_; - HRESULT hresult_; - int installer_exit_code_; DISALLOW_COPY_AND_ASSIGN(UpdateCheckDriver); }; @@ -400,25 +404,28 @@ allowed_retries_(kGoogleAllowedRetries), system_level_install_(false), last_reported_progress_(0), - status_(UPGRADE_ERROR), - error_code_(GOOGLE_UPDATE_NO_ERROR), - hresult_(S_OK), - installer_exit_code_(-1) {} + status_(UPGRADE_ERROR) {} UpdateCheckDriver::~UpdateCheckDriver() { DCHECK(result_runner_->RunsTasksInCurrentSequence()); // If there is an error, then error_code must not be blank, and vice versa. - DCHECK_NE(status_ == UPGRADE_ERROR, error_code_ == GOOGLE_UPDATE_NO_ERROR); + DCHECK_NE(status_ == UPGRADE_ERROR, + update_state_.error_code == GOOGLE_UPDATE_NO_ERROR); + + *GetLastUpdateStateStorage() = update_state_; + UMA_HISTOGRAM_ENUMERATION("GoogleUpdate.UpgradeResult", status_, NUM_UPGRADE_STATUS); if (status_ == UPGRADE_ERROR) { - UMA_HISTOGRAM_ENUMERATION("GoogleUpdate.UpdateErrorCode", error_code_, - NUM_ERROR_CODES); - if (FAILED(hresult_)) - base::UmaHistogramSparse("GoogleUpdate.ErrorHresult", hresult_); - if (installer_exit_code_ != -1) { + UMA_HISTOGRAM_ENUMERATION("GoogleUpdate.UpdateErrorCode", + update_state_.error_code, NUM_ERROR_CODES); + if (FAILED(update_state_.hresult)) { + base::UmaHistogramSparse("GoogleUpdate.ErrorHresult", + update_state_.hresult); + } + if (update_state_.installer_exit_code) { base::UmaHistogramSparse("GoogleUpdate.InstallerExitCode", - installer_exit_code_); + *update_state_.installer_exit_code); } } @@ -429,12 +436,14 @@ for (const auto& delegate : delegates_) { if (delegate) { - if (status_ == UPGRADE_ERROR) - delegate->OnError(error_code_, html_error_message_, new_version_); - else if (install_update_if_possible_) - delegate->OnUpgradeComplete(new_version_); - else - delegate->OnUpdateCheckComplete(new_version_); + if (status_ == UPGRADE_ERROR) { + delegate->OnError(update_state_.error_code, html_error_message_, + update_state_.new_version); + } else if (install_update_if_possible_) { + delegate->OnUpgradeComplete(update_state_.new_version); + } else { + delegate->OnUpdateCheckComplete(update_state_.new_version); + } } } } @@ -480,7 +489,7 @@ } DCHECK(FAILED(hresult)); - OnUpgradeError(error_code, hresult, -1, base::string16()); + OnUpgradeError(error_code, hresult, base::nullopt, base::string16()); result_runner_->DeleteSoon(FROM_HERE, this); } @@ -609,7 +618,7 @@ CurrentState state_value, GoogleUpdateErrorCode* error_code, HRESULT* hresult, - int* installer_exit_code, + base::Optional<int>* installer_exit_code, base::string16* error_string) const { if (state_value == STATE_ERROR) { // In general, errors reported by Google Update fall under this category @@ -618,7 +627,7 @@ // In general, the exit code of Chrome's installer is unknown (see special // case below). - *installer_exit_code = -1; + installer_exit_code->reset(); // Report the error_code provided by Google Update if possible, or the // reason it wasn't possible otherwise. @@ -654,7 +663,7 @@ // Report a failure to start the install as a general error while trying // to interact with Google Update. *error_code = GOOGLE_UPDATE_ONDEMAND_CLASS_REPORTED_ERROR; - *installer_exit_code = -1; + installer_exit_code->reset(); return true; } // Return false for handling in IsIntermediateState. @@ -766,30 +775,31 @@ CurrentState state_value = STATE_INIT; HRESULT hresult = S_OK; GoogleUpdateErrorCode error_code = GOOGLE_UPDATE_NO_ERROR; - int installer_exit_code = -1; + base::Optional<int> installer_exit_code; base::string16 error_string; GoogleUpdateUpgradeStatus upgrade_status = UPGRADE_ERROR; base::string16 new_version; int progress = 0; if (!GetCurrentState(&state, &state_value, &hresult)) { - OnUpgradeError(GOOGLE_UPDATE_ONDEMAND_CLASS_REPORTED_ERROR, hresult, -1, - base::string16()); + OnUpgradeError(GOOGLE_UPDATE_ONDEMAND_CLASS_REPORTED_ERROR, hresult, + base::nullopt, base::string16()); } else if (IsErrorState(state, state_value, &error_code, &hresult, &installer_exit_code, &error_string)) { OnUpgradeError(error_code, hresult, installer_exit_code, error_string); } else if (IsFinalState(state, state_value, &upgrade_status, &new_version)) { status_ = upgrade_status; - error_code_ = GOOGLE_UPDATE_NO_ERROR; + update_state_.error_code = GOOGLE_UPDATE_NO_ERROR; html_error_message_.clear(); if (!new_version.empty()) - new_version_ = new_version; - hresult_ = S_OK; - installer_exit_code_ = -1; + update_state_.new_version = new_version; + update_state_.hresult = S_OK; + update_state_.installer_exit_code.reset(); } else if (IsIntermediateState(state, state_value, &new_version, &progress)) { - bool got_new_version = new_version_.empty() && !new_version.empty(); + bool got_new_version = + update_state_.new_version.empty() && !new_version.empty(); if (got_new_version) - new_version_ = new_version; + update_state_.new_version = new_version; // Give the caller this status update if it differs from the last one given. if (got_new_version || progress != last_reported_progress_) { last_reported_progress_ = progress; @@ -797,9 +807,10 @@ // It is safe to post this task with an unretained pointer since the task // is guaranteed to run before a subsequent DeleteSoon is handled. result_runner_->PostTask( - FROM_HERE, base::BindOnce(&UpdateCheckDriver::NotifyUpgradeProgress, - base::Unretained(this), - last_reported_progress_, new_version_)); + FROM_HERE, + base::BindOnce(&UpdateCheckDriver::NotifyUpgradeProgress, + base::Unretained(this), last_reported_progress_, + update_state_.new_version)); } // Schedule the next check. @@ -824,12 +835,12 @@ void UpdateCheckDriver::OnUpgradeError(GoogleUpdateErrorCode error_code, HRESULT hresult, - int installer_exit_code, + base::Optional<int> installer_exit_code, const base::string16& error_string) { status_ = UPGRADE_ERROR; - error_code_ = error_code; - hresult_ = hresult; - installer_exit_code_ = installer_exit_code; + update_state_.error_code = error_code; + update_state_.hresult = hresult; + update_state_.installer_exit_code = installer_exit_code; // Some specific result codes have dedicated messages. if (hresult == GOOPDATE_E_APP_USING_EXTERNAL_UPDATER) { @@ -838,13 +849,14 @@ return; } - base::string16 html_error_msg = - base::StringPrintf(L"%d: <a href='%ls0x%X' target=_blank>0x%X</a>", - error_code_, base::UTF8ToUTF16( - chrome::kUpgradeHelpCenterBaseURL).c_str(), - hresult_, hresult_); - if (installer_exit_code_ != -1) - html_error_msg += base::StringPrintf(L": %d", installer_exit_code_); + base::string16 html_error_msg = base::StringPrintf( + L"%d: <a href='%ls0x%X' target=_blank>0x%X</a>", update_state_.error_code, + base::UTF8ToUTF16(chrome::kUpgradeHelpCenterBaseURL).c_str(), + update_state_.hresult, update_state_.hresult); + if (update_state_.installer_exit_code) { + html_error_msg += + L": " + base::NumberToString16(*update_state_.installer_exit_code); + } if (system_level_install_) html_error_msg += L" -- system level"; if (error_string.empty()) { @@ -870,6 +882,17 @@ elevation_window, delegate); } +// UpdateState ----------------------------------------------------------------- + +UpdateState::UpdateState() = default; +UpdateState::UpdateState(const UpdateState&) = default; +UpdateState::UpdateState(UpdateState&&) = default; +UpdateState& UpdateState::operator=(UpdateState&&) = default; +UpdateState::~UpdateState() = default; + +base::Optional<UpdateState> GetLastUpdateState() { + return *GetLastUpdateStateStorage(); +} // Private API exposed for testing. --------------------------------------------
diff --git a/chrome/browser/google/google_update_win.h b/chrome/browser/google/google_update_win.h index b66e322b..a69ac60 100644 --- a/chrome/browser/google/google_update_win.h +++ b/chrome/browser/google/google_update_win.h
@@ -7,9 +7,12 @@ #include <wrl/client.h> +#include <string> + #include "base/callback_forward.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" +#include "base/optional.h" #include "base/strings/string16.h" #include "google_update/google_update_idl.h" #include "ui/gfx/native_widget_types.h" @@ -100,6 +103,34 @@ gfx::AcceleratedWidget elevation_window, const base::WeakPtr<UpdateCheckDelegate>& delegate); +// The state from a completed update check. +struct UpdateState { + UpdateState(); + UpdateState(const UpdateState&); + UpdateState(UpdateState&&); + UpdateState& operator=(UpdateState&&); + ~UpdateState(); + + // GOOGLE_UPDATE_NO_ERROR if the last check or update succeeded; otherwise, + // the nature of the failure. + GoogleUpdateErrorCode error_code = GOOGLE_UPDATE_NO_ERROR; + + // The next version available or an empty string if either no update is + // available or an error occurred before the new version was discovered. + base::string16 new_version; + + // S_OK if the last check or update succeeded; otherwise, the failing error + // from Google Update or COM. + HRESULT hresult = S_OK; + + // If present, the process exit code from the failed run of the installer. + base::Optional<int> installer_exit_code; +}; + +// Returns the state from the most recent completed update check or no value if +// no such check has taken place. +base::Optional<UpdateState> GetLastUpdateState(); + // A type of callback supplied by tests to provide a custom IGoogleUpdate3Web // implementation (see src/google_update/google_update_idl.idl). typedef base::Callback<HRESULT(Microsoft::WRL::ComPtr<IGoogleUpdate3Web>*)>
diff --git a/chrome/browser/google/google_update_win_unittest.cc b/chrome/browser/google/google_update_win_unittest.cc index c0bed81..cd31714 100644 --- a/chrome/browser/google/google_update_win_unittest.cc +++ b/chrome/browser/google/google_update_win_unittest.cc
@@ -9,6 +9,7 @@ #include <wrl/client.h> #include <memory> +#include <string> #include "base/base_paths.h" #include "base/bind.h" @@ -684,6 +685,9 @@ BeginUpdateCheck(std::string(), false, 0, mock_update_check_delegate_.AsWeakPtr()); task_runner_->RunUntilIdle(); + ASSERT_TRUE(GetLastUpdateState()); + EXPECT_EQ(GetLastUpdateState()->error_code, + CANNOT_UPGRADE_CHROME_IN_THIS_DIRECTORY); } // Test the case where the GoogleUpdate class can't be created for an update @@ -698,6 +702,9 @@ BeginUpdateCheck(std::string(), false, 0, mock_update_check_delegate_.AsWeakPtr()); task_runner_->RunUntilIdle(); + ASSERT_TRUE(GetLastUpdateState()); + EXPECT_EQ(GetLastUpdateState()->error_code, + GOOGLE_UPDATE_ONDEMAND_CLASS_NOT_FOUND); } // Test the case where the GoogleUpdate class can't be created for an upgrade. @@ -711,6 +718,9 @@ BeginUpdateCheck(std::string(), true, 0, mock_update_check_delegate_.AsWeakPtr()); task_runner_->RunUntilIdle(); + ASSERT_TRUE(GetLastUpdateState()); + EXPECT_EQ(GetLastUpdateState()->error_code, + GOOGLE_UPDATE_ONDEMAND_CLASS_NOT_FOUND); } // Test the case where the GoogleUpdate class returns an error when an update @@ -728,6 +738,10 @@ BeginUpdateCheck(std::string(), false, 0, mock_update_check_delegate_.AsWeakPtr()); task_runner_->RunUntilIdle(); + ASSERT_TRUE(GetLastUpdateState()); + EXPECT_EQ(GetLastUpdateState()->error_code, + GOOGLE_UPDATE_ONDEMAND_CLASS_REPORTED_ERROR); + EXPECT_EQ(GetLastUpdateState()->hresult, E_FAIL); } // Test the case where the GoogleUpdate class reports that updates are disabled @@ -753,6 +767,8 @@ BeginUpdateCheck(std::string(), false, 0, mock_update_check_delegate_.AsWeakPtr()); task_runner_->RunUntilIdle(); + ASSERT_TRUE(GetLastUpdateState()); + EXPECT_EQ(GetLastUpdateState()->error_code, GOOGLE_UPDATE_DISABLED_BY_POLICY); } // Test the case where the GoogleUpdate class reports that manual updates are @@ -779,6 +795,9 @@ BeginUpdateCheck(std::string(), false, 0, mock_update_check_delegate_.AsWeakPtr()); task_runner_->RunUntilIdle(); + ASSERT_TRUE(GetLastUpdateState()); + EXPECT_EQ(GetLastUpdateState()->error_code, + GOOGLE_UPDATE_DISABLED_BY_POLICY_AUTO_ONLY); } // Test an update check where no update is available. @@ -800,6 +819,9 @@ BeginUpdateCheck(std::string(), false, 0, mock_update_check_delegate_.AsWeakPtr()); task_runner_->RunUntilIdle(); + ASSERT_TRUE(GetLastUpdateState()); + EXPECT_EQ(GetLastUpdateState()->error_code, GOOGLE_UPDATE_NO_ERROR); + EXPECT_EQ(GetLastUpdateState()->new_version, STRING16_LITERAL("")); } // Test an update check where an update is available. @@ -821,6 +843,9 @@ BeginUpdateCheck(std::string(), false, 0, mock_update_check_delegate_.AsWeakPtr()); task_runner_->RunUntilIdle(); + ASSERT_TRUE(GetLastUpdateState()); + EXPECT_EQ(GetLastUpdateState()->error_code, GOOGLE_UPDATE_NO_ERROR); + EXPECT_EQ(GetLastUpdateState()->new_version, new_version_); } // Test a successful upgrade. @@ -866,6 +891,9 @@ BeginUpdateCheck(std::string(), true, 0, mock_update_check_delegate_.AsWeakPtr()); task_runner_->RunUntilIdle(); + ASSERT_TRUE(GetLastUpdateState()); + EXPECT_EQ(GetLastUpdateState()->error_code, GOOGLE_UPDATE_NO_ERROR); + EXPECT_EQ(GetLastUpdateState()->new_version, new_version_); } // Test a failed upgrade where Google Update reports that the installer failed. @@ -917,6 +945,12 @@ BeginUpdateCheck(std::string(), true, 0, mock_update_check_delegate_.AsWeakPtr()); task_runner_->RunUntilIdle(); + ASSERT_TRUE(GetLastUpdateState()); + EXPECT_EQ(GetLastUpdateState()->error_code, GOOGLE_UPDATE_ERROR_UPDATING); + EXPECT_EQ(GetLastUpdateState()->new_version, new_version_); + EXPECT_EQ(GetLastUpdateState()->hresult, GOOPDATEINSTALL_E_INSTALLER_FAILED); + ASSERT_TRUE(GetLastUpdateState()->installer_exit_code); + EXPECT_EQ(GetLastUpdateState()->installer_exit_code.value(), kInstallerError); } // Test that a retry after a USING_EXTERNAL_UPDATER failure succeeds. @@ -958,6 +992,9 @@ BeginUpdateCheck(std::string(), false, 0, mock_update_check_delegate_.AsWeakPtr()); task_runner_->RunUntilIdle(); + ASSERT_TRUE(GetLastUpdateState()); + EXPECT_EQ(GetLastUpdateState()->error_code, GOOGLE_UPDATE_NO_ERROR); + EXPECT_EQ(GetLastUpdateState()->new_version, STRING16_LITERAL("")); } TEST_P(GoogleUpdateWinTest, UpdateInstalledMultipleDelegates) { @@ -1020,6 +1057,9 @@ BeginUpdateCheck(std::string(), true, 0, mock_update_check_delegate_2.AsWeakPtr()); task_runner_->RunUntilIdle(); + ASSERT_TRUE(GetLastUpdateState()); + EXPECT_EQ(GetLastUpdateState()->error_code, GOOGLE_UPDATE_NO_ERROR); + EXPECT_EQ(GetLastUpdateState()->new_version, new_version_); } INSTANTIATE_TEST_SUITE_P(UserLevel, GoogleUpdateWinTest, Values(false));
diff --git a/chrome/browser/importer/external_process_importer_client.cc b/chrome/browser/importer/external_process_importer_client.cc index b39cff2..5c56fb7 100644 --- a/chrome/browser/importer/external_process_importer_client.cc +++ b/chrome/browser/importer/external_process_importer_client.cc
@@ -71,10 +71,8 @@ // If the utility process hasn't started yet the message will queue until it // does. - chrome::mojom::ProfileImportObserverPtr observer; - receiver_.Bind(mojo::MakeRequest(&observer)); profile_import_->StartImport(source_profile_, items_, localized_strings, - std::move(observer)); + receiver_.BindNewPipeAndPassRemote()); } void ExternalProcessImporterClient::Cancel() {
diff --git a/chrome/browser/media/router/media_router.h b/chrome/browser/media/router/media_router.h index 8fd83c8..07f9eed 100644 --- a/chrome/browser/media/router/media_router.h +++ b/chrome/browser/media/router/media_router.h
@@ -30,6 +30,7 @@ #if !defined(OS_ANDROID) #include "chrome/common/media_router/mojom/media_controller.mojom.h" #include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #endif // !defined(OS_ANDROID) namespace content { @@ -204,7 +205,7 @@ virtual void GetMediaController( const MediaRoute::Id& route_id, mojo::PendingReceiver<mojom::MediaController> controller, - mojom::MediaStatusObserverPtr observer) = 0; + mojo::PendingRemote<mojom::MediaStatusObserver> observer) = 0; #endif // !defined(OS_ANDROID) // Registers/Unregisters a CastRemotingConnector with the |tab_id|. For a
diff --git a/chrome/browser/media/router/media_router_base.cc b/chrome/browser/media/router/media_router_base.cc index a8d599d..24d66af2 100644 --- a/chrome/browser/media/router/media_router_base.cc +++ b/chrome/browser/media/router/media_router_base.cc
@@ -92,7 +92,7 @@ void MediaRouterBase::GetMediaController( const MediaRoute::Id& route_id, mojo::PendingReceiver<mojom::MediaController> controller, - mojom::MediaStatusObserverPtr observer) {} + mojo::PendingRemote<mojom::MediaStatusObserver> observer) {} #endif // !defined(OS_ANDROID) MediaRouterBase::MediaRouterBase() : initialized_(false) {}
diff --git a/chrome/browser/media/router/media_router_base.h b/chrome/browser/media/router/media_router_base.h index ec62fe66..c4338a95 100644 --- a/chrome/browser/media/router/media_router_base.h +++ b/chrome/browser/media/router/media_router_base.h
@@ -22,6 +22,7 @@ #if !defined(OS_ANDROID) #include "chrome/common/media_router/mojom/media_controller.mojom.h" #include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #endif // !defined(OS_ANDROID) namespace media_router { @@ -45,7 +46,7 @@ void GetMediaController( const MediaRoute::Id& route_id, mojo::PendingReceiver<mojom::MediaController> controller, - mojom::MediaStatusObserverPtr observer) override; + mojo::PendingRemote<mojom::MediaStatusObserver> observer) override; #endif // !defined(OS_ANDROID) void RegisterRemotingSource(SessionID tab_id, CastRemotingConnector* remoting_source) override;
diff --git a/chrome/browser/media/router/mojo/media_router_desktop.cc b/chrome/browser/media/router/mojo/media_router_desktop.cc index a027e3b..3a59b27 100644 --- a/chrome/browser/media/router/mojo/media_router_desktop.cc +++ b/chrome/browser/media/router/mojo/media_router_desktop.cc
@@ -21,6 +21,8 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/system_connector.h" #include "extensions/common/extension.h" +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/remote.h" #include "services/service_manager/public/cpp/connector.h" #if defined(OS_WIN) #include "chrome/browser/media/router/mojo/media_route_provider_util_win.h" @@ -43,15 +45,16 @@ MediaRouterDesktop::~MediaRouterDesktop() = default; // static -void MediaRouterDesktop::BindToRequest(const extensions::Extension* extension, - content::BrowserContext* context, - mojom::MediaRouterRequest request, - content::RenderFrameHost* source) { +void MediaRouterDesktop::BindToReceiver( + const extensions::Extension* extension, + content::BrowserContext* context, + mojo::PendingReceiver<mojom::MediaRouter> receiver, + content::RenderFrameHost* source) { MediaRouterDesktop* impl = static_cast<MediaRouterDesktop*>( MediaRouterFactory::GetApiForBrowserContext(context)); DCHECK(impl); - impl->BindToMojoRequest(std::move(request), *extension); + impl->BindToMojoReceiver(std::move(receiver), *extension); } void MediaRouterDesktop::OnUserGesture() { @@ -106,7 +109,7 @@ void MediaRouterDesktop::RegisterMediaRouteProvider( MediaRouteProviderId provider_id, - mojom::MediaRouteProviderPtr media_route_provider_ptr, + mojo::PendingRemote<mojom::MediaRouteProvider> media_route_provider_remote, mojom::MediaRouter::RegisterMediaRouteProviderCallback callback) { auto config = mojom::MediaRouteProviderConfig::New(); // Enabling browser side discovery / sink query means disabling extension side @@ -122,12 +125,14 @@ SyncStateToMediaRouteProvider(provider_id); if (provider_id == MediaRouteProviderId::EXTENSION) { - RegisterExtensionMediaRouteProvider(std::move(media_route_provider_ptr)); + RegisterExtensionMediaRouteProvider(std::move(media_route_provider_remote)); } else { - media_route_provider_ptr.set_connection_error_handler( + mojo::Remote<mojom::MediaRouteProvider> bound_remote( + std::move(media_route_provider_remote)); + bound_remote.set_disconnect_handler( base::BindOnce(&MediaRouterDesktop::OnProviderConnectionError, weak_factory_.GetWeakPtr(), provider_id)); - media_route_providers_[provider_id] = std::move(media_route_provider_ptr); + media_route_providers_[provider_id] = std::move(bound_remote); } } @@ -148,7 +153,7 @@ } void MediaRouterDesktop::RegisterExtensionMediaRouteProvider( - mojom::MediaRouteProviderPtr extension_provider_ptr) { + mojo::PendingRemote<mojom::MediaRouteProvider> extension_provider_remote) { ProvideSinksToExtension(); #if defined(OS_WIN) // The extension MRP already turns on mDNS discovery for platforms other than @@ -160,14 +165,14 @@ EnsureMdnsDiscoveryEnabled(); #endif extension_provider_proxy_->RegisterMediaRouteProvider( - std::move(extension_provider_ptr)); + std::move(extension_provider_remote)); } -void MediaRouterDesktop::BindToMojoRequest( - mojo::InterfaceRequest<mojom::MediaRouter> request, +void MediaRouterDesktop::BindToMojoReceiver( + mojo::PendingReceiver<mojom::MediaRouter> receiver, const extensions::Extension& extension) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - MediaRouterMojoImpl::BindToMojoRequest(std::move(request)); + MediaRouterMojoImpl::BindToMojoReceiver(std::move(receiver)); extension_provider_proxy_->SetExtensionId(extension.id()); if (!provider_version_was_recorded_) { MediaRouterMojoMetrics::RecordMediaRouteProviderVersion(extension); @@ -217,13 +222,13 @@ extension_provider_proxy_ = std::make_unique<ExtensionMediaRouteProviderProxy>(context()); } - mojom::MediaRouteProviderPtr extension_provider_proxy_ptr; + mojo::Remote<mojom::MediaRouteProvider> extension_provider_proxy_remote; extension_provider_proxy_->Bind( - mojo::MakeRequest(&extension_provider_proxy_ptr)); - extension_provider_proxy_ptr.set_connection_error_handler(base::BindOnce( + extension_provider_proxy_remote.BindNewPipeAndPassReceiver()); + extension_provider_proxy_remote.set_disconnect_handler(base::BindOnce( &MediaRouterDesktop::OnExtensionProviderError, base::Unretained(this))); media_route_providers_[MediaRouteProviderId::EXTENSION] = - std::move(extension_provider_proxy_ptr); + std::move(extension_provider_proxy_remote); } void MediaRouterDesktop::OnExtensionProviderError() { @@ -241,14 +246,15 @@ } void MediaRouterDesktop::InitializeWiredDisplayMediaRouteProvider() { - mojom::MediaRouterPtr media_router_ptr; - MediaRouterMojoImpl::BindToMojoRequest(mojo::MakeRequest(&media_router_ptr)); - mojom::MediaRouteProviderPtr wired_display_provider_ptr; + mojo::PendingRemote<mojom::MediaRouter> media_router_remote; + MediaRouterMojoImpl::BindToMojoReceiver( + media_router_remote.InitWithNewPipeAndPassReceiver()); + mojo::PendingRemote<mojom::MediaRouteProvider> wired_display_provider_remote; wired_display_provider_ = std::make_unique<WiredDisplayMediaRouteProvider>( - mojo::MakeRequest(&wired_display_provider_ptr), - std::move(media_router_ptr), Profile::FromBrowserContext(context())); + wired_display_provider_remote.InitWithNewPipeAndPassReceiver(), + std::move(media_router_remote), Profile::FromBrowserContext(context())); RegisterMediaRouteProvider(MediaRouteProviderId::WIRED_DISPLAY, - std::move(wired_display_provider_ptr), + std::move(wired_display_provider_remote), base::DoNothing()); } @@ -260,27 +266,30 @@ void MediaRouterDesktop::InitializeCastMediaRouteProvider() { auto task_runner = cast_channel::CastSocketService::GetInstance()->task_runner(); - mojom::MediaRouterPtr media_router_ptr; - MediaRouterMojoImpl::BindToMojoRequest(mojo::MakeRequest(&media_router_ptr)); - mojom::MediaRouteProviderPtr cast_provider_ptr; + mojo::PendingRemote<mojom::MediaRouter> media_router_remote; + MediaRouterMojoImpl::BindToMojoReceiver( + media_router_remote.InitWithNewPipeAndPassReceiver()); + mojo::PendingRemote<mojom::MediaRouteProvider> cast_provider_remote; cast_provider_ = std::unique_ptr<CastMediaRouteProvider, base::OnTaskRunnerDeleter>( new CastMediaRouteProvider( - mojo::MakeRequest(&cast_provider_ptr), - media_router_ptr.PassInterface(), + cast_provider_remote.InitWithNewPipeAndPassReceiver(), + std::move(media_router_remote), media_sink_service_->GetCastMediaSinkServiceImpl(), media_sink_service_->cast_app_discovery_service(), GetCastMessageHandler(), GetConnector(), GetHashToken(), task_runner), base::OnTaskRunnerDeleter(task_runner)); RegisterMediaRouteProvider(MediaRouteProviderId::CAST, - std::move(cast_provider_ptr), base::DoNothing()); + std::move(cast_provider_remote), + base::DoNothing()); } void MediaRouterDesktop::InitializeDialMediaRouteProvider() { - mojom::MediaRouterPtr media_router_ptr; - MediaRouterMojoImpl::BindToMojoRequest(mojo::MakeRequest(&media_router_ptr)); - mojom::MediaRouteProviderPtr dial_provider_ptr; + mojo::PendingRemote<mojom::MediaRouter> media_router_remote; + MediaRouterMojoImpl::BindToMojoReceiver( + media_router_remote.InitWithNewPipeAndPassReceiver()); + mojo::PendingRemote<mojom::MediaRouteProvider> dial_provider_remote; auto* dial_media_sink_service = media_sink_service_->GetDialMediaSinkServiceImpl(); @@ -288,13 +297,14 @@ dial_provider_ = std::unique_ptr<DialMediaRouteProvider, base::OnTaskRunnerDeleter>( - new DialMediaRouteProvider(mojo::MakeRequest(&dial_provider_ptr), - media_router_ptr.PassInterface(), - dial_media_sink_service, GetConnector(), - GetHashToken(), task_runner), + new DialMediaRouteProvider( + dial_provider_remote.InitWithNewPipeAndPassReceiver(), + std::move(media_router_remote), dial_media_sink_service, + GetConnector(), GetHashToken(), task_runner), base::OnTaskRunnerDeleter(task_runner)); RegisterMediaRouteProvider(MediaRouteProviderId::DIAL, - std::move(dial_provider_ptr), base::DoNothing()); + std::move(dial_provider_remote), + base::DoNothing()); } #if defined(OS_WIN)
diff --git a/chrome/browser/media/router/mojo/media_router_desktop.h b/chrome/browser/media/router/mojo/media_router_desktop.h index 34327ab..102d4888 100644 --- a/chrome/browser/media/router/mojo/media_router_desktop.h +++ b/chrome/browser/media/router/mojo/media_router_desktop.h
@@ -12,6 +12,8 @@ #include "chrome/browser/media/router/providers/cast/dual_media_sink_service.h" #include "chrome/browser/media/router/providers/dial/dial_media_route_provider.h" #include "chrome/browser/media/router/providers/extension/extension_media_route_provider_proxy.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/pending_remote.h" namespace content { class RenderFrameHost; @@ -45,11 +47,11 @@ // |extension|: The component extension, used for querying // suspension state. // |context|: The BrowserContext which owns the extension process. - // |request|: The Mojo connection request used for binding. - static void BindToRequest(const extensions::Extension* extension, - content::BrowserContext* context, - mojom::MediaRouterRequest request, - content::RenderFrameHost* source); + // |receiver|: The Mojo pending receiver used for binding. + static void BindToReceiver(const extensions::Extension* extension, + content::BrowserContext* context, + mojo::PendingReceiver<mojom::MediaRouter> receiver, + content::RenderFrameHost* source); // MediaRouter implementation. void OnUserGesture() override; @@ -79,7 +81,8 @@ // mojom::MediaRouter implementation. void RegisterMediaRouteProvider( MediaRouteProviderId provider_id, - mojom::MediaRouteProviderPtr media_route_provider_ptr, + mojo::PendingRemote<mojom::MediaRouteProvider> + media_route_provider_remote, mojom::MediaRouter::RegisterMediaRouteProviderCallback callback) override; void OnSinksReceived(MediaRouteProviderId provider_id, const std::string& media_source, @@ -88,17 +91,17 @@ void GetMediaSinkServiceStatus( mojom::MediaRouter::GetMediaSinkServiceStatusCallback callback) override; - // Registers a Mojo pointer to the extension MRP with + // Registers a Mojo remote to the extension MRP with // |extension_provider_proxy_| and does initializations specific to the // extension MRP. void RegisterExtensionMediaRouteProvider( - mojom::MediaRouteProviderPtr extension_provider_ptr); + mojo::PendingRemote<mojom::MediaRouteProvider> extension_provider_remote); - // Binds |this| to a Mojo interface request, so that clients can acquire a + // Binds |this| to a Mojo pending receiver, so that clients can acquire a // handle to a MediaRouter instance via the Mojo service connector. // Passes the extension's ID to the event page request manager. - void BindToMojoRequest(mojo::InterfaceRequest<mojom::MediaRouter> request, - const extensions::Extension& extension); + void BindToMojoReceiver(mojo::PendingReceiver<mojom::MediaRouter> receiver, + const extensions::Extension& extension); // Provides the current list of sinks from |media_sink_service_| to the // extension. Also registers with |media_sink_service_| to listen for updates.
diff --git a/chrome/browser/media/router/mojo/media_router_desktop_unittest.cc b/chrome/browser/media/router/mojo/media_router_desktop_unittest.cc index 6e25070..27805e68 100644 --- a/chrome/browser/media/router/mojo/media_router_desktop_unittest.cc +++ b/chrome/browser/media/router/mojo/media_router_desktop_unittest.cc
@@ -11,6 +11,7 @@ #include <string> #include <utility> +#include "base/macros.h" #include "base/run_loop.h" #include "base/test/scoped_feature_list.h" #include "build/build_config.h" @@ -208,13 +209,13 @@ // |extension_mrp_proxy|. for (int i = 0; i < MediaRouterDesktop::kMaxMediaRouteProviderErrorCount; i++) { - extension_mrp_proxy->binding_.Unbind(); + ignore_result(extension_mrp_proxy->receiver_.Unbind()); base::RunLoop().RunUntilIdle(); - EXPECT_TRUE(extension_mrp_proxy->binding_.is_bound()); + EXPECT_TRUE(extension_mrp_proxy->receiver_.is_bound()); } - extension_mrp_proxy->binding_.Unbind(); + ignore_result(extension_mrp_proxy->receiver_.Unbind()); base::RunLoop().RunUntilIdle(); - EXPECT_FALSE(extension_mrp_proxy->binding_.is_bound()); + EXPECT_FALSE(extension_mrp_proxy->receiver_.is_bound()); } } // namespace media_router
diff --git a/chrome/browser/media/router/mojo/media_router_mojo_impl.cc b/chrome/browser/media/router/mojo/media_router_mojo_impl.cc index 2d738535..2190bf8 100644 --- a/chrome/browser/media/router/mojo/media_router_mojo_impl.cc +++ b/chrome/browser/media/router/mojo/media_router_mojo_impl.cc
@@ -138,14 +138,16 @@ void MediaRouterMojoImpl::RegisterMediaRouteProvider( MediaRouteProviderId provider_id, - mojom::MediaRouteProviderPtr media_route_provider_ptr, + mojo::PendingRemote<mojom::MediaRouteProvider> media_route_provider_remote, mojom::MediaRouter::RegisterMediaRouteProviderCallback callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); DCHECK(!base::Contains(media_route_providers_, provider_id)); - media_route_provider_ptr.set_connection_error_handler( + mojo::Remote<mojom::MediaRouteProvider> bound_remote( + std::move(media_route_provider_remote)); + bound_remote.set_disconnect_handler( base::BindOnce(&MediaRouterMojoImpl::OnProviderConnectionError, weak_factory_.GetWeakPtr(), provider_id)); - media_route_providers_[provider_id] = std::move(media_route_provider_ptr); + media_route_providers_[provider_id] = std::move(bound_remote); std::move(callback).Run(instance_id_, mojom::MediaRouteProviderConfig::New()); } @@ -439,7 +441,7 @@ void MediaRouterMojoImpl::GetMediaController( const MediaRoute::Id& route_id, mojo::PendingReceiver<mojom::MediaController> controller, - mojom::MediaStatusObserverPtr observer) { + mojo::PendingRemote<mojom::MediaStatusObserver> observer) { auto* route = GetRoute(route_id); base::Optional<MediaRouteProviderId> provider_id = GetProviderIdForRoute(route_id); @@ -968,9 +970,9 @@ } } -void MediaRouterMojoImpl::BindToMojoRequest( - mojo::InterfaceRequest<mojom::MediaRouter> request) { - bindings_.AddBinding(this, std::move(request)); +void MediaRouterMojoImpl::BindToMojoReceiver( + mojo::PendingReceiver<mojom::MediaRouter> receiver) { + receivers_.Add(this, std::move(receiver)); } base::Optional<MediaRouteProviderId> MediaRouterMojoImpl::GetProviderIdForRoute(
diff --git a/chrome/browser/media/router/mojo/media_router_mojo_impl.h b/chrome/browser/media/router/mojo/media_router_mojo_impl.h index 7c86793b..879507d 100644 --- a/chrome/browser/media/router/mojo/media_router_mojo_impl.h +++ b/chrome/browser/media/router/mojo/media_router_mojo_impl.h
@@ -27,8 +27,10 @@ #include "chrome/common/media_router/mojom/media_router.mojom.h" #include "chrome/common/media_router/route_request_result.h" #include "content/public/browser/browser_thread.h" -#include "mojo/public/cpp/bindings/binding_set.h" #include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/receiver_set.h" +#include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/public/mojom/presentation/presentation.mojom.h" namespace content { @@ -81,10 +83,11 @@ void GetMediaController( const MediaRoute::Id& route_id, mojo::PendingReceiver<mojom::MediaController> controller, - mojom::MediaStatusObserverPtr observer) final; + mojo::PendingRemote<mojom::MediaStatusObserver> observer) final; void RegisterMediaRouteProvider( MediaRouteProviderId provider_id, - mojom::MediaRouteProviderPtr media_route_provider_ptr, + mojo::PendingRemote<mojom::MediaRouteProvider> + media_route_provider_remote, mojom::MediaRouter::RegisterMediaRouteProviderCallback callback) override; // Issues 0+ calls to the provider given by |provider_id| to ensure its state @@ -111,8 +114,8 @@ // Removes the pointer from |media_route_providers_|. void OnProviderConnectionError(MediaRouteProviderId provider_id); - // Creates a binding between |this| and |request|. - void BindToMojoRequest(mojo::InterfaceRequest<mojom::MediaRouter> request); + // Creates a binding between |this| and |receiver|. + void BindToMojoReceiver(mojo::PendingReceiver<mojom::MediaRouter> receiver); // Methods for obtaining a pointer to the provider associated with the given // object. They return a nullopt when such a provider is not found. @@ -129,9 +132,9 @@ const std::vector<MediaSinkInternal>& internal_sinks, const std::vector<url::Origin>& origins) override; - // Mojo pointers to media route providers. Providers are added via + // Mojo remotes to media route providers. Providers are added via // RegisterMediaRouteProvider(). - base::flat_map<MediaRouteProviderId, mojom::MediaRouteProviderPtr> + base::flat_map<MediaRouteProviderId, mojo::Remote<mojom::MediaRouteProvider>> media_route_providers_; private: @@ -416,8 +419,8 @@ // The last reported sink availability from the media route providers. ProviderSinkAvailability sink_availability_; - // Bindings for Mojo pointers to |this| held by media route providers. - mojo::BindingSet<mojom::MediaRouter> bindings_; + // Receivers for Mojo remotes to |this| held by media route providers. + mojo::ReceiverSet<mojom::MediaRouter> receivers_; content::BrowserContext* const context_;
diff --git a/chrome/browser/media/router/mojo/media_router_mojo_impl_unittest.cc b/chrome/browser/media/router/mojo/media_router_mojo_impl_unittest.cc index cce461a..8aa1278 100644 --- a/chrome/browser/media/router/mojo/media_router_mojo_impl_unittest.cc +++ b/chrome/browser/media/router/mojo/media_router_mojo_impl_unittest.cc
@@ -981,9 +981,10 @@ TEST_F(MediaRouterMojoImplTest, GetMediaController) { MockMediaController mock_controller; mojo::Remote<mojom::MediaController> controller_remote; - mojom::MediaStatusObserverPtr observer_ptr; - MockMediaStatusObserver mock_observer(mojo::MakeRequest(&observer_ptr)); - mojom::MediaStatusObserverPtr observer_ptr_held_by_controller; + mojo::PendingRemote<mojom::MediaStatusObserver> observer_remote; + MockMediaStatusObserver mock_observer( + observer_remote.InitWithNewPipeAndPassReceiver()); + mojo::Remote<mojom::MediaStatusObserver> observer_remote_held_by_controller; router()->OnRoutesUpdated(MediaRouteProviderId::EXTENSION, {CreateMediaRoute()}, "", {}); @@ -992,22 +993,22 @@ .WillOnce( [&](const std::string& route_id, mojo::PendingReceiver<mojom::MediaController>& media_controller, - mojom::MediaStatusObserverPtr& observer, + mojo::PendingRemote<mojom::MediaStatusObserver>& observer, MockMediaRouteProvider::CreateMediaRouteControllerCallback& callback) { mock_controller.Bind(std::move(media_controller)); - observer_ptr_held_by_controller = std::move(observer); + observer_remote_held_by_controller.Bind(std::move(observer)); std::move(callback).Run(true); }); router()->GetMediaController(kRouteId, controller_remote.BindNewPipeAndPassReceiver(), - std::move(observer_ptr)); + std::move(observer_remote)); base::RunLoop().RunUntilIdle(); EXPECT_CALL(mock_controller, Play()); controller_remote->Play(); EXPECT_CALL(mock_observer, OnMediaStatusUpdated(_)); - observer_ptr_held_by_controller->OnMediaStatusUpdated( + observer_remote_held_by_controller->OnMediaStatusUpdated( mojom::MediaStatus::New()); base::RunLoop().RunUntilIdle(); }
diff --git a/chrome/browser/media/router/providers/cast/activity_record.h b/chrome/browser/media/router/providers/cast/activity_record.h index c067102..4a8f313 100644 --- a/chrome/browser/media/router/providers/cast/activity_record.h +++ b/chrome/browser/media/router/providers/cast/activity_record.h
@@ -18,6 +18,7 @@ #include "chrome/common/media_router/mojom/media_router.mojom.h" #include "chrome/common/media_router/providers/cast/cast_media_source.h" #include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/pending_remote.h" namespace cast_channel { class CastMessageHandler; @@ -143,7 +144,7 @@ virtual void CreateMediaController( mojo::PendingReceiver<mojom::MediaController> media_controller, - mojom::MediaStatusObserverPtr observer) = 0; + mojo::PendingRemote<mojom::MediaStatusObserver> observer) = 0; protected: CastSession* GetSession() const;
diff --git a/chrome/browser/media/router/providers/cast/cast_activity_manager.cc b/chrome/browser/media/router/providers/cast/cast_activity_manager.cc index d275112..6e6e001 100644 --- a/chrome/browser/media/router/providers/cast/cast_activity_manager.cc +++ b/chrome/browser/media/router/providers/cast/cast_activity_manager.cc
@@ -391,7 +391,7 @@ bool CastActivityManager::CreateMediaController( const std::string& route_id, mojo::PendingReceiver<mojom::MediaController> media_controller, - mojom::MediaStatusObserverPtr observer) { + mojo::PendingRemote<mojom::MediaStatusObserver> observer) { auto activity_it = activities_.find(route_id); if (activity_it == activities_.end()) return false;
diff --git a/chrome/browser/media/router/providers/cast/cast_activity_manager.h b/chrome/browser/media/router/providers/cast/cast_activity_manager.h index c934e2f..dda3a5d 100644 --- a/chrome/browser/media/router/providers/cast/cast_activity_manager.h +++ b/chrome/browser/media/router/providers/cast/cast_activity_manager.h
@@ -22,6 +22,7 @@ #include "chrome/common/media_router/mojom/media_router.mojom.h" #include "chrome/common/media_router/providers/cast/cast_media_source.h" #include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #include "url/origin.h" namespace cast_channel { @@ -109,7 +110,7 @@ bool CreateMediaController( const std::string& route_id, mojo::PendingReceiver<mojom::MediaController> media_controller, - mojom::MediaStatusObserverPtr observer); + mojo::PendingRemote<mojom::MediaStatusObserver> observer); const MediaRoute* GetRoute(const MediaRoute::Id& route_id) const; std::vector<MediaRoute> GetRoutes() const;
diff --git a/chrome/browser/media/router/providers/cast/cast_activity_manager_unittest.cc b/chrome/browser/media/router/providers/cast/cast_activity_manager_unittest.cc index c5a36999..9d2847a0 100644 --- a/chrome/browser/media/router/providers/cast/cast_activity_manager_unittest.cc +++ b/chrome/browser/media/router/providers/cast/cast_activity_manager_unittest.cc
@@ -29,6 +29,8 @@ #include "components/cast_channel/cast_test_util.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/test/browser_task_environment.h" +#include "mojo/public/cpp/bindings/receiver.h" +#include "mojo/public/cpp/bindings/remote.h" #include "services/data_decoder/data_decoder_service.h" #include "services/data_decoder/public/cpp/testing_json_parser.h" #include "services/data_decoder/public/mojom/constants.mojom.h" @@ -104,15 +106,15 @@ void SetUp() override { CastActivityManager::SetActitivyRecordFactoryForTest(this); - router_binding_ = std::make_unique<mojo::Binding<mojom::MediaRouter>>( - &mock_router_, mojo::MakeRequest(&router_ptr_)); + router_receiver_ = std::make_unique<mojo::Receiver<mojom::MediaRouter>>( + &mock_router_, router_remote_.BindNewPipeAndPassReceiver()); session_tracker_.reset( new CastSessionTracker(&media_sink_service_, &message_handler_, socket_service_.task_runner())); manager_ = std::make_unique<CastActivityManager>( &media_sink_service_, session_tracker_.get(), &message_handler_, - router_ptr_.get(), + router_remote_.get(), std::make_unique<DataDecoder>(connector_factory_.GetDefaultConnector()), "theHashToken"); @@ -306,8 +308,8 @@ data_decoder::TestingJsonParser::ScopedFactoryOverride parser_override_; service_manager::TestConnectorFactory connector_factory_; MockMojoMediaRouter mock_router_; - mojom::MediaRouterPtr router_ptr_; - std::unique_ptr<mojo::Binding<mojom::MediaRouter>> router_binding_; + mojo::Remote<mojom::MediaRouter> router_remote_; + std::unique_ptr<mojo::Receiver<mojom::MediaRouter>> router_receiver_; cast_channel::MockCastSocketService socket_service_; cast_channel::MockCastSocket socket_; cast_channel::MockCastMessageHandler message_handler_;
diff --git a/chrome/browser/media/router/providers/cast/cast_activity_record.cc b/chrome/browser/media/router/providers/cast/cast_activity_record.cc index da34f9f..65e9a8f 100644 --- a/chrome/browser/media/router/providers/cast/cast_activity_record.cc +++ b/chrome/browser/media/router/providers/cast/cast_activity_record.cc
@@ -206,7 +206,7 @@ void CastActivityRecord::CreateMediaController( mojo::PendingReceiver<mojom::MediaController> media_controller, - mojom::MediaStatusObserverPtr observer) { + mojo::PendingRemote<mojom::MediaStatusObserver> observer) { media_controller_ = std::make_unique<CastMediaController>( this, std::move(media_controller), std::move(observer));
diff --git a/chrome/browser/media/router/providers/cast/cast_activity_record.h b/chrome/browser/media/router/providers/cast/cast_activity_record.h index 0d62577..24f2231f 100644 --- a/chrome/browser/media/router/providers/cast/cast_activity_record.h +++ b/chrome/browser/media/router/providers/cast/cast_activity_record.h
@@ -16,6 +16,7 @@ #include "chrome/common/media_router/providers/cast/cast_media_source.h" #include "components/cast_channel/cast_message_handler.h" #include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/pending_remote.h" namespace url { class Origin; @@ -85,7 +86,7 @@ void OnInternalMessage(const cast_channel::InternalMessage& message) override; void CreateMediaController( mojo::PendingReceiver<mojom::MediaController> media_controller, - mojom::MediaStatusObserverPtr observer) override; + mojo::PendingRemote<mojom::MediaStatusObserver> observer) override; static void SetClientFactoryForTest( CastSessionClientFactoryForTest* factory) {
diff --git a/chrome/browser/media/router/providers/cast/cast_media_controller.cc b/chrome/browser/media/router/providers/cast/cast_media_controller.cc index d9f26df5..f81a47f 100644 --- a/chrome/browser/media/router/providers/cast/cast_media_controller.cc +++ b/chrome/browser/media/router/providers/cast/cast_media_controller.cc
@@ -62,7 +62,7 @@ CastMediaController::CastMediaController( ActivityRecord* activity, mojo::PendingReceiver<mojom::MediaController> receiver, - mojom::MediaStatusObserverPtr observer) + mojo::PendingRemote<mojom::MediaStatusObserver> observer) : sender_id_("sender-" + base::NumberToString(base::RandUint64())), activity_(activity), receiver_(this, std::move(receiver)),
diff --git a/chrome/browser/media/router/providers/cast/cast_media_controller.h b/chrome/browser/media/router/providers/cast/cast_media_controller.h index 54fb0ea..cd8ca7e 100644 --- a/chrome/browser/media/router/providers/cast/cast_media_controller.h +++ b/chrome/browser/media/router/providers/cast/cast_media_controller.h
@@ -10,7 +10,9 @@ #include "chrome/common/media_router/mojom/media_status.mojom.h" #include "components/cast_channel/cast_message_util.h" #include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/receiver.h" +#include "mojo/public/cpp/bindings/remote.h" namespace base { class Value; @@ -49,7 +51,7 @@ public: CastMediaController(ActivityRecord* activity, mojo::PendingReceiver<mojom::MediaController> receiver, - mojom::MediaStatusObserverPtr observer); + mojo::PendingRemote<mojom::MediaStatusObserver> observer); ~CastMediaController() override; // mojom::MediaController overrides: @@ -81,7 +83,7 @@ int media_session_id_; mojo::Receiver<mojom::MediaController> receiver_; - mojom::MediaStatusObserverPtr observer_; + mojo::Remote<mojom::MediaStatusObserver> observer_; DISALLOW_COPY_AND_ASSIGN(CastMediaController); };
diff --git a/chrome/browser/media/router/providers/cast/cast_media_controller_unittest.cc b/chrome/browser/media/router/providers/cast/cast_media_controller_unittest.cc index 9899e26..7162425 100644 --- a/chrome/browser/media/router/providers/cast/cast_media_controller_unittest.cc +++ b/chrome/browser/media/router/providers/cast/cast_media_controller_unittest.cc
@@ -127,9 +127,9 @@ void SetUp() override { testing::Test::SetUp(); - mojom::MediaStatusObserverPtr mojo_status_observer; + mojo::PendingRemote<mojom::MediaStatusObserver> mojo_status_observer; status_observer_ = std::make_unique<MockMediaStatusObserver>( - mojo::MakeRequest(&mojo_status_observer)); + mojo_status_observer.InitWithNewPipeAndPassReceiver()); controller_ = std::make_unique<CastMediaController>( &activity_, mojo_controller_.BindNewPipeAndPassReceiver(), std::move(mojo_status_observer));
diff --git a/chrome/browser/media/router/providers/cast/cast_media_route_provider.cc b/chrome/browser/media/router/providers/cast/cast_media_route_provider.cc index 4457902..57b05907 100644 --- a/chrome/browser/media/router/providers/cast/cast_media_route_provider.cc +++ b/chrome/browser/media/router/providers/cast/cast_media_route_provider.cc
@@ -38,16 +38,15 @@ } // namespace CastMediaRouteProvider::CastMediaRouteProvider( - mojom::MediaRouteProviderRequest request, - mojom::MediaRouterPtrInfo media_router, + mojo::PendingReceiver<mojom::MediaRouteProvider> receiver, + mojo::PendingRemote<mojom::MediaRouter> media_router, MediaSinkServiceBase* media_sink_service, CastAppDiscoveryService* app_discovery_service, cast_channel::CastMessageHandler* message_handler, service_manager::Connector* connector, const std::string& hash_token, const scoped_refptr<base::SequencedTaskRunner>& task_runner) - : binding_(this), - media_sink_service_(media_sink_service), + : media_sink_service_(media_sink_service), app_discovery_service_(app_discovery_service), message_handler_(message_handler) { DETACH_FROM_SEQUENCE(sequence_checker_); @@ -58,19 +57,20 @@ task_runner->PostTask( FROM_HERE, base::BindOnce(&CastMediaRouteProvider::Init, base::Unretained(this), - std::move(request), std::move(media_router), + std::move(receiver), std::move(media_router), CastSessionTracker::GetInstance(), std::make_unique<DataDecoder>(connector), hash_token)); } -void CastMediaRouteProvider::Init(mojom::MediaRouteProviderRequest request, - mojom::MediaRouterPtrInfo media_router, - CastSessionTracker* session_tracker, - std::unique_ptr<DataDecoder> data_decoder, - const std::string& hash_token) { +void CastMediaRouteProvider::Init( + mojo::PendingReceiver<mojom::MediaRouteProvider> receiver, + mojo::PendingRemote<mojom::MediaRouter> media_router, + CastSessionTracker* session_tracker, + std::unique_ptr<DataDecoder> data_decoder, + const std::string& hash_token) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - binding_.Bind(std::move(request)); + receiver_.Bind(std::move(receiver)); media_router_.Bind(std::move(media_router)); activity_manager_ = std::make_unique<CastActivityManager>( @@ -262,7 +262,7 @@ void CastMediaRouteProvider::CreateMediaRouteController( const std::string& route_id, mojo::PendingReceiver<mojom::MediaController> media_controller, - mojom::MediaStatusObserverPtr observer, + mojo::PendingRemote<mojom::MediaStatusObserver> observer, CreateMediaRouteControllerCallback callback) { std::move(callback).Run(activity_manager_->CreateMediaController( route_id, std::move(media_controller), std::move(observer)));
diff --git a/chrome/browser/media/router/providers/cast/cast_media_route_provider.h b/chrome/browser/media/router/providers/cast/cast_media_route_provider.h index 9846544..584a9fe 100644 --- a/chrome/browser/media/router/providers/cast/cast_media_route_provider.h +++ b/chrome/browser/media/router/providers/cast/cast_media_route_provider.h
@@ -14,8 +14,10 @@ #include "chrome/browser/media/router/providers/cast/cast_app_discovery_service.h" #include "chrome/browser/media/router/providers/cast/dual_media_sink_service.h" #include "chrome/common/media_router/mojom/media_router.mojom.h" -#include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/receiver.h" +#include "mojo/public/cpp/bindings/remote.h" namespace cast_channel { class CastMessageHandler; @@ -41,8 +43,8 @@ class CastMediaRouteProvider : public mojom::MediaRouteProvider { public: CastMediaRouteProvider( - mojom::MediaRouteProviderRequest request, - mojom::MediaRouterPtrInfo media_router, + mojo::PendingReceiver<mojom::MediaRouteProvider> receiver, + mojo::PendingRemote<mojom::MediaRouter> media_router, MediaSinkServiceBase* media_sink_service, CastAppDiscoveryService* app_discovery_service, cast_channel::CastMessageHandler* message_handler, @@ -100,12 +102,12 @@ void CreateMediaRouteController( const std::string& route_id, mojo::PendingReceiver<mojom::MediaController> media_controller, - mojom::MediaStatusObserverPtr observer, + mojo::PendingRemote<mojom::MediaStatusObserver> observer, CreateMediaRouteControllerCallback callback) override; private: - void Init(mojom::MediaRouteProviderRequest request, - mojom::MediaRouterPtrInfo media_router, + void Init(mojo::PendingReceiver<mojom::MediaRouteProvider> receiver, + mojo::PendingRemote<mojom::MediaRouter> media_router, CastSessionTracker* session_tracker, std::unique_ptr<DataDecoder> data_decoder, const std::string& hash_token); @@ -118,11 +120,11 @@ void BroadcastMessageToSinks(const std::vector<std::string>& app_ids, const cast_channel::BroadcastRequest& request); - // Binds |this| to the Mojo request passed into the ctor. - mojo::Binding<mojom::MediaRouteProvider> binding_; + // Binds |this| to the Mojo receiver passed into the ctor. + mojo::Receiver<mojom::MediaRouteProvider> receiver_{this}; - // Mojo pointer to the Media Router. - mojom::MediaRouterPtr media_router_; + // Mojo remote to the Media Router. + mojo::Remote<mojom::MediaRouter> media_router_; // Non-owned pointer to the Cast MediaSinkServiceBase instance. MediaSinkServiceBase* const media_sink_service_;
diff --git a/chrome/browser/media/router/providers/cast/cast_media_route_provider_unittest.cc b/chrome/browser/media/router/providers/cast/cast_media_route_provider_unittest.cc index 8ba39cb2..36eef233 100644 --- a/chrome/browser/media/router/providers/cast/cast_media_route_provider_unittest.cc +++ b/chrome/browser/media/router/providers/cast/cast_media_route_provider_unittest.cc
@@ -15,6 +15,9 @@ #include "components/cast_channel/cast_test_util.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/test/browser_task_environment.h" +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/receiver.h" +#include "mojo/public/cpp/bindings/remote.h" #include "services/data_decoder/data_decoder_service.h" #include "services/data_decoder/public/mojom/constants.mojom.h" #include "services/service_manager/public/cpp/connector.h" @@ -46,9 +49,9 @@ ~CastMediaRouteProviderTest() override = default; void SetUp() override { - mojom::MediaRouterPtr router_ptr; - router_binding_ = std::make_unique<mojo::Binding<mojom::MediaRouter>>( - &mock_router_, mojo::MakeRequest(&router_ptr)); + mojo::PendingRemote<mojom::MediaRouter> router_remote; + router_receiver_ = std::make_unique<mojo::Receiver<mojom::MediaRouter>>( + &mock_router_, router_remote.InitWithNewPipeAndPassReceiver()); session_tracker_ = std::unique_ptr<CastSessionTracker>( new CastSessionTracker(&media_sink_service_, &message_handler_, @@ -57,7 +60,7 @@ EXPECT_CALL(mock_router_, OnSinkAvailabilityUpdated(_, _)); provider_ = std::make_unique<CastMediaRouteProvider>( - mojo::MakeRequest(&provider_ptr_), router_ptr.PassInterface(), + provider_remote_.BindNewPipeAndPassReceiver(), std::move(router_remote), &media_sink_service_, &app_discovery_service_, &message_handler_, connector_factory_.GetDefaultConnector(), "hash-token", base::SequencedTaskRunnerHandle::Get()); @@ -106,9 +109,9 @@ service_manager::TestConnectorFactory connector_factory_; data_decoder::DataDecoderService data_decoder_service_; - mojom::MediaRouteProviderPtr provider_ptr_; + mojo::Remote<mojom::MediaRouteProvider> provider_remote_; MockMojoMediaRouter mock_router_; - std::unique_ptr<mojo::Binding<mojom::MediaRouter>> router_binding_; + std::unique_ptr<mojo::Receiver<mojom::MediaRouter>> router_receiver_; cast_channel::MockCastSocketService socket_service_; cast_channel::MockCastMessageHandler message_handler_;
diff --git a/chrome/browser/media/router/providers/cast/mirroring_activity_record.cc b/chrome/browser/media/router/providers/cast/mirroring_activity_record.cc index 93c2e4c..88b2774 100644 --- a/chrome/browser/media/router/providers/cast/mirroring_activity_record.cc +++ b/chrome/browser/media/router/providers/cast/mirroring_activity_record.cc
@@ -253,7 +253,7 @@ void MirroringActivityRecord::CreateMediaController( mojo::PendingReceiver<mojom::MediaController> media_controller, - mojom::MediaStatusObserverPtr observer) {} + mojo::PendingRemote<mojom::MediaStatusObserver> observer) {} void MirroringActivityRecord::StopMirroring() { // Running the callback will cause this object to be deleted.
diff --git a/chrome/browser/media/router/providers/cast/mirroring_activity_record.h b/chrome/browser/media/router/providers/cast/mirroring_activity_record.h index 9c834c1d6..10559b1b 100644 --- a/chrome/browser/media/router/providers/cast/mirroring_activity_record.h +++ b/chrome/browser/media/router/providers/cast/mirroring_activity_record.h
@@ -18,6 +18,7 @@ #include "components/mirroring/mojom/mirroring_service_host.mojom.h" #include "components/mirroring/mojom/session_observer.mojom.h" #include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" @@ -81,7 +82,7 @@ protected: void CreateMediaController( mojo::PendingReceiver<mojom::MediaController> media_controller, - mojom::MediaStatusObserverPtr observer) override; + mojo::PendingRemote<mojom::MediaStatusObserver> observer) override; private: enum class MirroringType {
diff --git a/chrome/browser/media/router/providers/cast/mock_activity_record.h b/chrome/browser/media/router/providers/cast/mock_activity_record.h index b2aab5b..7379a16 100644 --- a/chrome/browser/media/router/providers/cast/mock_activity_record.h +++ b/chrome/browser/media/router/providers/cast/mock_activity_record.h
@@ -11,6 +11,7 @@ #include "chrome/browser/media/router/providers/cast/cast_internal_message_util.h" #include "chrome/browser/media/router/providers/cast/cast_session_client.h" #include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #include "testing/gmock/include/gmock/gmock.h" namespace media_router { @@ -69,7 +70,7 @@ MOCK_METHOD2( CreateMediaController, void(mojo::PendingReceiver<mojom::MediaController> media_controller, - mojom::MediaStatusObserverPtr observer)); + mojo::PendingRemote<mojom::MediaStatusObserver> observer)); }; } // namespace media_router
diff --git a/chrome/browser/media/router/providers/dial/dial_media_route_provider.cc b/chrome/browser/media/router/providers/dial/dial_media_route_provider.cc index 93347db..ca46f69 100644 --- a/chrome/browser/media/router/providers/dial/dial_media_route_provider.cc +++ b/chrome/browser/media/router/providers/dial/dial_media_route_provider.cc
@@ -37,14 +37,13 @@ } // namespace DialMediaRouteProvider::DialMediaRouteProvider( - mojom::MediaRouteProviderRequest request, - mojom::MediaRouterPtrInfo media_router, + mojo::PendingReceiver<mojom::MediaRouteProvider> receiver, + mojo::PendingRemote<mojom::MediaRouter> media_router, DialMediaSinkServiceImpl* media_sink_service, service_manager::Connector* connector, const std::string& hash_token, const scoped_refptr<base::SequencedTaskRunner>& task_runner) - : binding_(this), - media_sink_service_(media_sink_service), + : media_sink_service_(media_sink_service), data_decoder_(std::make_unique<DataDecoder>(connector)), internal_message_util_(hash_token) { DETACH_FROM_SEQUENCE(sequence_checker_); @@ -53,14 +52,15 @@ task_runner->PostTask( FROM_HERE, base::BindOnce(&DialMediaRouteProvider::Init, base::Unretained(this), - std::move(request), std::move(media_router))); + std::move(receiver), std::move(media_router))); } -void DialMediaRouteProvider::Init(mojom::MediaRouteProviderRequest request, - mojom::MediaRouterPtrInfo media_router) { +void DialMediaRouteProvider::Init( + mojo::PendingReceiver<mojom::MediaRouteProvider> receiver, + mojo::PendingRemote<mojom::MediaRouter> media_router) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - binding_.Bind(std::move(request)); + receiver_.Bind(std::move(receiver)); media_router_.Bind(std::move(media_router)); media_sink_service_->AddObserver(this); @@ -511,7 +511,7 @@ void DialMediaRouteProvider::CreateMediaRouteController( const std::string& route_id, mojo::PendingReceiver<mojom::MediaController> media_controller, - mojom::MediaStatusObserverPtr observer, + mojo::PendingRemote<mojom::MediaStatusObserver> observer, CreateMediaRouteControllerCallback callback) { NOTIMPLEMENTED(); std::move(callback).Run(false);
diff --git a/chrome/browser/media/router/providers/dial/dial_media_route_provider.h b/chrome/browser/media/router/providers/dial/dial_media_route_provider.h index a3c3365..14a8ff6 100644 --- a/chrome/browser/media/router/providers/dial/dial_media_route_provider.h +++ b/chrome/browser/media/router/providers/dial/dial_media_route_provider.h
@@ -20,8 +20,10 @@ #include "chrome/browser/media/router/providers/dial/dial_activity_manager.h" #include "chrome/browser/media/router/providers/dial/dial_internal_message_util.h" #include "chrome/common/media_router/mojom/media_router.mojom.h" -#include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/receiver.h" +#include "mojo/public/cpp/bindings/remote.h" namespace url { class Origin; @@ -49,15 +51,15 @@ class DialMediaRouteProvider : public mojom::MediaRouteProvider, public MediaSinkServiceBase::Observer { public: - // |request|: Request to bind to |this|. - // |media_router|: Pointer to MediaRouter. + // |receiver|: Mojo receiver to bind to |this|. + // |media_router|: Pending remote to MediaRouter. // |media_sink_service|: DIAL MediaSinkService providing information on sinks. // |connector|: Connector object for accessing data_decoder services. // |hash_token|: A per-profile value used to hash sink IDs. // |task_runner|: The task runner on which |this| runs. DialMediaRouteProvider( - mojom::MediaRouteProviderRequest request, - mojom::MediaRouterPtrInfo media_router, + mojo::PendingReceiver<mojom::MediaRouteProvider> receiver, + mojo::PendingRemote<mojom::MediaRouter> media_router, DialMediaSinkServiceImpl* media_sink_service, service_manager::Connector* connector, const std::string& hash_token, @@ -113,7 +115,7 @@ void CreateMediaRouteController( const std::string& route_id, mojo::PendingReceiver<mojom::MediaController> media_controller, - mojom::MediaStatusObserverPtr observer, + mojo::PendingRemote<mojom::MediaStatusObserver> observer, CreateMediaRouteControllerCallback callback) override; void SetActivityManagerForTest( @@ -143,9 +145,9 @@ // MediaSinkServiceBase::Observer: void OnSinksDiscovered(const std::vector<MediaSinkInternal>& sinks) override; - // Binds the message pipes |request| and |media_router| to |this|. - void Init(mojom::MediaRouteProviderRequest request, - mojom::MediaRouterPtrInfo media_router); + // Binds the message pipes |receiver| and |media_router| to |this|. + void Init(mojo::PendingReceiver<mojom::MediaRouteProvider> receiver, + mojo::PendingRemote<mojom::MediaRouter> media_router); void OnAvailableSinksUpdated(const std::string& app_name); @@ -179,11 +181,11 @@ // all origins are valid. std::vector<url::Origin> GetOrigins(const std::string& app_name); - // Binds |this| to the Mojo request passed into the ctor. - mojo::Binding<mojom::MediaRouteProvider> binding_; + // Binds |this| to the Mojo receiver passed into the ctor. + mojo::Receiver<mojom::MediaRouteProvider> receiver_{this}; - // Mojo pointer to the Media Router. - mojom::MediaRouterPtr media_router_; + // Mojo remote to the Media Router. + mojo::Remote<mojom::MediaRouter> media_router_; // Non-owned pointer to the DialMediaSinkServiceImpl instance. DialMediaSinkServiceImpl* const media_sink_service_;
diff --git a/chrome/browser/media/router/providers/dial/dial_media_route_provider_unittest.cc b/chrome/browser/media/router/providers/dial/dial_media_route_provider_unittest.cc index b245a4f..7420f87 100644 --- a/chrome/browser/media/router/providers/dial/dial_media_route_provider_unittest.cc +++ b/chrome/browser/media/router/providers/dial/dial_media_route_provider_unittest.cc
@@ -15,6 +15,9 @@ #include "chrome/browser/media/router/route_message_util.h" #include "chrome/browser/media/router/test/test_helper.h" #include "content/public/test/browser_task_environment.h" +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/receiver.h" +#include "mojo/public/cpp/bindings/remote.h" #include "net/http/http_status_code.h" #include "services/data_decoder/data_decoder_service.h" #include "services/data_decoder/public/cpp/testing_json_parser.h" @@ -93,13 +96,13 @@ mock_sink_service_(connector_factory_.GetDefaultConnector()) {} void SetUp() override { - mojom::MediaRouterPtr router_ptr; - router_binding_ = std::make_unique<mojo::Binding<mojom::MediaRouter>>( - &mock_router_, mojo::MakeRequest(&router_ptr)); + mojo::PendingRemote<mojom::MediaRouter> router_remote; + router_receiver_ = std::make_unique<mojo::Receiver<mojom::MediaRouter>>( + &mock_router_, router_remote.InitWithNewPipeAndPassReceiver()); EXPECT_CALL(mock_router_, OnSinkAvailabilityUpdated(_, _)); provider_ = std::make_unique<DialMediaRouteProvider>( - mojo::MakeRequest(&provider_ptr_), router_ptr.PassInterface(), + provider_remote_.BindNewPipeAndPassReceiver(), std::move(router_remote), &mock_sink_service_, connector_factory_.GetDefaultConnector(), "hash-token", base::SequencedTaskRunnerHandle::Get()); @@ -382,9 +385,9 @@ network::TestURLLoaderFactory loader_factory_; - mojom::MediaRouteProviderPtr provider_ptr_; + mojo::Remote<mojom::MediaRouteProvider> provider_remote_; MockMojoMediaRouter mock_router_; - std::unique_ptr<mojo::Binding<mojom::MediaRouter>> router_binding_; + std::unique_ptr<mojo::Receiver<mojom::MediaRouter>> router_receiver_; data_decoder::TestingJsonParser::ScopedFactoryOverride parser_override_;
diff --git a/chrome/browser/media/router/providers/extension/extension_media_route_provider_proxy.cc b/chrome/browser/media/router/providers/extension/extension_media_route_provider_proxy.cc index 86a66866..cb792a9 100644 --- a/chrome/browser/media/router/providers/extension/extension_media_route_provider_proxy.cc +++ b/chrome/browser/media/router/providers/extension/extension_media_route_provider_proxy.cc
@@ -17,18 +17,17 @@ ExtensionMediaRouteProviderProxy::ExtensionMediaRouteProviderProxy( content::BrowserContext* context) - : binding_(this), - request_manager_( + : request_manager_( EventPageRequestManagerFactory::GetApiForBrowserContext(context)) {} ExtensionMediaRouteProviderProxy::~ExtensionMediaRouteProviderProxy() = default; void ExtensionMediaRouteProviderProxy::Bind( - mojom::MediaRouteProviderRequest request) { - // This method is called when the previous Binding became invalid. We close it - // first to make sure it is in a clean state. - binding_.Close(); - binding_.Bind(std::move(request)); + mojo::PendingReceiver<mojom::MediaRouteProvider> receiver) { + // This method is called when the previous receiver became invalid. We close + // it first to make sure it is in a clean state. + receiver_.reset(); + receiver_.Bind(std::move(receiver)); } void ExtensionMediaRouteProviderProxy::CreateRoute( @@ -212,7 +211,7 @@ void ExtensionMediaRouteProviderProxy::CreateMediaRouteController( const std::string& route_id, mojo::PendingReceiver<mojom::MediaController> media_controller, - mojom::MediaStatusObserverPtr observer, + mojo::PendingRemote<mojom::MediaStatusObserver> observer, CreateMediaRouteControllerCallback callback) { request_manager_->RunOrDefer( base::BindOnce( @@ -223,9 +222,10 @@ } void ExtensionMediaRouteProviderProxy::RegisterMediaRouteProvider( - mojom::MediaRouteProviderPtr media_route_provider) { - media_route_provider_ = std::move(media_route_provider); - media_route_provider_.set_connection_error_handler( + mojo::PendingRemote<mojom::MediaRouteProvider> media_route_provider) { + media_route_provider_.reset(); + media_route_provider_.Bind(std::move(media_route_provider)); + media_route_provider_.set_disconnect_handler( base::BindOnce(&ExtensionMediaRouteProviderProxy::OnMojoConnectionError, base::Unretained(this))); request_manager_->OnMojoConnectionsReady(); @@ -383,10 +383,10 @@ void ExtensionMediaRouteProviderProxy::DoCreateMediaRouteController( const std::string& route_id, mojo::PendingReceiver<mojom::MediaController> media_controller, - mojom::MediaStatusObserverPtr observer, + mojo::PendingRemote<mojom::MediaStatusObserver> observer, CreateMediaRouteControllerCallback callback) { DVLOG(1) << "DoCreateMediaRouteController"; - if (!media_controller.is_valid() || !observer.is_bound()) + if (!media_controller.is_valid() || !observer.is_valid()) return; media_route_provider_->CreateMediaRouteController(
diff --git a/chrome/browser/media/router/providers/extension/extension_media_route_provider_proxy.h b/chrome/browser/media/router/providers/extension/extension_media_route_provider_proxy.h index 6226ad4e..1a6e75e 100644 --- a/chrome/browser/media/router/providers/extension/extension_media_route_provider_proxy.h +++ b/chrome/browser/media/router/providers/extension/extension_media_route_provider_proxy.h
@@ -7,8 +7,10 @@ #include "base/memory/weak_ptr.h" #include "chrome/common/media_router/mojom/media_router.mojom.h" -#include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/receiver.h" +#include "mojo/public/cpp/bindings/remote.h" namespace content { class BrowserContext; @@ -25,9 +27,9 @@ // the request passed into the ctor. // // Calls from this object to the component extension MRP are queued with -// EventPageRequestManager. When the extension is awake, the Mojo pointer to the +// EventPageRequestManager. When the extension is awake, the Mojo remote to the // MRP is valid, so the request is executed immediately. Otherwise, when the -// extension is awakened, this object obtains a valid Mojo pointer to the MRP +// extension is awakened, this object obtains a valid Mojo remote to the MRP // from MediaRouter, and MediaRouter makes EventPageRequestManager execute all // the requests. class ExtensionMediaRouteProviderProxy : public mojom::MediaRouteProvider { @@ -35,9 +37,9 @@ explicit ExtensionMediaRouteProviderProxy(content::BrowserContext* context); ~ExtensionMediaRouteProviderProxy() override; - // Binds |request| to |this|. If |this| is already bound to a previous - // request, that previous request will be dropped. - void Bind(mojom::MediaRouteProviderRequest request); + // Binds |receiver| to |this|. If |this| is already bound to a previous + // receiver, that previous receiver will be reset first. + void Bind(mojo::PendingReceiver<mojom::MediaRouteProvider> receiver); // mojom::MediaRouteProvider implementation. Forwards the calls to // |media_route_provider_| through |request_manager_|. @@ -89,13 +91,13 @@ void CreateMediaRouteController( const std::string& route_id, mojo::PendingReceiver<mojom::MediaController> media_controller, - mojom::MediaStatusObserverPtr observer, + mojo::PendingRemote<mojom::MediaStatusObserver> observer, CreateMediaRouteControllerCallback callback) override; // Sets the MediaRouteProvider to forward calls to. Notifies // |request_manager_| that Mojo connections are ready. void RegisterMediaRouteProvider( - mojom::MediaRouteProviderPtr media_route_provider); + mojo::PendingRemote<mojom::MediaRouteProvider> media_route_provider); // Called when a Mojo connection to the component extension is invalidated. void OnMojoConnectionError(); @@ -158,17 +160,17 @@ void DoCreateMediaRouteController( const std::string& route_id, mojo::PendingReceiver<mojom::MediaController> media_controller, - mojom::MediaStatusObserverPtr observer, + mojo::PendingRemote<mojom::MediaStatusObserver> observer, CreateMediaRouteControllerCallback callback); - // Mojo pointer to the MediaRouteProvider in the component extension. - // Set to null initially, and later set to the Mojo pointer passed in via - // RegisterMediaRouteProvider(). This is set to null again when the component + // Mojo remote to the MediaRouteProvider in the component extension. + // Set to NullRemote initially, and later set to the Mojo remote passed in via + // RegisterMediaRouteProvider(). This is set to NullRemote again when // extension is suspended or a Mojo channel error occurs. - mojom::MediaRouteProviderPtr media_route_provider_; + mojo::Remote<mojom::MediaRouteProvider> media_route_provider_; - // Binds |this| to the Mojo request passed into the ctor. - mojo::Binding<mojom::MediaRouteProvider> binding_; + // Binds |this| to the Mojo receiver passed into the ctor. + mojo::Receiver<mojom::MediaRouteProvider> receiver_{this}; // Request manager responsible for waking the component extension and calling // the requests to it.
diff --git a/chrome/browser/media/router/providers/extension/extension_media_route_provider_proxy_unittest.cc b/chrome/browser/media/router/providers/extension/extension_media_route_provider_proxy_unittest.cc index 68f1adf..2edfb157 100644 --- a/chrome/browser/media/router/providers/extension/extension_media_route_provider_proxy_unittest.cc +++ b/chrome/browser/media/router/providers/extension/extension_media_route_provider_proxy_unittest.cc
@@ -15,6 +15,9 @@ #include "chrome/browser/media/router/test/media_router_mojo_test.h" #include "chrome/test/base/testing_profile.h" #include "content/public/test/browser_task_environment.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -69,7 +72,7 @@ provider_proxy_ = std::make_unique<ExtensionMediaRouteProviderProxy>(&profile_); - provider_proxy_->Bind(mojo::MakeRequest(&provider_proxy_ptr_)); + provider_proxy_->Bind(provider_proxy_remote_.BindNewPipeAndPassReceiver()); RegisterMockMediaRouteProvider(); } @@ -81,19 +84,20 @@ false, false); std::unique_ptr<ExtensionMediaRouteProviderProxy> provider_proxy_; - mojom::MediaRouteProviderPtr provider_proxy_ptr_; + mojo::Remote<mojom::MediaRouteProvider> provider_proxy_remote_; StrictMock<MockMediaRouteProvider> mock_provider_; MockEventPageRequestManager* request_manager_ = nullptr; - std::unique_ptr<mojo::Binding<mojom::MediaRouteProvider>> binding_; + std::unique_ptr<mojo::Receiver<mojom::MediaRouteProvider>> receiver_; private: void RegisterMockMediaRouteProvider() { mock_provider_.SetRouteToReturn(route_); - mojom::MediaRouteProviderPtr mock_provider_ptr; - binding_ = std::make_unique<mojo::Binding<mojom::MediaRouteProvider>>( - &mock_provider_, mojo::MakeRequest(&mock_provider_ptr)); - provider_proxy_->RegisterMediaRouteProvider(std::move(mock_provider_ptr)); + mojo::PendingRemote<mojom::MediaRouteProvider> mock_provider_remote; + receiver_ = std::make_unique<mojo::Receiver<mojom::MediaRouteProvider>>( + &mock_provider_, mock_provider_remote.InitWithNewPipeAndPassReceiver()); + provider_proxy_->RegisterMediaRouteProvider( + std::move(mock_provider_remote)); } content::BrowserTaskEnvironment task_environment_; @@ -260,23 +264,22 @@ &MockMediaRouteProvider::CreateMediaRouteControllerSuccess))); mojo::Remote<mojom::MediaController> controller_remote; - mojom::MediaStatusObserverPtr observer_ptr; - mojom::MediaStatusObserverRequest observer_request = - mojo::MakeRequest(&observer_ptr); + mojo::PendingRemote<mojom::MediaStatusObserver> observer_remote; + ignore_result(observer_remote.InitWithNewPipeAndPassReceiver()); MockBoolCallback callback; provider_proxy_->CreateMediaRouteController( kRouteId, controller_remote.BindNewPipeAndPassReceiver(), - std::move(observer_ptr), + std::move(observer_remote), base::BindOnce(&MockBoolCallback::Run, base::Unretained(&callback))); base::RunLoop().RunUntilIdle(); } TEST_F(ExtensionMediaRouteProviderProxyTest, NotifyRequestManagerOnError) { - // Invalidating the Mojo pointer to the MRP held by the proxy should make it + // Invalidating the Mojo remote to the MRP held by the proxy should make it // notify request manager. EXPECT_CALL(*request_manager_, OnMojoConnectionError()); - binding_.reset(); + receiver_.reset(); base::RunLoop().RunUntilIdle(); }
diff --git a/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider.cc b/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider.cc index 9d442add..ed6b8d1 100644 --- a/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider.cc +++ b/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider.cc
@@ -85,10 +85,10 @@ } WiredDisplayMediaRouteProvider::WiredDisplayMediaRouteProvider( - mojom::MediaRouteProviderRequest request, - mojom::MediaRouterPtr media_router, + mojo::PendingReceiver<mojom::MediaRouteProvider> receiver, + mojo::PendingRemote<mojom::MediaRouter> media_router, Profile* profile) - : binding_(this, std::move(request)), + : receiver_(this, std::move(receiver)), media_router_(std::move(media_router)), profile_(profile) { media_router_->OnSinkAvailabilityUpdated( @@ -273,7 +273,7 @@ void WiredDisplayMediaRouteProvider::CreateMediaRouteController( const std::string& route_id, mojo::PendingReceiver<mojom::MediaController> media_controller, - mojom::MediaStatusObserverPtr observer, + mojo::PendingRemote<mojom::MediaStatusObserver> observer, CreateMediaRouteControllerCallback callback) { // Local screens do not support media controls. auto it = presentations_.find(route_id); @@ -345,21 +345,22 @@ void WiredDisplayMediaRouteProvider::Presentation::SetMojoConnections( mojo::PendingReceiver<mojom::MediaController> media_controller, - mojom::MediaStatusObserverPtr observer) { + mojo::PendingRemote<mojom::MediaStatusObserver> observer) { // This provider does not support media controls, so we do not bind // |media_controller| to a controller implementation. media_controller_receiver_ = std::move(media_controller); - media_status_observer_ = std::move(observer); + media_status_observer_.reset(); + media_status_observer_.Bind(std::move(observer)); media_status_observer_->OnMediaStatusUpdated(status_.Clone()); - media_status_observer_.set_connection_error_handler(base::BindOnce( + media_status_observer_.set_disconnect_handler(base::BindOnce( &WiredDisplayMediaRouteProvider::Presentation::ResetMojoConnections, base::Unretained(this))); } void WiredDisplayMediaRouteProvider::Presentation::ResetMojoConnections() { media_controller_receiver_.reset(); - media_status_observer_ = nullptr; + media_status_observer_.reset(); } void WiredDisplayMediaRouteProvider::NotifyRouteObservers() const {
diff --git a/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider.h b/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider.h index 58505c3f..a981723d 100644 --- a/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider.h +++ b/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider.h
@@ -18,8 +18,10 @@ #include "chrome/browser/media/router/providers/wired_display/wired_display_presentation_receiver.h" #include "chrome/common/media_router/media_route_provider_helper.h" #include "chrome/common/media_router/mojom/media_router.mojom.h" -#include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/receiver.h" +#include "mojo/public/cpp/bindings/remote.h" #include "ui/display/display.h" #include "ui/display/display_observer.h" @@ -41,9 +43,10 @@ static std::string GetRouteDescription(const std::string& media_source); - WiredDisplayMediaRouteProvider(mojom::MediaRouteProviderRequest request, - mojom::MediaRouterPtr media_router, - Profile* profile); + WiredDisplayMediaRouteProvider( + mojo::PendingReceiver<mojom::MediaRouteProvider> receiver, + mojo::PendingRemote<mojom::MediaRouter> media_router, + Profile* profile); ~WiredDisplayMediaRouteProvider() override; // mojom::MediaRouteProvider: @@ -95,7 +98,7 @@ void CreateMediaRouteController( const std::string& route_id, mojo::PendingReceiver<mojom::MediaController> media_controller, - mojom::MediaStatusObserverPtr observer, + mojo::PendingRemote<mojom::MediaStatusObserver> observer, CreateMediaRouteControllerCallback callback) override; // display::DisplayObserver: @@ -124,7 +127,7 @@ void SetMojoConnections( mojo::PendingReceiver<mojom::MediaController> media_controller, - mojom::MediaStatusObserverPtr observer); + mojo::PendingRemote<mojom::MediaStatusObserver> observer); // Resets the Mojo connections to media controller and status observer. void ResetMojoConnections(); @@ -150,7 +153,7 @@ // |media_status_observer|, when set, gets notified whenever |status| // changes. - mojom::MediaStatusObserverPtr media_status_observer_; + mojo::Remote<mojom::MediaStatusObserver> media_status_observer_; DISALLOW_COPY_AND_ASSIGN(Presentation); }; @@ -188,11 +191,11 @@ // primary display. std::vector<display::Display> GetAvailableDisplays() const; - // Binds |this| to the Mojo request passed into the ctor. - mojo::Binding<mojom::MediaRouteProvider> binding_; + // Binds |this| to the Mojo receiver passed into the ctor. + mojo::Receiver<mojom::MediaRouteProvider> receiver_; - // Mojo pointer to the Media Router. - mojom::MediaRouterPtr media_router_; + // Mojo remote to the Media Router. + mojo::Remote<mojom::MediaRouter> media_router_; // Presentation profiles are created based on this original profile. This // profile is not owned by |this|.
diff --git a/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider_unittest.cc b/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider_unittest.cc index 6920ecd5..1d648fe7 100644 --- a/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider_unittest.cc +++ b/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider_unittest.cc
@@ -13,6 +13,9 @@ #include "chrome/common/media_router/mojom/media_router.mojom.h" #include "chrome/test/base/testing_profile.h" #include "content/public/test/browser_task_environment.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -115,10 +118,11 @@ class TestWiredDisplayMediaRouteProvider : public WiredDisplayMediaRouteProvider { public: - TestWiredDisplayMediaRouteProvider(mojom::MediaRouteProviderRequest request, - mojom::MediaRouterPtr media_router, - Profile* profile) - : WiredDisplayMediaRouteProvider(std::move(request), + TestWiredDisplayMediaRouteProvider( + mojo::PendingReceiver<mojom::MediaRouteProvider> receiver, + mojo::PendingRemote<mojom::MediaRouter> media_router, + Profile* profile) + : WiredDisplayMediaRouteProvider(std::move(receiver), std::move(media_router), profile) {} ~TestWiredDisplayMediaRouteProvider() override = default; @@ -168,12 +172,12 @@ void SetUp() override { display::Screen::SetScreenInstance(&test_screen_); - mojom::MediaRouterPtr router_pointer; - router_binding_ = std::make_unique<mojo::Binding<mojom::MediaRouter>>( - &router_, mojo::MakeRequest(&router_pointer)); + mojo::PendingRemote<mojom::MediaRouter> router_pointer; + router_receiver_ = std::make_unique<mojo::Receiver<mojom::MediaRouter>>( + &router_, router_pointer.InitWithNewPipeAndPassReceiver()); provider_ = std::make_unique<TestWiredDisplayMediaRouteProvider>( - mojo::MakeRequest(&provider_pointer_), std::move(router_pointer), - &profile_); + provider_remote_.BindNewPipeAndPassReceiver(), + std::move(router_pointer), &profile_); provider_->set_primary_display(primary_display_); WiredDisplayPresentationReceiverFactory::SetCreateReceiverCallbackForTest( base::BindRepeating(&MockReceiverCreator::CreateReceiver, @@ -188,11 +192,10 @@ protected: content::BrowserTaskEnvironment task_environment_; - // A mojo pointer to |provider_|. - mojom::MediaRouteProviderPtr provider_pointer_; + mojo::Remote<mojom::MediaRouteProvider> provider_remote_; std::unique_ptr<TestWiredDisplayMediaRouteProvider> provider_; MockMojoMediaRouter router_; - std::unique_ptr<mojo::Binding<mojom::MediaRouter>> router_binding_; + std::unique_ptr<mojo::Receiver<mojom::MediaRouter>> router_receiver_; gfx::Rect primary_display_bounds_; gfx::Rect secondary_display1_bounds_; @@ -231,14 +234,14 @@ MediaRouteProviderId::WIRED_DISPLAY); EXPECT_EQ(sinks[0].sink().icon_type(), SinkIconType::WIRED_DISPLAY); }))); - provider_pointer_->StartObservingMediaSinks(kPresentationSource); + provider_remote_->StartObservingMediaSinks(kPresentationSource); base::RunLoop().RunUntilIdle(); } TEST_F(WiredDisplayMediaRouteProviderTest, NotifyOnDisplayChange) { const std::string primary_id = GetSinkId(primary_display_); const std::string secondary_id1 = GetSinkId(secondary_display1_); - provider_pointer_->StartObservingMediaSinks(kPresentationSource); + provider_remote_->StartObservingMediaSinks(kPresentationSource); base::RunLoop().RunUntilIdle(); // Add an external display. MediaRouter should be notified of the sink and the @@ -300,7 +303,7 @@ EXPECT_CALL(router_, OnSinksReceived(kProviderId, kNonPresentationSource, _, _)) .Times(0); - provider_pointer_->StartObservingMediaSinks(kNonPresentationSource); + provider_remote_->StartObservingMediaSinks(kNonPresentationSource); base::RunLoop().RunUntilIdle(); } @@ -309,7 +312,7 @@ MockCallback callback; provider_->set_all_displays({secondary_display1_, primary_display_}); - provider_pointer_->StartObservingMediaRoutes(kPresentationSource); + provider_remote_->StartObservingMediaRoutes(kPresentationSource); base::RunLoop().RunUntilIdle(); // Create a route for |presentation_id|. @@ -331,7 +334,7 @@ }))); EXPECT_CALL(*receiver_creator_.receiver(), Start(presentation_id, GURL(kPresentationSource))); - provider_pointer_->CreateRoute( + provider_remote_->CreateRoute( kPresentationSource, GetSinkId(secondary_display1_), presentation_id, url::Origin::Create(GURL(kPresentationSource)), 0, base::TimeDelta::FromSeconds(100), false, @@ -346,9 +349,9 @@ OnPresentationConnectionStateChanged( presentation_id, mojom::MediaRouter::PresentationConnectionState::TERMINATED)); - provider_pointer_->TerminateRoute( - presentation_id, base::BindOnce(&MockCallback::TerminateRoute, - base::Unretained(&callback))); + provider_remote_->TerminateRoute(presentation_id, + base::BindOnce(&MockCallback::TerminateRoute, + base::Unretained(&callback))); base::RunLoop().RunUntilIdle(); // The presentation should not be removed until the receiver's termination @@ -364,11 +367,11 @@ MockCallback callback; provider_->set_all_displays({secondary_display1_, primary_display_}); - provider_pointer_->StartObservingMediaRoutes(kPresentationSource); + provider_remote_->StartObservingMediaRoutes(kPresentationSource); base::RunLoop().RunUntilIdle(); // Create a route for |presentation_id|. - provider_pointer_->CreateRoute( + provider_remote_->CreateRoute( kPresentationSource, GetSinkId(secondary_display1_), presentation_id, url::Origin::Create(GURL(kPresentationSource)), 0, base::TimeDelta::FromSeconds(100), false, @@ -376,12 +379,12 @@ base::RunLoop().RunUntilIdle(); mojo::Remote<mojom::MediaController> media_controller_remote; - mojom::MediaStatusObserverPtr status_observer_ptr; + mojo::PendingRemote<mojom::MediaStatusObserver> status_observer_remote; MockMediaStatusObserver status_observer( - mojo::MakeRequest(&status_observer_ptr)); - provider_pointer_->CreateMediaRouteController( + status_observer_remote.InitWithNewPipeAndPassReceiver()); + provider_remote_->CreateMediaRouteController( presentation_id, media_controller_remote.BindNewPipeAndPassReceiver(), - std::move(status_observer_ptr), base::BindOnce([](bool success) {})); + std::move(status_observer_remote), base::BindOnce([](bool success) {})); EXPECT_CALL(status_observer, OnMediaStatusUpdated(_)) .WillOnce(Invoke([&page_title](mojom::MediaStatusPtr status) { @@ -394,10 +397,10 @@ TEST_F(WiredDisplayMediaRouteProviderTest, ExitFullscreenOnDisplayRemoved) { MockCallback callback; provider_->set_all_displays({secondary_display1_, primary_display_}); - provider_pointer_->StartObservingMediaRoutes(kPresentationSource); + provider_remote_->StartObservingMediaRoutes(kPresentationSource); base::RunLoop().RunUntilIdle(); - provider_pointer_->CreateRoute( + provider_remote_->CreateRoute( kPresentationSource, GetSinkId(secondary_display1_), "presentationId", url::Origin::Create(GURL(kPresentationSource)), 0, base::TimeDelta::FromSeconds(100), false,
diff --git a/chrome/browser/media/router/test/media_router_mojo_test.cc b/chrome/browser/media/router/test/media_router_mojo_test.cc index cc7594a0..2a1a844 100644 --- a/chrome/browser/media/router/test/media_router_mojo_test.cc +++ b/chrome/browser/media/router/test/media_router_mojo_test.cc
@@ -116,8 +116,8 @@ } MockMediaStatusObserver::MockMediaStatusObserver( - mojom::MediaStatusObserverRequest request) - : binding_(this, std::move(request)) {} + mojo::PendingReceiver<mojom::MediaStatusObserver> receiver) + : receiver_(this, std::move(receiver)) {} MockMediaStatusObserver::~MockMediaStatusObserver() {} @@ -395,8 +395,9 @@ void MediaRouterMojoTest::RegisterMediaRouteProvider( mojom::MediaRouteProvider* provider, MediaRouteProviderId provider_id) { - mojom::MediaRouteProviderPtr mojo_provider; - provider_bindings_.AddBinding(provider, mojo::MakeRequest(&mojo_provider)); + mojo::PendingRemote<mojom::MediaRouteProvider> mojo_provider; + provider_receivers_.Add(provider, + mojo_provider.InitWithNewPipeAndPassReceiver()); media_router_->RegisterMediaRouteProvider( provider_id, std::move(mojo_provider), base::BindOnce([](const std::string& instance_id,
diff --git a/chrome/browser/media/router/test/media_router_mojo_test.h b/chrome/browser/media/router/test/media_router_mojo_test.h index b0d49a61..d12a3d3 100644 --- a/chrome/browser/media/router/test/media_router_mojo_test.h +++ b/chrome/browser/media/router/test/media_router_mojo_test.h
@@ -21,10 +21,10 @@ #include "content/public/test/browser_task_environment.h" #include "extensions/browser/event_page_tracker.h" #include "extensions/common/extension.h" -#include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/receiver.h" +#include "mojo/public/cpp/bindings/receiver_set.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -144,7 +144,7 @@ void CreateMediaRouteController( const std::string& route_id, mojo::PendingReceiver<mojom::MediaController> media_controller, - mojom::MediaStatusObserverPtr observer, + mojo::PendingRemote<mojom::MediaStatusObserver> observer, CreateMediaRouteControllerCallback callback) override { CreateMediaRouteControllerInternal(route_id, media_controller, observer, callback); @@ -153,7 +153,7 @@ CreateMediaRouteControllerInternal, void(const std::string& route_id, mojo::PendingReceiver<mojom::MediaController>& media_controller, - mojom::MediaStatusObserverPtr& observer, + mojo::PendingRemote<mojom::MediaStatusObserver>& observer, CreateMediaRouteControllerCallback& callback)); // These methods execute the callbacks with the success or timeout result @@ -209,13 +209,14 @@ class MockMediaStatusObserver : public mojom::MediaStatusObserver { public: - explicit MockMediaStatusObserver(mojom::MediaStatusObserverRequest request); + explicit MockMediaStatusObserver( + mojo::PendingReceiver<mojom::MediaStatusObserver> receiver); ~MockMediaStatusObserver() override; MOCK_METHOD1(OnMediaStatusUpdated, void(mojom::MediaStatusPtr status)); private: - mojo::Binding<mojom::MediaStatusObserver> binding_; + mojo::Receiver<mojom::MediaStatusObserver> receiver_; }; class MockMediaController : public mojom::MediaController { @@ -297,7 +298,7 @@ scoped_refptr<const extensions::Extension> extension_; TestingProfile profile_; std::unique_ptr<MediaRouterMojoImpl> media_router_; - mojo::BindingSet<mojom::MediaRouteProvider> provider_bindings_; + mojo::ReceiverSet<mojom::MediaRouteProvider> provider_receivers_; std::unique_ptr<MediaRoutesObserver> routes_observer_; std::unique_ptr<MockMediaSinksObserver> sinks_observer_;
diff --git a/chrome/browser/media/router/test/mock_media_router.h b/chrome/browser/media/router/test/mock_media_router.h index cf2b3c48..495a9c2c 100644 --- a/chrome/browser/media/router/test/mock_media_router.h +++ b/chrome/browser/media/router/test/mock_media_router.h
@@ -15,6 +15,8 @@ #include "chrome/common/media_router/media_route.h" #include "chrome/common/media_router/media_sink.h" #include "chrome/common/media_router/media_source.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #include "testing/gmock/include/gmock/gmock.h" #include "url/origin.h" @@ -135,7 +137,7 @@ MOCK_METHOD3(GetMediaController, void(const MediaRoute::Id& route_id, mojo::PendingReceiver<mojom::MediaController> controller, - mojom::MediaStatusObserverPtr observer)); + mojo::PendingRemote<mojom::MediaStatusObserver> observer)); #endif // !defined(OS_ANDROID) MOCK_METHOD1(OnAddPresentationConnectionStateChangedCallbackInvoked, void(const content::PresentationConnectionStateChangedCallback&
diff --git a/chrome/browser/media/router/test/mock_mojo_media_router.h b/chrome/browser/media/router/test/mock_mojo_media_router.h index 71f92bb..5793955d 100644 --- a/chrome/browser/media/router/test/mock_mojo_media_router.h +++ b/chrome/browser/media/router/test/mock_mojo_media_router.h
@@ -9,6 +9,7 @@ #include "chrome/common/media_router/media_route_provider_helper.h" #include "chrome/common/media_router/mojom/media_router.mojom.h" #include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #include "testing/gmock/include/gmock/gmock.h" namespace media_router { @@ -21,14 +22,15 @@ // mojom::MediaRouter overrides: void RegisterMediaRouteProvider( MediaRouteProviderId provider_id, - mojom::MediaRouteProviderPtr provider_ptr, + mojo::PendingRemote<mojom::MediaRouteProvider> provider_remote, RegisterMediaRouteProviderCallback callback) override { - RegisterMediaRouteProviderInternal(provider_id, provider_ptr, callback); + RegisterMediaRouteProviderInternal(provider_id, provider_remote, callback); } - MOCK_METHOD3(RegisterMediaRouteProviderInternal, - void(MediaRouteProviderId provider_id, - mojom::MediaRouteProviderPtr& provider_ptr, - RegisterMediaRouteProviderCallback& callback)); + MOCK_METHOD3( + RegisterMediaRouteProviderInternal, + void(MediaRouteProviderId provider_id, + mojo::PendingRemote<mojom::MediaRouteProvider>& provider_remote, + RegisterMediaRouteProviderCallback& callback)); MOCK_METHOD1(OnIssue, void(const IssueInfo& issue)); MOCK_METHOD4(OnSinksReceived, void(MediaRouteProviderId provider_id,
diff --git a/chrome/browser/media/webrtc/webrtc_getdisplaymedia_browsertest.cc b/chrome/browser/media/webrtc/webrtc_getdisplaymedia_browsertest.cc index 85d08ce..44027f5 100644 --- a/chrome/browser/media/webrtc/webrtc_getdisplaymedia_browsertest.cc +++ b/chrome/browser/media/webrtc/webrtc_getdisplaymedia_browsertest.cc
@@ -37,7 +37,8 @@ } void RunGetDisplayMedia(content::WebContents* tab, - const std::string& constraints) { + const std::string& constraints, + bool is_fake_ui = false) { std::string result; EXPECT_TRUE(content::ExecuteScriptAndExtractString( tab->GetMainFrame(), @@ -45,9 +46,11 @@ &result)); #if defined(OS_MACOSX) // Starting from macOS 10.15, screen capture requires system permissions - // that are disabled by default. - EXPECT_EQ(result, base::mac::IsAtMostOS10_14() ? "getdisplaymedia-success" - : "getdisplaymedia-failure"); + // that are disabled by default. The permission is reported as granted + // if the fake UI is used. + EXPECT_EQ(result, base::mac::IsAtMostOS10_14() || is_fake_ui + ? "getdisplaymedia-success" + : "getdisplaymedia-failure"); #else EXPECT_EQ(result, "getdisplaymedia-success"); #endif @@ -133,7 +136,7 @@ content::WebContents* tab = OpenTestPageInNewTab(kMainHtmlPage); std::string constraints("{video:true}"); - RunGetDisplayMedia(tab, constraints); + RunGetDisplayMedia(tab, constraints, /*is_fake_ui=*/true); std::string result; EXPECT_TRUE(content::ExecuteScriptAndExtractString( @@ -155,7 +158,7 @@ content::WebContents* tab = OpenTestPageInNewTab(kMainHtmlPage); std::string constraints("{video:true, audio:true}"); - RunGetDisplayMedia(tab, constraints); + RunGetDisplayMedia(tab, constraints, /*is_fake_ui=*/true); std::string result; EXPECT_TRUE(content::ExecuteScriptAndExtractString( @@ -173,7 +176,7 @@ const std::string& constraints = base::StringPrintf("{video: {width: {max: %d}, frameRate: {max: %d}}}", kMaxWidth, kMaxFrameRate); - RunGetDisplayMedia(tab, constraints); + RunGetDisplayMedia(tab, constraints, /*is_fake_ui=*/true); std::string result; EXPECT_TRUE(content::ExecuteScriptAndExtractString(
diff --git a/chrome/browser/metrics/process_memory_metrics_emitter_browsertest.cc b/chrome/browser/metrics/process_memory_metrics_emitter_browsertest.cc index 74c0724..cbeaee6 100644 --- a/chrome/browser/metrics/process_memory_metrics_emitter_browsertest.cc +++ b/chrome/browser/metrics/process_memory_metrics_emitter_browsertest.cc
@@ -44,6 +44,7 @@ namespace { +using base::trace_event::MemoryDumpDeterminism; using base::trace_event::MemoryDumpType; using memory_instrumentation::GlobalMemoryDump; using memory_instrumentation::mojom::ProcessType; @@ -88,6 +89,7 @@ memory_instrumentation::MemoryInstrumentation::GetInstance() ->RequestGlobalDumpAndAppendToTrace( MemoryDumpType::EXPLICITLY_TRIGGERED, explicit_dump_type, + MemoryDumpDeterminism::NONE, Bind(&RequestGlobalDumpCallback, quit_closure)); }
diff --git a/chrome/browser/net/system_network_context_manager.cc b/chrome/browser/net/system_network_context_manager.cc index 7fb3154..95964da 100644 --- a/chrome/browser/net/system_network_context_manager.cc +++ b/chrome/browser/net/system_network_context_manager.cc
@@ -476,6 +476,9 @@ pref_change_registrar_.Add(prefs::kKerberosEnabled, auth_pref_callback); #endif // defined(OS_CHROMEOS) + local_state_->SetDefaultPrefValue( + prefs::kEnableReferrers, + base::Value(!base::FeatureList::IsEnabled(features::kNoReferrers))); enable_referrers_.Init( prefs::kEnableReferrers, local_state_, base::BindRepeating(&SystemNetworkContextManager::UpdateReferrersEnabled,
diff --git a/chrome/browser/net/system_network_context_manager_browsertest.cc b/chrome/browser/net/system_network_context_manager_browsertest.cc index f6f7da5..c283951c 100644 --- a/chrome/browser/net/system_network_context_manager_browsertest.cc +++ b/chrome/browser/net/system_network_context_manager_browsertest.cc
@@ -20,7 +20,6 @@ #include "chrome/test/base/in_process_browser_test.h" #include "components/prefs/pref_service.h" #include "components/version_info/version_info.h" -#include "content/public/common/content_switches.h" #include "content/public/common/user_agent.h" #include "services/network/public/cpp/network_service_buildflags.h" #include "services/network/public/mojom/network_context.mojom.h" @@ -295,6 +294,36 @@ SystemNetworkContextManagerStubResolverBrowsertest, ::testing::Bool()); +class SystemNetworkContextManagerReferrersFeatureBrowsertest + : public SystemNetworkContextManagerBrowsertest, + public testing::WithParamInterface<bool> { + public: + SystemNetworkContextManagerReferrersFeatureBrowsertest() { + scoped_feature_list_.InitWithFeatureState(features::kNoReferrers, + GetParam()); + } + ~SystemNetworkContextManagerReferrersFeatureBrowsertest() override {} + + void SetUpOnMainThread() override {} + + private: + base::test::ScopedFeatureList scoped_feature_list_; +}; + +// Tests that toggling the kNoReferrers feature correctly changes the default +// value of the kEnableReferrers pref. +IN_PROC_BROWSER_TEST_P(SystemNetworkContextManagerReferrersFeatureBrowsertest, + TestDefaultReferrerReflectsFeatureValue) { + ASSERT_TRUE(!!g_browser_process); + PrefService* local_state = g_browser_process->local_state(); + ASSERT_TRUE(!!local_state); + EXPECT_NE(local_state->GetBoolean(prefs::kEnableReferrers), GetParam()); +} + +INSTANTIATE_TEST_SUITE_P(, + SystemNetworkContextManagerReferrersFeatureBrowsertest, + ::testing::Bool()); + class SystemNetworkContextManagerFreezeQUICUaBrowsertest : public SystemNetworkContextManagerBrowsertest, public testing::WithParamInterface<bool> {
diff --git a/chrome/browser/performance_manager/decorators/page_almost_idle_decorator.cc b/chrome/browser/performance_manager/decorators/page_almost_idle_decorator.cc index c6fa924..1493559 100644 --- a/chrome/browser/performance_manager/decorators/page_almost_idle_decorator.cc +++ b/chrome/browser/performance_manager/decorators/page_almost_idle_decorator.cc
@@ -81,12 +81,9 @@ UpdateLoadIdleStatePage(PageNodeImpl::FromNode(page_node)); } -void PageAlmostIdleDecorator::OnMainFrameNavigationCommitted( +void PageAlmostIdleDecorator::OnMainFrameDocumentChanged( const PageNode* page_node) { - // Filter out the initial visible URL notification. - if (page_node->GetNavigationID() == 0) - return; - + DCHECK_NE(0, page_node->GetNavigationID()); // Reset the load-idle state associated with this page as a new navigation has // started. auto* page_impl = PageNodeImpl::FromNode(page_node);
diff --git a/chrome/browser/performance_manager/decorators/page_almost_idle_decorator.h b/chrome/browser/performance_manager/decorators/page_almost_idle_decorator.h index fd6a2c2..1edc9ad 100644 --- a/chrome/browser/performance_manager/decorators/page_almost_idle_decorator.h +++ b/chrome/browser/performance_manager/decorators/page_almost_idle_decorator.h
@@ -41,7 +41,7 @@ // PageNodeObserver implementation: void OnIsLoadingChanged(const PageNode* page_node) override; - void OnMainFrameNavigationCommitted(const PageNode* page_node) override; + void OnMainFrameDocumentChanged(const PageNode* page_node) override; // ProcessNodeObserver implementation: void OnMainThreadTaskLoadIsLow(const ProcessNode* process_node) override;
diff --git a/chrome/browser/performance_manager/decorators/page_almost_idle_decorator_unittest.cc b/chrome/browser/performance_manager/decorators/page_almost_idle_decorator_unittest.cc index 3c1f6f6..727f1ec 100644 --- a/chrome/browser/performance_manager/decorators/page_almost_idle_decorator_unittest.cc +++ b/chrome/browser/performance_manager/decorators/page_almost_idle_decorator_unittest.cc
@@ -127,7 +127,7 @@ EXPECT_FALSE(Data::GetForTesting(page_node)); // Post a navigation. The state should reset. - page_node->OnMainFrameNavigationCommitted(base::TimeTicks::Now(), 1, + page_node->OnMainFrameNavigationCommitted(false, base::TimeTicks::Now(), 1, GURL("https://www.example.org")); page_data = Data::GetForTesting(page_node); EXPECT_EQ(LIS::kLoadingNotStarted, page_data->load_idle_state_);
diff --git a/chrome/browser/performance_manager/graph/node_base.h b/chrome/browser/performance_manager/graph/node_base.h index 4743184..82085f1 100644 --- a/chrome/browser/performance_manager/graph/node_base.h +++ b/chrome/browser/performance_manager/graph/node_base.h
@@ -12,7 +12,6 @@ #include "base/callback.h" #include "base/macros.h" -#include "base/observer_list.h" #include "base/sequence_checker.h" #include "chrome/browser/performance_manager/graph/graph_impl.h" #include "chrome/browser/performance_manager/graph/node_type.h"
diff --git a/chrome/browser/performance_manager/graph/page_node_impl.cc b/chrome/browser/performance_manager/graph/page_node_impl.cc index 9464407..ff6b5e45 100644 --- a/chrome/browser/performance_manager/graph/page_node_impl.cc +++ b/chrome/browser/performance_manager/graph/page_node_impl.cc
@@ -19,11 +19,13 @@ PageNodeImpl::PageNodeImpl(GraphImpl* graph, const WebContentsProxy& contents_proxy, const std::string& browser_context_id, + const GURL& visible_url, bool is_visible, bool is_audible) : TypedNodeBase(graph), contents_proxy_(contents_proxy), visibility_change_time_(base::TimeTicks::Now()), + main_frame_url_(visible_url), browser_context_id_(browser_context_id), is_visible_(is_visible), is_audible_(is_audible) { @@ -97,15 +99,25 @@ } void PageNodeImpl::OnMainFrameNavigationCommitted( + bool same_document, base::TimeTicks navigation_committed_time, int64_t navigation_id, const GURL& url) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + // This should never be invoked with a null navigation, nor should it be + // called twice for the same navigation. + DCHECK_NE(0, navigation_id); + DCHECK_NE(navigation_id_, navigation_id); navigation_committed_time_ = navigation_committed_time; - main_frame_url_ = url; navigation_id_ = navigation_id; + main_frame_url_.SetAndMaybeNotify(this, url); + + // No mainframe document change notification on same-document navigations. + if (same_document) + return; + for (auto* observer : GetObservers()) - observer->OnMainFrameNavigationCommitted(this); + observer->OnMainFrameDocumentChanged(this); } double PageNodeImpl::GetCPUUsage() const { @@ -215,7 +227,7 @@ const GURL& PageNodeImpl::main_frame_url() const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - return main_frame_url_; + return main_frame_url_.value(); } int64_t PageNodeImpl::navigation_id() const {
diff --git a/chrome/browser/performance_manager/graph/page_node_impl.h b/chrome/browser/performance_manager/graph/page_node_impl.h index 45655ae..351cb1d 100644 --- a/chrome/browser/performance_manager/graph/page_node_impl.h +++ b/chrome/browser/performance_manager/graph/page_node_impl.h
@@ -31,6 +31,7 @@ PageNodeImpl(GraphImpl* graph, const WebContentsProxy& contents_proxy, const std::string& browser_context_id, + const GURL& visible_url, bool is_visible, bool is_audible); ~PageNodeImpl() override; @@ -46,7 +47,8 @@ void SetUkmSourceId(ukm::SourceId ukm_source_id); void OnFaviconUpdated(); void OnTitleUpdated(); - void OnMainFrameNavigationCommitted(base::TimeTicks navigation_committed_time, + void OnMainFrameNavigationCommitted(bool same_document, + base::TimeTicks navigation_committed_time, int64_t navigation_id, const GURL& url); @@ -174,7 +176,10 @@ // The URL the main frame last committed, or the initial URL a page was // initialized with. The latter case is distinguished by a zero navigation ID. - GURL main_frame_url_; + ObservedProperty:: + NotifiesOnlyOnChanges<GURL, &PageNodeObserver::OnMainFrameUrlChanged> + main_frame_url_; + // The unique ID of the navigation handle the main frame last committed, or // zero if the page has never committed a navigation. int64_t navigation_id_ = 0;
diff --git a/chrome/browser/performance_manager/graph/page_node_impl_unittest.cc b/chrome/browser/performance_manager/graph/page_node_impl_unittest.cc index 7e6be0fe..f4b889e 100644 --- a/chrome/browser/performance_manager/graph/page_node_impl_unittest.cc +++ b/chrome/browser/performance_manager/graph/page_node_impl_unittest.cc
@@ -123,8 +123,8 @@ // 1st navigation. GURL url("http://www.example.org"); - mock_graph.page->OnMainFrameNavigationCommitted(base::TimeTicks::Now(), 10u, - url); + mock_graph.page->OnMainFrameNavigationCommitted(false, base::TimeTicks::Now(), + 10u, url); EXPECT_EQ(url, mock_graph.page->main_frame_url()); EXPECT_EQ(10u, mock_graph.page->navigation_id()); AdvanceClock(base::TimeDelta::FromSeconds(11)); @@ -133,13 +133,23 @@ // 2nd navigation. url = GURL("http://www.example.org/bobcat"); - mock_graph.page->OnMainFrameNavigationCommitted(base::TimeTicks::Now(), 20u, - url); + mock_graph.page->OnMainFrameNavigationCommitted(false, base::TimeTicks::Now(), + 20u, url); EXPECT_EQ(url, mock_graph.page->main_frame_url()); EXPECT_EQ(20u, mock_graph.page->navigation_id()); AdvanceClock(base::TimeDelta::FromSeconds(17)); EXPECT_EQ(base::TimeDelta::FromSeconds(17), mock_graph.page->TimeSinceLastNavigation()); + + // Test a same-document navigation. + url = GURL("http://www.example.org/bobcat#fun"); + mock_graph.page->OnMainFrameNavigationCommitted(true, base::TimeTicks::Now(), + 30u, url); + EXPECT_EQ(url, mock_graph.page->main_frame_url()); + EXPECT_EQ(30u, mock_graph.page->navigation_id()); + AdvanceClock(base::TimeDelta::FromSeconds(17)); + EXPECT_EQ(base::TimeDelta::FromSeconds(17), + mock_graph.page->TimeSinceLastNavigation()); } TEST_F(PageNodeImplTest, BrowserContextID) { @@ -188,8 +198,9 @@ MOCK_METHOD1(OnUkmSourceIdChanged, void(const PageNode*)); MOCK_METHOD1(OnPageLifecycleStateChanged, void(const PageNode*)); MOCK_METHOD1(OnPageOriginTrialFreezePolicyChanged, void(const PageNode*)); + MOCK_METHOD1(OnMainFrameUrlChanged, void(const PageNode*)); MOCK_METHOD1(OnPageAlmostIdleChanged, void(const PageNode*)); - MOCK_METHOD1(OnMainFrameNavigationCommitted, void(const PageNode*)); + MOCK_METHOD1(OnMainFrameDocumentChanged, void(const PageNode*)); MOCK_METHOD1(OnTitleUpdated, void(const PageNode*)); MOCK_METHOD1(OnFaviconUpdated, void(const PageNode*)); @@ -257,10 +268,19 @@ page_node->SetPageAlmostIdleForTesting(true); EXPECT_EQ(raw_page_node, obs.TakeNotifiedPageNode()); - EXPECT_CALL(obs, OnMainFrameNavigationCommitted(_)) + const GURL kTestUrl = GURL("https://foo.com/"); + int64_t navigation_id = 0x1234; + EXPECT_CALL(obs, OnMainFrameUrlChanged(_)) .WillOnce(Invoke(&obs, &MockObserver::SetNotifiedPageNode)); - page_node->OnMainFrameNavigationCommitted(base::TimeTicks::Now(), 0x1234ull, - GURL("https://foo.com/")); + // Expect no OnMainFrameDocumentChanged for same-document navigation + page_node->OnMainFrameNavigationCommitted(true, base::TimeTicks::Now(), + ++navigation_id, kTestUrl); + EXPECT_EQ(raw_page_node, obs.TakeNotifiedPageNode()); + + EXPECT_CALL(obs, OnMainFrameDocumentChanged(_)) + .WillOnce(Invoke(&obs, &MockObserver::SetNotifiedPageNode)); + page_node->OnMainFrameNavigationCommitted(false, base::TimeTicks::Now(), + ++navigation_id, kTestUrl); EXPECT_EQ(raw_page_node, obs.TakeNotifiedPageNode()); EXPECT_CALL(obs, OnTitleUpdated(_))
diff --git a/chrome/browser/performance_manager/observers/metrics_collector_unittest.cc b/chrome/browser/performance_manager/observers/metrics_collector_unittest.cc index b9171c0..e4b5777 100644 --- a/chrome/browser/performance_manager/observers/metrics_collector_unittest.cc +++ b/chrome/browser/performance_manager/observers/metrics_collector_unittest.cc
@@ -57,8 +57,8 @@ TEST_F(MAYBE_MetricsCollectorTest, FromBackgroundedToFirstTitleUpdatedUMA) { auto page_node = CreateNode<PageNodeImpl>(); - page_node->OnMainFrameNavigationCommitted(base::TimeTicks::Now(), kDummyID, - kDummyUrl); + page_node->OnMainFrameNavigationCommitted(false, base::TimeTicks::Now(), + kDummyID, kDummyUrl); AdvanceClock(kTestMetricsReportDelayTimeout); page_node->SetIsVisible(true); @@ -90,8 +90,8 @@ FromBackgroundedToFirstTitleUpdatedUMA5MinutesTimeout) { auto page_node = CreateNode<PageNodeImpl>(); - page_node->OnMainFrameNavigationCommitted(base::TimeTicks::Now(), kDummyID, - kDummyUrl); + page_node->OnMainFrameNavigationCommitted(false, base::TimeTicks::Now(), + kDummyID, kDummyUrl); page_node->SetIsVisible(false); page_node->OnTitleUpdated(); // The page is within 5 minutes after main frame navigation was committed, @@ -111,8 +111,8 @@ auto frame_node = CreateNode<FrameNodeImpl>(process_node.get(), page_node.get()); - page_node->OnMainFrameNavigationCommitted(base::TimeTicks::Now(), kDummyID, - kDummyUrl); + page_node->OnMainFrameNavigationCommitted(false, base::TimeTicks::Now(), + kDummyID, kDummyUrl); AdvanceClock(kTestMetricsReportDelayTimeout); page_node->SetIsVisible(true); @@ -148,8 +148,8 @@ auto frame_node = CreateNode<FrameNodeImpl>(process_node.get(), page_node.get()); - page_node->OnMainFrameNavigationCommitted(base::TimeTicks::Now(), kDummyID, - kDummyUrl); + page_node->OnMainFrameNavigationCommitted(false, base::TimeTicks::Now(), + kDummyID, kDummyUrl); page_node->SetIsVisible(false); frame_node->OnNonPersistentNotificationCreated(); // The page is within 5 minutes after main frame navigation was committed, @@ -165,8 +165,8 @@ TEST_F(MAYBE_MetricsCollectorTest, FromBackgroundedToFirstFaviconUpdatedUMA) { auto page_node = CreateNode<PageNodeImpl>(); - page_node->OnMainFrameNavigationCommitted(base::TimeTicks::Now(), kDummyID, - kDummyUrl); + page_node->OnMainFrameNavigationCommitted(false, base::TimeTicks::Now(), + kDummyID, kDummyUrl); AdvanceClock(kTestMetricsReportDelayTimeout); page_node->SetIsVisible(true); @@ -198,8 +198,8 @@ FromBackgroundedToFirstFaviconUpdatedUMA5MinutesTimeout) { auto page_node = CreateNode<PageNodeImpl>(); - page_node->OnMainFrameNavigationCommitted(base::TimeTicks::Now(), kDummyID, - kDummyUrl); + page_node->OnMainFrameNavigationCommitted(false, base::TimeTicks::Now(), + kDummyID, kDummyUrl); page_node->SetIsVisible(false); page_node->OnFaviconUpdated(); // The page is within 5 minutes after main frame navigation was committed, @@ -226,8 +226,8 @@ GURL url = GURL("https://google.com/foobar"); ukm_recorder.UpdateSourceURL(id, url); page_node->SetUkmSourceId(id); - page_node->OnMainFrameNavigationCommitted(base::TimeTicks::Now(), kDummyID, - kDummyUrl); + page_node->OnMainFrameNavigationCommitted(false, base::TimeTicks::Now(), + kDummyID, kDummyUrl); for (int count = 1; count < kDefaultFrequencyUkmEQTReported; ++count) { process_node->SetExpectedTaskQueueingDuration(
diff --git a/chrome/browser/performance_manager/performance_manager_impl.cc b/chrome/browser/performance_manager/performance_manager_impl.cc index db5ba4d5..1a91fbf 100644 --- a/chrome/browser/performance_manager/performance_manager_impl.cc +++ b/chrome/browser/performance_manager/performance_manager_impl.cc
@@ -155,11 +155,12 @@ std::unique_ptr<PageNodeImpl> PerformanceManagerImpl::CreatePageNode( const WebContentsProxy& contents_proxy, const std::string& browser_context_id, + const GURL& visible_url, bool is_visible, bool is_audible) { return CreateNodeImpl<PageNodeImpl>(base::OnceCallback<void(PageNodeImpl*)>(), contents_proxy, browser_context_id, - is_visible, is_audible); + visible_url, is_visible, is_audible); } std::unique_ptr<ProcessNodeImpl> PerformanceManagerImpl::CreateProcessNode(
diff --git a/chrome/browser/performance_manager/performance_manager_impl.h b/chrome/browser/performance_manager/performance_manager_impl.h index ef5d135..f06e3dbe 100644 --- a/chrome/browser/performance_manager/performance_manager_impl.h +++ b/chrome/browser/performance_manager/performance_manager_impl.h
@@ -93,6 +93,7 @@ std::unique_ptr<PageNodeImpl> CreatePageNode( const WebContentsProxy& contents_proxy, const std::string& browser_context_id, + const GURL& visible_url, bool is_visible, bool is_audible); std::unique_ptr<ProcessNodeImpl> CreateProcessNode(
diff --git a/chrome/browser/performance_manager/performance_manager_impl_unittest.cc b/chrome/browser/performance_manager/performance_manager_impl_unittest.cc index 437ef18..3f92688 100644 --- a/chrome/browser/performance_manager/performance_manager_impl_unittest.cc +++ b/chrome/browser/performance_manager/performance_manager_impl_unittest.cc
@@ -60,7 +60,7 @@ EXPECT_NE(nullptr, process_node.get()); std::unique_ptr<PageNodeImpl> page_node = performance_manager()->CreatePageNode(WebContentsProxy(), std::string(), - false, false); + GURL(), false, false); EXPECT_NE(nullptr, page_node.get()); // Create a node of each type. @@ -81,7 +81,7 @@ performance_manager()->CreateProcessNode(RenderProcessHostProxy()); std::unique_ptr<PageNodeImpl> page_node = performance_manager()->CreatePageNode(WebContentsProxy(), std::string(), - false, false); + GURL(), false, false); std::unique_ptr<FrameNodeImpl> parent1_frame = performance_manager()->CreateFrameNode( @@ -125,7 +125,7 @@ // Create a page node for something to target. std::unique_ptr<PageNodeImpl> page_node = performance_manager()->CreatePageNode(WebContentsProxy(), std::string(), - false, false); + GURL(), false, false); base::RunLoop run_loop; base::OnceClosure quit_closure = run_loop.QuitClosure(); EXPECT_FALSE(performance_manager()->OnPMTaskRunnerForTesting()); @@ -147,7 +147,7 @@ // Create a page node for something to target. std::unique_ptr<PageNodeImpl> page_node = performance_manager()->CreatePageNode(WebContentsProxy(), std::string(), - false, false); + GURL(), false, false); base::RunLoop run_loop; EXPECT_FALSE(performance_manager()->OnPMTaskRunnerForTesting());
diff --git a/chrome/browser/performance_manager/performance_manager_tab_helper.cc b/chrome/browser/performance_manager/performance_manager_tab_helper.cc index b0de4ac..0b99637 100644 --- a/chrome/browser/performance_manager/performance_manager_tab_helper.cc +++ b/chrome/browser/performance_manager/performance_manager_tab_helper.cc
@@ -46,21 +46,9 @@ page_node_ = performance_manager_->CreatePageNode( WebContentsProxy(weak_factory_.GetWeakPtr()), web_contents->GetBrowserContext()->UniqueId(), + web_contents->GetVisibleURL(), web_contents->GetVisibility() == content::Visibility::VISIBLE, web_contents->IsCurrentlyAudible()); - - // Set the initial (visible) URL of the page early. In the rare and unlikely - // case the main frame has been navigated, this URL will be overridden with - // the main frame's last committed URL and navigation ID in the loop below. - GURL visible_url = web_contents->GetVisibleURL(); - if (visible_url.is_valid()) { - // Post the visible URL as a navigation to the zero navigation ID. - constexpr int64_t kZeroNavigationId = 0; - PostToGraph(FROM_HERE, &PageNodeImpl::OnMainFrameNavigationCommitted, - page_node_.get(), base::TimeTicks::Now(), kZeroNavigationId, - visible_url); - } - // Dispatch creation notifications for any pre-existing frames. std::vector<content::RenderFrameHost*> existing_frames = web_contents->GetAllFrames(); @@ -286,17 +274,16 @@ PostToGraph(FROM_HERE, &FrameNodeImpl::OnNavigationCommitted, frame_node, url, navigation_handle->IsSameDocument()); - if (navigation_handle->IsSameDocument() || - !navigation_handle->IsInMainFrame()) { + if (!navigation_handle->IsInMainFrame()) return; - } // Make sure the hierarchical structure is constructed before sending signal // to the performance manager. OnMainFrameNavigation(navigation_handle->GetNavigationId()); PostToGraph(FROM_HERE, &PageNodeImpl::OnMainFrameNavigationCommitted, - page_node_.get(), navigation_committed_time, - navigation_handle->GetNavigationId(), url); + page_node_.get(), navigation_handle->IsSameDocument(), + navigation_committed_time, navigation_handle->GetNavigationId(), + url); } void PerformanceManagerTabHelper::TitleWasSet(content::NavigationEntry* entry) {
diff --git a/chrome/browser/performance_manager/public/graph/page_node.h b/chrome/browser/performance_manager/public/graph/page_node.h index 7b82daf..1e82e2e9 100644 --- a/chrome/browser/performance_manager/public/graph/page_node.h +++ b/chrome/browser/performance_manager/public/graph/page_node.h
@@ -140,16 +140,16 @@ virtual void OnPageOriginTrialFreezePolicyChanged( const PageNode* page_node) = 0; + // Invoked when the MainFrameUrl property changes. + virtual void OnMainFrameUrlChanged(const PageNode* page_node) = 0; + // Invoked when the PageAlmostIdle property changes. virtual void OnPageAlmostIdleChanged(const PageNode* page_node) = 0; - // This is fired when a main frame navigation commits. It indicates that the - // |main_frame_url| and possibly the |navigation_id| properties have changed. - // Prior to loading and initial navigation of page, the |main_frame_url| can - // change, while the |navigation_id| stays zero. - // TODO(siggi): Maybe #hash navigation can work the same way, or perhaps the - // two each properties deserve their own notification? - virtual void OnMainFrameNavigationCommitted(const PageNode* page_node) = 0; + // This is fired when a non-same document navigation commits in the main + // frame. It indicates that the the |NavigationId| property and possibly the + // |MainFrameUrl| properties have changed. + virtual void OnMainFrameDocumentChanged(const PageNode* page_node) = 0; // Events with no property changes. @@ -184,7 +184,8 @@ void OnPageOriginTrialFreezePolicyChanged( const PageNode* page_node) override {} void OnPageAlmostIdleChanged(const PageNode* page_node) override {} - void OnMainFrameNavigationCommitted(const PageNode* page_node) override {} + void OnMainFrameUrlChanged(const PageNode* page_node) override {} + void OnMainFrameDocumentChanged(const PageNode* page_node) override {} void OnTitleUpdated(const PageNode* page_node) override {} void OnFaviconUpdated(const PageNode* page_node) override {}
diff --git a/chrome/browser/performance_manager/test_support/graph_test_harness.h b/chrome/browser/performance_manager/test_support/graph_test_harness.h index 0e22103..c517e0e 100644 --- a/chrome/browser/performance_manager/test_support/graph_test_harness.h +++ b/chrome/browser/performance_manager/test_support/graph_test_harness.h
@@ -107,10 +107,11 @@ GraphImpl* graph, const WebContentsProxy& wc_proxy = WebContentsProxy(), const std::string& browser_context_id = std::string(), + const GURL& url = GURL(), bool is_visible = false, bool is_audible = false) { return std::make_unique<PageNodeImpl>(graph, wc_proxy, browser_context_id, - is_visible, is_audible); + url, is_visible, is_audible); } };
diff --git a/chrome/browser/platform_util_unittest.cc b/chrome/browser/platform_util_unittest.cc index 3704d421..ff182eb 100644 --- a/chrome/browser/platform_util_unittest.cc +++ b/chrome/browser/platform_util_unittest.cc
@@ -252,7 +252,8 @@ // ChromeOS doesn't follow symbolic links in sandboxed filesystems. So all the // symbolic link tests should return PATH_NOT_FOUND. -TEST_F(PlatformUtilPosixTest, OpenFileWithPosixSymlinksChromeOS) { +// Very flaky due to memory unsafety: crbug.com/1007240 +TEST_F(PlatformUtilPosixTest, DISABLED_OpenFileWithPosixSymlinksChromeOS) { EXPECT_EQ(OPEN_FAILED_PATH_NOT_FOUND, CallOpenItem(symlink_to_file_, OPEN_FILE)); EXPECT_EQ(OPEN_FAILED_PATH_NOT_FOUND, @@ -270,7 +271,8 @@ CallOpenItem(symlink_to_nowhere_, OPEN_FOLDER)); } -TEST_F(PlatformUtilTest, OpenFileWithUnhandledFileType) { +// Very flaky due to memory unsafety: crbug.com/1007240 +TEST_F(PlatformUtilTest, DISABLED_OpenFileWithUnhandledFileType) { base::FilePath unhandled_file = directory_.GetPath().AppendASCII("myfile.filetype"); ASSERT_EQ(3, base::WriteFile(unhandled_file, "cat", 3));
diff --git a/chrome/browser/policy/policy_test_utils.cc b/chrome/browser/policy/policy_test_utils.cc index 9f2ff884..3ed7f00 100644 --- a/chrome/browser/policy/policy_test_utils.cc +++ b/chrome/browser/policy/policy_test_utils.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/policy/policy_test_utils.h" +#include "base/message_loop/message_loop_current.h" #include "base/path_service.h" #include "base/strings/utf_string_conversions.h" #include "base/task/post_task.h"
diff --git a/chrome/browser/resource_coordinator/tab_manager_stats_collector_unittest.cc b/chrome/browser/resource_coordinator/tab_manager_stats_collector_unittest.cc index d7d999d..c92c059 100644 --- a/chrome/browser/resource_coordinator/tab_manager_stats_collector_unittest.cc +++ b/chrome/browser/resource_coordinator/tab_manager_stats_collector_unittest.cc
@@ -10,6 +10,7 @@ #include "base/bind.h" #include "base/macros.h" +#include "base/message_loop/message_loop_current.h" #include "base/metrics/metrics_hashes.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/simple_test_tick_clock.h"
diff --git a/chrome/browser/resources/chromeos/camera/src/css/main.css b/chrome/browser/resources/chromeos/camera/src/css/main.css index 571d1e2..b8ba077 100644 --- a/chrome/browser/resources/chromeos/camera/src/css/main.css +++ b/chrome/browser/resources/chromeos/camera/src/css/main.css
@@ -259,11 +259,14 @@ z-index: 0; } -#modes-group.hide, -.mode-item.hide { +#modes-group.hide { visibility: hidden; } +.mode-item.hide { + display: none; +} + .mode-item>input { height: 100%; position: absolute;
diff --git a/chrome/browser/resources/chromeos/login/oobe_update.html b/chrome/browser/resources/chromeos/login/oobe_update.html index 8a06be5..f1afb3c 100644 --- a/chrome/browser/resources/chromeos/login/oobe_update.html +++ b/chrome/browser/resources/chromeos/login/oobe_update.html
@@ -30,6 +30,9 @@ aria-live="polite" id="checking-for-updates-dialog"> <iron-icon icon="oobe-update:googleg" slot="oobe-icon"></iron-icon> <h1 slot="title" i18n-content="checkingForUpdates"></h1> + <div slot="subtitle" class="update-subtitle" id="checkingForUpdatesMsg" + i18n-content="checkingForUpdatesMsg"> + </div> <div slot="subtitle" class="update-subtitle" id="checkingForUpdateCancelHint" i18n-content="cancelUpdateHint" hidden="[[!cancelAllowed]]"> </div>
diff --git a/chrome/browser/resources/local_ntp/doodles.css b/chrome/browser/resources/local_ntp/doodles.css index 885619d..ca9a379 100644 --- a/chrome/browser/resources/local_ntp/doodles.css +++ b/chrome/browser/resources/local_ntp/doodles.css
@@ -263,7 +263,8 @@ #ddlsd-title { color: #212121; font-size: 22px; - padding: 0 40px 16px 0; + padding-bottom: 16px; + padding-inline-end: 40px; } @media (prefers-color-scheme: dark) { @@ -273,7 +274,6 @@ } #ddlsd-close { - background: url(icons/close.svg) no-repeat; height: 24px; position: absolute; right: 22px; @@ -281,6 +281,29 @@ width: 24px; } +[dir=rtl] #ddlsd-close { + left: 22px; + right: auto; +} + +#ddlsd-close::before { + -webkit-mask-image: url(../../../../ui/webui/resources/images/icon_clear.svg); + -webkit-mask-position: center center; + -webkit-mask-repeat: no-repeat; + -webkit-mask-size: 32px; + background-color: #4d4d4d; + content: ''; + display: block; + height: 100%; + width: 100%; +} + +@media (prefers-color-scheme: dark) { + #ddlsd-close::before { + background-color: rgb(var(--GG500-rgb)); + } +} + #ddlsd-fbb { background: url(icons/facebook.svg) no-repeat center; } @@ -315,7 +338,6 @@ background: url(icons/copy.svg) no-repeat center; background-size: contain; display: inline-block; - float: right; height: 36px; margin: 5px; width: 36px; @@ -338,8 +360,8 @@ } #ddlsd-link { + display: flex; margin: 6px; - overflow: hidden; } #ddlsd-text-ctr {
diff --git a/chrome/browser/resources/local_ntp/icons/close.svg b/chrome/browser/resources/local_ntp/icons/close.svg deleted file mode 100644 index 282fa77..0000000 --- a/chrome/browser/resources/local_ntp/icons/close.svg +++ /dev/null
@@ -1 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24"><defs><style>.a{fill:none;stroke:#4d4d4d;stroke-miterlimit:10;stroke-width:3px}</style></defs><path class="a" d="M3.5 3.5L21 21M3.5 21L21 3.5"/></svg> \ No newline at end of file
diff --git a/chrome/browser/resources/local_ntp/local_ntp.html b/chrome/browser/resources/local_ntp/local_ntp.html index ac5bac8b..5690800 100644 --- a/chrome/browser/resources/local_ntp/local_ntp.html +++ b/chrome/browser/resources/local_ntp/local_ntp.html
@@ -157,10 +157,10 @@ <button id="ddlsd-emb" class="ddlsd-sbtn"></button> <hr id="ddlsd-hr"> <div id="ddlsd-link"> - <button id="ddlsd-copy"></button> <span id="ddlsd-text-ctr"> <input type="text" id="ddlsd-text" dir="ltr"> </span> + <button id="ddlsd-copy"></button> </div> </div> </dialog>
diff --git a/chrome/browser/safe_browsing/browser_feature_extractor_unittest.cc b/chrome/browser/safe_browsing/browser_feature_extractor_unittest.cc index bccb9561..e5d5bcb 100644 --- a/chrome/browser/safe_browsing/browser_feature_extractor_unittest.cc +++ b/chrome/browser/safe_browsing/browser_feature_extractor_unittest.cc
@@ -11,7 +11,7 @@ #include "base/bind.h" #include "base/macros.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_loop_current.h" #include "base/run_loop.h" #include "base/strings/stringprintf.h" #include "base/time/time.h"
diff --git a/chrome/browser/safe_browsing/client_side_detection_host.cc b/chrome/browser/safe_browsing/client_side_detection_host.cc index 04bdf84..c93ee3e 100644 --- a/chrome/browser/safe_browsing/client_side_detection_host.cc +++ b/chrome/browser/safe_browsing/client_side_detection_host.cc
@@ -508,7 +508,9 @@ DVLOG(1) << "Instruct renderer to start phishing detection for URL: " << browse_info_->url; content::RenderFrameHost* rfh = web_contents()->GetMainFrame(); - rfh->GetRemoteInterfaces()->GetInterface(&phishing_detector_); + phishing_detector_.reset(); + rfh->GetRemoteInterfaces()->GetInterface( + phishing_detector_.BindNewPipeAndPassReceiver()); phishing_detector_->StartPhishingDetection( browse_info_->url, base::BindRepeating(&ClientSideDetectionHost::PhishingDetectionDone,
diff --git a/chrome/browser/safe_browsing/client_side_detection_host.h b/chrome/browser/safe_browsing/client_side_detection_host.h index a946471b..95b35a6 100644 --- a/chrome/browser/safe_browsing/client_side_detection_host.h +++ b/chrome/browser/safe_browsing/client_side_detection_host.h
@@ -18,7 +18,7 @@ #include "components/safe_browsing/common/safe_browsing.mojom.h" #include "components/safe_browsing/db/database_manager.h" #include "content/public/browser/web_contents_observer.h" -#include "mojo/public/cpp/bindings/binding_set.h" +#include "mojo/public/cpp/bindings/remote.h" #include "services/service_manager/public/cpp/binder_registry.h" #include "url/gurl.h" @@ -155,7 +155,7 @@ // Current host, used to help determine cur_host_redirects_. std::string cur_host_; // The currently active message pipe to the renderer PhishingDetector. - mojom::PhishingDetectorPtr phishing_detector_; + mojo::Remote<mojom::PhishingDetector> phishing_detector_; // Max number of ips we save for each browse static const size_t kMaxIPsPerBrowse;
diff --git a/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc b/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc index 4053ff0..c5d5bf4 100644 --- a/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc +++ b/chrome/browser/safe_browsing/client_side_detection_host_unittest.cc
@@ -39,6 +39,8 @@ #include "content/public/test/test_renderer_host.h" #include "content/public/test/web_contents_tester.h" #include "ipc/ipc_test_sink.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/receiver_set.h" #include "services/network/public/cpp/shared_url_loader_factory.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -205,9 +207,9 @@ ~FakePhishingDetector() override = default; - void BindRequest(mojo::ScopedMessagePipeHandle handle) { - bindings_.AddBinding(this, - mojom::PhishingDetectorRequest(std::move(handle))); + void BindReceiver(mojo::ScopedMessagePipeHandle handle) { + receivers_.Add(this, mojo::PendingReceiver<mojom::PhishingDetector>( + std::move(handle))); } // mojom::PhishingDetector @@ -241,7 +243,7 @@ } private: - mojo::BindingSet<mojom::PhishingDetector> bindings_; + mojo::ReceiverSet<mojom::PhishingDetector> receivers_; bool phishing_detection_started_ = false; GURL url_; @@ -263,7 +265,7 @@ test_api.SetBinderForName( mojom::PhishingDetector::Name_, - base::BindRepeating(&FakePhishingDetector::BindRequest, + base::BindRepeating(&FakePhishingDetector::BindReceiver, base::Unretained(&fake_phishing_detector_))); }
diff --git a/chrome/browser/signin/account_consistency_mode_manager.cc b/chrome/browser/signin/account_consistency_mode_manager.cc index 8bf187e..e52abb7 100644 --- a/chrome/browser/signin/account_consistency_mode_manager.cc +++ b/chrome/browser/signin/account_consistency_mode_manager.cc
@@ -298,12 +298,8 @@ if (IsDiceMigrationCompleted(profile)) return AccountConsistencyMethod::kDice; - if (!IsReadyForDiceMigration(profile) && - profile->GetPrefs()->GetBoolean(prefs::kTokenServiceDiceCompatible) && - base::FeatureList::IsEnabled(kForceDiceMigration)) { - // Force migration to Dice. + if (base::FeatureList::IsEnabled(kForceDiceMigration)) return AccountConsistencyMethod::kDice; - } } return method;
diff --git a/chrome/browser/signin/e2e_tests/demo_signin_e2e_test.cc b/chrome/browser/signin/e2e_tests/demo_signin_e2e_test.cc index 5f12702..d7a40fc 100644 --- a/chrome/browser/signin/e2e_tests/demo_signin_e2e_test.cc +++ b/chrome/browser/signin/e2e_tests/demo_signin_e2e_test.cc
@@ -2,25 +2,106 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/strings/stringprintf.h" #include "chrome/browser/signin/e2e_tests/live_test.h" #include "chrome/browser/signin/e2e_tests/test_accounts_util.h" +#include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model_observer.h" #include "chrome/browser/ui/webui/signin/login_ui_test_utils.h" -#include "content/public/test/browser_test_utils.h" -#include "content/public/test/test_utils.h" +#include "components/signin/public/identity_manager/accounts_in_cookie_jar_info.h" +#include "components/signin/public/identity_manager/identity_manager.h" +#include "components/signin/public/identity_manager/test_identity_manager_observer.h" +#include "google_apis/gaia/gaia_urls.h" #include "ui/compositor/scoped_animation_duration_scale_mode.h" -using signin::test::TestAccount; -using signin::test::TestAccountsUtil; +namespace signin { +namespace test { -class DemoSignInTest : public signin::test::LiveTest {}; +// IdentityManager observer allowing to wait for sign out events for several +// accounts. +class SignOutTestObserver : public IdentityManager::Observer { + public: + explicit SignOutTestObserver(IdentityManager* identity_manager) + : identity_manager_(identity_manager) { + identity_manager_->AddObserver(this); + } + ~SignOutTestObserver() override { identity_manager_->RemoveObserver(this); } + void OnRefreshTokenRemovedForAccount( + const CoreAccountId& account_id) override { + ++signed_out_accounts_; + if (expected_accounts_ != -1 && signed_out_accounts_ >= expected_accounts_) + run_loop_.Quit(); + } + + void WaitForRefreshTokenRemovedForAccounts(int expected_accounts) { + expected_accounts_ = expected_accounts; + if (signed_out_accounts_ >= expected_accounts_) + return; + + run_loop_.Run(); + } + + private: + signin::IdentityManager* identity_manager_; + base::RunLoop run_loop_; + int signed_out_accounts_ = 0; + int expected_accounts_ = -1; +}; + +// Live tests for SignIn. +class DemoSignInTest : public signin::test::LiveTest { + public: + DemoSignInTest() = default; + ~DemoSignInTest() override = default; + + void SetUp() override { + LiveTest::SetUp(); + // Always disable animation for stability. + ui::ScopedAnimationDurationScaleMode disable_animation( + ui::ScopedAnimationDurationScaleMode::ZERO_DURATION); + } + + void SignInFromWeb(const TestAccount& test_account) { + AddTabAtIndex(0, GaiaUrls::GetInstance()->add_account_url(), + ui::PageTransition::PAGE_TRANSITION_TYPED); + SignInFromCurrentPage(test_account); + } + + void SignInFromCurrentPage(const TestAccount& test_account) { + TestIdentityManagerObserver observer(identity_manager()); + base::RunLoop cookie_update_loop; + observer.SetOnAccountsInCookieUpdatedCallback( + cookie_update_loop.QuitClosure()); + base::RunLoop refresh_token_update_loop; + observer.SetOnRefreshTokenUpdatedCallback( + refresh_token_update_loop.QuitClosure()); + login_ui_test_utils::ExecuteJsToSigninInSigninFrame( + browser(), test_account.user, test_account.password); + cookie_update_loop.Run(); + refresh_token_update_loop.Run(); + } + + void SignOutFromWeb(size_t signed_in_accounts) { + TestIdentityManagerObserver observer(identity_manager()); + base::RunLoop cookie_update_loop; + observer.SetOnAccountsInCookieUpdatedCallback( + cookie_update_loop.QuitClosure()); + SignOutTestObserver sign_out_observer(identity_manager()); + AddTabAtIndex(0, GaiaUrls::GetInstance()->service_logout_url(), + ui::PageTransition::PAGE_TRANSITION_TYPED); + cookie_update_loop.Run(); + sign_out_observer.WaitForRefreshTokenRemovedForAccounts(signed_in_accounts); + } + + signin::IdentityManager* identity_manager() { + return IdentityManagerFactory::GetForProfile(browser()->profile()); + } +}; + +// Sings in an account through the settings page and checks that the account is +// added to Chrome. Sync should be disabled. IN_PROC_BROWSER_TEST_F(DemoSignInTest, SimpleSignInFlow) { - // Always disable animation for stability. - ui::ScopedAnimationDurationScaleMode disable_animation( - ui::ScopedAnimationDurationScaleMode::ZERO_DURATION); GURL url("chrome://settings"); AddTabAtIndex(0, url, ui::PageTransition::PAGE_TRANSITION_TYPED); auto* settings_tab = browser()->tab_strip_model()->GetActiveWebContents(); @@ -31,14 +112,63 @@ "testElement.$$('#sign-in').click();")); TestAccount ta; CHECK(GetTestAccountsUtil()->GetAccount("TEST_ACCOUNT_1", ta)); - login_ui_test_utils::ExecuteJsToSigninInSigninFrame(browser(), ta.user, - ta.password); - login_ui_test_utils::DismissSyncConfirmationDialog( - browser(), base::TimeDelta::FromSeconds(3)); - GURL signin("chrome://signin-internals"); - AddTabAtIndex(0, signin, ui::PageTransition::PAGE_TRANSITION_TYPED); - auto* signin_tab = browser()->tab_strip_model()->GetActiveWebContents(); - std::string query_str = base::StringPrintf( - "document.body.innerHTML.indexOf('%s');", ta.user.c_str()); - EXPECT_GT(content::EvalJs(signin_tab, query_str).ExtractInt(), 0); + SignInFromCurrentPage(ta); + + const AccountsInCookieJarInfo& accounts_in_cookie_jar = + identity_manager()->GetAccountsInCookieJar(); + EXPECT_TRUE(accounts_in_cookie_jar.accounts_are_fresh); + ASSERT_EQ(1u, accounts_in_cookie_jar.signed_in_accounts.size()); + EXPECT_TRUE(accounts_in_cookie_jar.signed_out_accounts.empty()); + const gaia::ListedAccount& account = + accounts_in_cookie_jar.signed_in_accounts[0]; + EXPECT_TRUE(gaia::AreEmailsSame(ta.user, account.email)); + EXPECT_TRUE(identity_manager()->HasAccountWithRefreshToken(account.id)); + EXPECT_FALSE(identity_manager()->HasPrimaryAccount()); } + +// Sings in two accounts on the web and checks that cookies and refresh tokens +// are added to Chrome. Sync should be disabled. +// Then, signs out on the web and checks that accounts are removed from Chrome. +IN_PROC_BROWSER_TEST_F(DemoSignInTest, WebSignInAndSignOut) { + TestAccount test_account_1; + CHECK(GetTestAccountsUtil()->GetAccount("TEST_ACCOUNT_1", test_account_1)); + SignInFromWeb(test_account_1); + + const AccountsInCookieJarInfo& accounts_in_cookie_jar_1 = + identity_manager()->GetAccountsInCookieJar(); + EXPECT_TRUE(accounts_in_cookie_jar_1.accounts_are_fresh); + ASSERT_EQ(1u, accounts_in_cookie_jar_1.signed_in_accounts.size()); + EXPECT_TRUE(accounts_in_cookie_jar_1.signed_out_accounts.empty()); + const gaia::ListedAccount& account_1 = + accounts_in_cookie_jar_1.signed_in_accounts[0]; + EXPECT_TRUE(gaia::AreEmailsSame(test_account_1.user, account_1.email)); + EXPECT_TRUE(identity_manager()->HasAccountWithRefreshToken(account_1.id)); + EXPECT_FALSE(identity_manager()->HasPrimaryAccount()); + + TestAccount test_account_2; + CHECK(GetTestAccountsUtil()->GetAccount("TEST_ACCOUNT_2", test_account_2)); + SignInFromWeb(test_account_2); + + const AccountsInCookieJarInfo& accounts_in_cookie_jar_2 = + identity_manager()->GetAccountsInCookieJar(); + EXPECT_TRUE(accounts_in_cookie_jar_2.accounts_are_fresh); + ASSERT_EQ(2u, accounts_in_cookie_jar_2.signed_in_accounts.size()); + EXPECT_TRUE(accounts_in_cookie_jar_2.signed_out_accounts.empty()); + EXPECT_EQ(accounts_in_cookie_jar_2.signed_in_accounts[0].id, account_1.id); + const gaia::ListedAccount& account_2 = + accounts_in_cookie_jar_2.signed_in_accounts[1]; + EXPECT_TRUE(gaia::AreEmailsSame(test_account_2.user, account_2.email)); + EXPECT_TRUE(identity_manager()->HasAccountWithRefreshToken(account_2.id)); + EXPECT_FALSE(identity_manager()->HasPrimaryAccount()); + + SignOutFromWeb(2); + + const AccountsInCookieJarInfo& accounts_in_cookie_jar_3 = + identity_manager()->GetAccountsInCookieJar(); + EXPECT_TRUE(accounts_in_cookie_jar_3.accounts_are_fresh); + ASSERT_TRUE(accounts_in_cookie_jar_3.signed_in_accounts.empty()); + EXPECT_EQ(2u, accounts_in_cookie_jar_3.signed_out_accounts.size()); +} + +} // namespace test +} // namespace signin
diff --git a/chrome/browser/sync/test/integration/encryption_helper.cc b/chrome/browser/sync/test/integration/encryption_helper.cc index 4d5a0e6..6205c96 100644 --- a/chrome/browser/sync/test/integration/encryption_helper.cc +++ b/chrome/browser/sync/test/integration/encryption_helper.cc
@@ -27,10 +27,11 @@ return true; } -void InitCustomPassphraseCryptographerFromNigori( +std::unique_ptr<syncer::Cryptographer> +InitCustomPassphraseCryptographerFromNigori( const sync_pb::NigoriSpecifics& nigori, - syncer::Cryptographer* cryptographer, const std::string& passphrase) { + auto cryptographer = std::make_unique<syncer::DirectoryCryptographer>(); sync_pb::EncryptedData keybag = nigori.encryption_keybag(); cryptographer->SetPendingKeys(keybag); @@ -38,22 +39,24 @@ switch (syncer::ProtoKeyDerivationMethodToEnum( nigori.custom_passphrase_key_derivation_method())) { case syncer::KeyDerivationMethod::PBKDF2_HMAC_SHA1_1003: - ASSERT_TRUE(cryptographer->DecryptPendingKeys( + EXPECT_TRUE(cryptographer->DecryptPendingKeys( {syncer::KeyDerivationParams::CreateForPbkdf2(), passphrase})); break; case syncer::KeyDerivationMethod::SCRYPT_8192_8_11: - ASSERT_TRUE(base::Base64Decode( + EXPECT_TRUE(base::Base64Decode( nigori.custom_passphrase_key_derivation_salt(), &decoded_salt)); - ASSERT_TRUE(cryptographer->DecryptPendingKeys( + EXPECT_TRUE(cryptographer->DecryptPendingKeys( {syncer::KeyDerivationParams::CreateForScrypt(decoded_salt), passphrase})); break; case syncer::KeyDerivationMethod::UNSUPPORTED: // This test cannot pass since we wouldn't know how to decrypt data // encrypted using an unsupported method. - FAIL() << "Unsupported key derivation method encountered: " - << nigori.custom_passphrase_key_derivation_method(); + ADD_FAILURE() << "Unsupported key derivation method encountered: " + << nigori.custom_passphrase_key_derivation_method(); } + + return cryptographer; } sync_pb::NigoriSpecifics CreateCustomPassphraseNigori( @@ -95,7 +98,7 @@ // keybag using a key derived from that passphrase). However, in some migrated // states, the keybag might also additionally contain an old, pre-migration // key. - syncer::Cryptographer cryptographer; + syncer::DirectoryCryptographer cryptographer; bool add_key_result = cryptographer.AddKey(params); DCHECK(add_key_result); bool get_keys_result = @@ -112,7 +115,7 @@ sync_pb::EntitySpecifics wrapped_entity_specifics; *wrapped_entity_specifics.mutable_bookmark() = bookmark_specifics; - syncer::Cryptographer cryptographer; + syncer::DirectoryCryptographer cryptographer; bool add_key_result = cryptographer.AddKey(key_params); DCHECK(add_key_result); bool encrypt_result = cryptographer.Encrypt(
diff --git a/chrome/browser/sync/test/integration/encryption_helper.h b/chrome/browser/sync/test/integration/encryption_helper.h index aa4cf09b..4166bba 100644 --- a/chrome/browser/sync/test/integration/encryption_helper.h +++ b/chrome/browser/sync/test/integration/encryption_helper.h
@@ -5,12 +5,13 @@ #ifndef CHROME_BROWSER_SYNC_TEST_INTEGRATION_ENCRYPTION_HELPER_H_ #define CHROME_BROWSER_SYNC_TEST_INTEGRATION_ENCRYPTION_HELPER_H_ +#include <memory> #include <string> #include "base/test/scoped_feature_list.h" #include "chrome/browser/sync/test/integration/single_client_status_change_checker.h" -#include "components/sync/nigori/cryptographer.h" #include "components/sync/protocol/nigori_specifics.pb.h" +#include "components/sync/syncable/directory_cryptographer.h" #include "components/sync/test/fake_server/fake_server.h" namespace encryption_helper { @@ -30,9 +31,9 @@ // Nigori is encrypted (by design), the provided |passphrase| will be used to // decrypt it. This function will fail the test (using ASSERT) if the Nigori is // not a custom passphrase one, or if the key cannot be decrypted. -void InitCustomPassphraseCryptographerFromNigori( +std::unique_ptr<syncer::Cryptographer> +InitCustomPassphraseCryptographerFromNigori( const sync_pb::NigoriSpecifics& nigori, - syncer::Cryptographer* cryptographer, const std::string& passphrase); // Returns an EntitySpecifics containing encrypted data corresponding to the
diff --git a/chrome/browser/sync/test/integration/single_client_custom_passphrase_sync_test.cc b/chrome/browser/sync/test/integration/single_client_custom_passphrase_sync_test.cc index f920849..b067adc1 100644 --- a/chrome/browser/sync/test/integration/single_client_custom_passphrase_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_custom_passphrase_sync_test.cc
@@ -144,10 +144,7 @@ EXPECT_TRUE(GetServerNigori(GetFakeServer(), &nigori)); EXPECT_EQ(ProtoPassphraseInt32ToEnum(nigori.passphrase_type()), PassphraseType::kCustomPassphrase); - auto cryptographer = std::make_unique<Cryptographer>(); - InitCustomPassphraseCryptographerFromNigori(nigori, cryptographer.get(), - passphrase); - return cryptographer; + return InitCustomPassphraseCryptographerFromNigori(nigori, passphrase); } // A cryptographer initialized with the given KeyParams has not "seen" the @@ -155,7 +152,7 @@ // does not depend on external info. std::unique_ptr<Cryptographer> CreateCryptographerWithKeyParams( const KeyParams& key_params) { - auto cryptographer = std::make_unique<Cryptographer>(); + auto cryptographer = std::make_unique<syncer::DirectoryCryptographer>(); cryptographer->AddKey(key_params); return cryptographer; }
diff --git a/chrome/browser/sync/test/integration/single_client_passwords_sync_test.cc b/chrome/browser/sync/test/integration/single_client_passwords_sync_test.cc index f781c80..8f6ede2 100644 --- a/chrome/browser/sync/test/integration/single_client_passwords_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_passwords_sync_test.cc
@@ -20,7 +20,7 @@ #include "components/sync/base/time.h" #include "components/sync/driver/profile_sync_service.h" #include "components/sync/driver/sync_driver_switches.h" -#include "components/sync/nigori/cryptographer.h" +#include "components/sync/syncable/directory_cryptographer.h" namespace { @@ -52,7 +52,7 @@ sync_pb::PasswordSpecifics EncryptPasswordSpecifics( const syncer::KeyParams& key_params, const sync_pb::PasswordSpecificsData& password_data) { - syncer::Cryptographer cryptographer; + syncer::DirectoryCryptographer cryptographer; cryptographer.AddKey(key_params); sync_pb::PasswordSpecifics encrypted_specifics; @@ -338,12 +338,12 @@ nigori.set_encrypt_everything(false); nigori.set_passphrase_type(sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE); - syncer::Cryptographer cryptographer; + syncer::DirectoryCryptographer cryptographer; ASSERT_TRUE(cryptographer.AddKey(key_params)); ASSERT_TRUE(cryptographer.AddNonDefaultKey(key_params)); ASSERT_TRUE(cryptographer.GetKeys(nigori.mutable_encryption_keybag())); - syncer::Cryptographer keystore_cryptographer; + syncer::DirectoryCryptographer keystore_cryptographer; ASSERT_TRUE(keystore_cryptographer.AddKey(key_params)); ASSERT_TRUE(keystore_cryptographer.EncryptString( cryptographer.GetDefaultNigoriKeyData(),
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 3ffd157..ac801fb4 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -1894,6 +1894,7 @@ "webui/version_handler_chromeos.h", "window_sizer/window_sizer_ash.cc", ] + deps += [ "//ash", "//ash/components/shortcut_viewer", @@ -1901,6 +1902,7 @@ "//ash/public/cpp", "//ash/public/cpp/resources:ash_public_unscaled_resources", "//ash/public/cpp/vector_icons", + "//build:branding_buildflags", "//chrome/browser/chromeos", "//chrome/browser/chromeos:backdrop_wallpaper_proto", "//chrome/browser/resources/chromeos:camera_resources",
diff --git a/chrome/browser/ui/ash/chrome_screenshot_grabber.cc b/chrome/browser/ui/ash/chrome_screenshot_grabber.cc index 82ba484..9c35f13 100644 --- a/chrome/browser/ui/ash/chrome_screenshot_grabber.cc +++ b/chrome/browser/ui/ash/chrome_screenshot_grabber.cc
@@ -18,7 +18,7 @@ #include "base/files/file_util.h" #include "base/i18n/time_formatting.h" #include "base/macros.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_loop_current.h" #include "base/metrics/user_metrics.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h"
diff --git a/chrome/browser/ui/ash/media_client_impl.cc b/chrome/browser/ui/ash/media_client_impl.cc index 44b0a144..f07830e 100644 --- a/chrome/browser/ui/ash/media_client_impl.cc +++ b/chrome/browser/ui/ash/media_client_impl.cc
@@ -10,7 +10,7 @@ #include "base/bind.h" #include "base/location.h" #include "base/logging.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_loop_current.h" #include "base/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" #include "chrome/browser/chromeos/extensions/media_player_api.h"
diff --git a/chrome/browser/ui/views/menu_model_adapter_test.cc b/chrome/browser/ui/views/menu_model_adapter_test.cc index 8fbf146..0be63a5 100644 --- a/chrome/browser/ui/views/menu_model_adapter_test.cc +++ b/chrome/browser/ui/views/menu_model_adapter_test.cc
@@ -6,7 +6,7 @@ #include "base/callback.h" #include "base/location.h" #include "base/macros.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_loop_current.h" #include "base/single_thread_task_runner.h" #include "base/strings/utf_string_conversions.h" #include "base/threading/thread_task_runner_handle.h"
diff --git a/chrome/browser/ui/views/profiles/avatar_toolbar_button.cc b/chrome/browser/ui/views/profiles/avatar_toolbar_button.cc index 3caba49..96b279c 100644 --- a/chrome/browser/ui/views/profiles/avatar_toolbar_button.cc +++ b/chrome/browser/ui/views/profiles/avatar_toolbar_button.cc
@@ -224,6 +224,8 @@ void AvatarToolbarButton::NotifyClick(const ui::Event& event) { Button::NotifyClick(event); + if (should_reset_user_email_when_no_longer_hovered_or_focused_) + ResetUserEmailWhenNotHoveredOrFocused(); // TODO(bsep): Other toolbar buttons have ToolbarView as a listener and let it // call ExecuteCommandWithDisposition on their behalf. Unfortunately, it's not // possible to plumb IsKeyEvent through, so this has to be a special case. @@ -233,6 +235,18 @@ event.IsKeyEvent()); } +void AvatarToolbarButton::OnMouseExited(const ui::MouseEvent& event) { + if (should_reset_user_email_when_no_longer_hovered_or_focused_) + ResetUserEmailWhenNotHoveredOrFocused(); + ToolbarButton::OnMouseExited(event); +} + +void AvatarToolbarButton::OnBlur() { + if (should_reset_user_email_when_no_longer_hovered_or_focused_) + ResetUserEmailWhenNotHoveredOrFocused(); + ToolbarButton::OnBlur(); +} + void AvatarToolbarButton::OnThemeChanged() { ToolbarButton::OnThemeChanged(); UpdateIcon(); @@ -336,11 +350,28 @@ // Hide the pill after a while. base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( FROM_HERE, - base::BindOnce(&AvatarToolbarButton::ResetUserEmail, - weak_ptr_factory_.GetWeakPtr()), + base::BindOnce( + &AvatarToolbarButton::ResetUserEmailWhenNotHoveredOrFocused, + weak_ptr_factory_.GetWeakPtr()), kEmailExpansionDuration); } +void AvatarToolbarButton::ResetUserEmailWhenNotHoveredOrFocused() { + // No-op if it has been reset already. + if (!user_email_) + return; + + // Keep email visible while hovering or being focused. + if (IsMouseHovered() || HasFocus()) { + // TODO(crbug.com/967317): Include also the case when some other button from + // the parent container is shown and hovered / focused. + should_reset_user_email_when_no_longer_hovered_or_focused_ = true; + return; + } + should_reset_user_email_when_no_longer_hovered_or_focused_ = false; + ResetUserEmail(); +} + void AvatarToolbarButton::ResetUserEmail() { DCHECK(user_email_.has_value()); user_email_ = base::nullopt;
diff --git a/chrome/browser/ui/views/profiles/avatar_toolbar_button.h b/chrome/browser/ui/views/profiles/avatar_toolbar_button.h index 72073d7..24e0ba68 100644 --- a/chrome/browser/ui/views/profiles/avatar_toolbar_button.h +++ b/chrome/browser/ui/views/profiles/avatar_toolbar_button.h
@@ -56,6 +56,8 @@ // ToolbarButton: void NotifyClick(const ui::Event& event) override; + void OnMouseExited(const ui::MouseEvent& event) override; + void OnBlur() override; void OnThemeChanged() override; void AddedToWidget() override; @@ -93,6 +95,7 @@ void OnCreditCardSaved() override; void ExpandToShowEmail(); + void ResetUserEmailWhenNotHoveredOrFocused(); void ResetUserEmail(); base::string16 GetAvatarTooltipText() const; @@ -130,6 +133,8 @@ base::Optional<std::string> user_email_; // We cannot show the animation before we fetch the new avatar. bool waiting_for_image_to_show_user_email_ = false; + // We cannot hide the animation when the button is hovered or focused. + bool should_reset_user_email_when_no_longer_hovered_or_focused_ = false; ScopedObserver<ProfileAttributesStorage, ProfileAttributesStorage::Observer> profile_observer_{this};
diff --git a/chrome/browser/ui/views/simple_message_box_views.cc b/chrome/browser/ui/views/simple_message_box_views.cc index 7128fa3..0a36db5 100644 --- a/chrome/browser/ui/views/simple_message_box_views.cc +++ b/chrome/browser/ui/views/simple_message_box_views.cc
@@ -10,7 +10,7 @@ #include "base/callback.h" #include "base/compiler_specific.h" #include "base/macros.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_loop_current.h" #include "base/run_loop.h" #include "build/build_config.h" #include "chrome/browser/ui/browser_dialogs.h"
diff --git a/chrome/browser/ui/views/toolbar/app_menu.cc b/chrome/browser/ui/views/toolbar/app_menu.cc index 0a5201c..eea1608 100644 --- a/chrome/browser/ui/views/toolbar/app_menu.cc +++ b/chrome/browser/ui/views/toolbar/app_menu.cc
@@ -471,13 +471,12 @@ // the keyboard navigation to work. DCHECK(Button::AsButton(fullscreen_button_)); - // TODO(https://crbug.com/957391): Do away with this bespoke color. Ideally - // this should be kColorId_EnabledMenuItemForegroundColor. The color here is - // ripped directly from the old PNG asset for this image. fullscreen_button_->SetImage( ImageButton::STATE_NORMAL, - gfx::CreateVectorIcon(kFullscreenIcon, - SkColorSetRGB(0x98, 0x98, 0x98))); + gfx::CreateVectorIcon( + kFullscreenIcon, + GetNativeTheme()->GetSystemColor( + ui::NativeTheme::kColorId_EnabledMenuItemForegroundColor))); // Since |fullscreen_button_| will reside in a menu, make it ALWAYS // focusable regardless of the platform. @@ -548,18 +547,16 @@ zoom_label_max_width_valid_ = false; ui::NativeTheme* theme = GetNativeTheme(); - if (theme) { - zoom_label_->SetEnabledColor(theme->GetSystemColor( - ui::NativeTheme::kColorId_EnabledMenuItemForegroundColor)); - gfx::ImageSkia hovered_fullscreen_image = gfx::CreateVectorIcon( - kFullscreenIcon, - theme->GetSystemColor( - ui::NativeTheme::kColorId_SelectedMenuItemForegroundColor)); - fullscreen_button_->SetImage(ImageButton::STATE_HOVERED, - hovered_fullscreen_image); - fullscreen_button_->SetImage(ImageButton::STATE_PRESSED, - hovered_fullscreen_image); - } + zoom_label_->SetEnabledColor(theme->GetSystemColor( + ui::NativeTheme::kColorId_EnabledMenuItemForegroundColor)); + gfx::ImageSkia hovered_fullscreen_image = gfx::CreateVectorIcon( + kFullscreenIcon, + theme->GetSystemColor( + ui::NativeTheme::kColorId_SelectedMenuItemForegroundColor)); + fullscreen_button_->SetImage(ImageButton::STATE_HOVERED, + hovered_fullscreen_image); + fullscreen_button_->SetImage(ImageButton::STATE_PRESSED, + hovered_fullscreen_image); } // Overridden from ButtonListener.
diff --git a/chrome/browser/ui/views/toolbar/toolbar_button.cc b/chrome/browser/ui/views/toolbar/toolbar_button.cc index 3b9380bf..d621e6f 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_button.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_button.cc
@@ -120,10 +120,7 @@ void ToolbarButton::ClearHighlight() { highlight_color_animation_.Hide(); - // TODO(crbug.com/1002160): Support AnimatingLayoutManager by reporting - // preferred size without the label, clear the label only once the layout - // animation is completed. - LabelButton::SetText(base::string16()); + ShrinkDownThenClearText(); } void ToolbarButton::UpdateColorsAndInsets() {
diff --git a/chrome/browser/ui/webui/chromeos/account_manager_error_ui.cc b/chrome/browser/ui/webui/chromeos/account_manager_error_ui.cc index 6db2f476..ed686a24 100644 --- a/chrome/browser/ui/webui/chromeos/account_manager_error_ui.cc +++ b/chrome/browser/ui/webui/chromeos/account_manager_error_ui.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/ui/webui/chromeos/account_manager_error_ui.h" #include "base/bind.h" +#include "build/branding_buildflags.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/url_constants.h" #include "chrome/common/webui_url_constants.h" @@ -31,7 +32,7 @@ html_source->AddLocalizedString( "errorMessage", IDS_ACCOUNT_MANAGER_SECONDARY_ACCOUNTS_DISABLED_TEXT); html_source->AddLocalizedString("okButton", IDS_APP_OK); -#if defined(GOOGLE_CHROME_BUILD) +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) html_source->AddResourcePath("googleg.svg", IDR_ACCOUNT_MANAGER_WELCOME_GOOGLE_LOGO_SVG); #endif
diff --git a/chrome/browser/ui/webui/discards/graph_dump_impl.cc b/chrome/browser/ui/webui/discards/graph_dump_impl.cc index 4b1e847..9e19520 100644 --- a/chrome/browser/ui/webui/discards/graph_dump_impl.cc +++ b/chrome/browser/ui/webui/discards/graph_dump_impl.cc
@@ -249,10 +249,10 @@ StartPageFaviconRequest(page_node); } -void DiscardsGraphDumpImpl::OnMainFrameNavigationCommitted( +void DiscardsGraphDumpImpl::OnMainFrameUrlChanged( const performance_manager::PageNode* page_node) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); SendPageNotification(page_node, false); - StartPageFaviconRequest(page_node); } void DiscardsGraphDumpImpl::OnProcessNodeAdded(
diff --git a/chrome/browser/ui/webui/discards/graph_dump_impl.h b/chrome/browser/ui/webui/discards/graph_dump_impl.h index f158ba6..c5c85ad3 100644 --- a/chrome/browser/ui/webui/discards/graph_dump_impl.h +++ b/chrome/browser/ui/webui/discards/graph_dump_impl.h
@@ -98,11 +98,13 @@ // Ignored. void OnPageOriginTrialFreezePolicyChanged( const performance_manager::PageNode* page_node) override {} + void OnMainFrameUrlChanged( + const performance_manager::PageNode* page_node) override; // Ignored. void OnPageAlmostIdleChanged( const performance_manager::PageNode* page_node) override {} - void OnMainFrameNavigationCommitted( - const performance_manager::PageNode* page_node) override; + void OnMainFrameDocumentChanged( + const performance_manager::PageNode* page_node) override {} void OnTitleUpdated(const performance_manager::PageNode* page_node) override { } // Ignored. void OnFaviconUpdated(
diff --git a/chrome/browser/ui/webui/discards/graph_dump_impl_unittest.cc b/chrome/browser/ui/webui/discards/graph_dump_impl_unittest.cc index 1f804827..ee07948 100644 --- a/chrome/browser/ui/webui/discards/graph_dump_impl_unittest.cc +++ b/chrome/browser/ui/webui/discards/graph_dump_impl_unittest.cc
@@ -133,8 +133,11 @@ base::TimeTicks now = base::TimeTicks::Now(); const GURL kExampleUrl("http://www.example.org"); - mock_graph.page->OnMainFrameNavigationCommitted(now, 1, kExampleUrl); - mock_graph.other_page->OnMainFrameNavigationCommitted(now, 2, kExampleUrl); + int64_t next_navigation_id = 1; + mock_graph.page->OnMainFrameNavigationCommitted( + false, now, next_navigation_id++, kExampleUrl); + mock_graph.other_page->OnMainFrameNavigationCommitted( + false, now, next_navigation_id++, kExampleUrl); auto* main_frame = mock_graph.page->GetMainFrameNodeImpl(); main_frame->OnNavigationCommitted(kExampleUrl, /* same_document */ false); @@ -193,7 +196,8 @@ // Test change notifications. const GURL kAnotherURL("http://www.google.com/"); - mock_graph.page->OnMainFrameNavigationCommitted(now, 1, kAnotherURL); + mock_graph.page->OnMainFrameNavigationCommitted( + false, now, next_navigation_id++, kAnotherURL); size_t child_frame_id = NodeBase::GetSerializationId(mock_graph.child_frame.get()); @@ -201,6 +205,7 @@ task_environment.RunUntilIdle(); + // Main frame navigation results in a notification for the url. EXPECT_EQ(1u, change_stream.num_changes()); EXPECT_FALSE(base::Contains(change_stream.id_set(), child_frame_id));
diff --git a/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc b/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc index eab0779..0f326828 100644 --- a/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc +++ b/chrome/browser/ui/webui/net_internals/net_internals_ui_browsertest.cc
@@ -14,6 +14,7 @@ #include "base/files/scoped_file.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "base/message_loop/message_loop_current.h" #include "base/strings/string_split.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h"
diff --git a/chrome/browser/web_applications/proto/BUILD.gn b/chrome/browser/web_applications/proto/BUILD.gn index eae2f64b..1a55541 100644 --- a/chrome/browser/web_applications/proto/BUILD.gn +++ b/chrome/browser/web_applications/proto/BUILD.gn
@@ -5,7 +5,9 @@ import("//third_party/protobuf/proto_library.gni") proto_library("proto") { + import_dirs = [ "//components/sync/protocol" ] sources = [ "web_app.proto", ] + link_deps = [ "//components/sync/protocol" ] }
diff --git a/chrome/browser/web_applications/proto/web_app.proto b/chrome/browser/web_applications/proto/web_app.proto index a093f0e..54cda05 100644 --- a/chrome/browser/web_applications/proto/web_app.proto +++ b/chrome/browser/web_applications/proto/web_app.proto
@@ -4,6 +4,8 @@ syntax = "proto2"; +import "web_app_specifics.proto"; + option optimize_for = LITE_RUNTIME; package web_app; @@ -26,29 +28,19 @@ required bool default = 5; } -// WebApp class data. This should be a superset for WebAppSpecifics in -// components/sync/protocol/web_app_specifics.proto +// Full WebApp object data. Note on database identities: +// app_id is a hash of launch_url. app_id is the client tag for sync system. +// app_id is the storage key in ModelTypeStore. message WebAppProto { - // Keep in sync with WebAppSpecifics::LaunchContainer. - enum LaunchContainer { - TAB = 1; - WINDOW = 2; - } + // Synced data. + required sync_pb.WebAppSpecifics specifics = 1; - // app_id is a hash of launch_url. app_id is the client tag for sync system. - // app_id is the storage key in ModelTypeStore. - required string launch_url = 1; - required string name = 2; - required LaunchContainer launch_container = 3; - optional uint32 theme_color = 4; - - // Local data members, not to be synced: - optional string description = 5; - optional string scope = 6; - - required SourcesProto sources = 7; - required bool is_locally_installed = 8; - + // Local data. Not to be synced. + // + optional string description = 2; + optional string scope = 3; + required SourcesProto sources = 4; + required bool is_locally_installed = 5; // A list of icon infos. - repeated WebAppIconInfoProto icons = 9; + repeated WebAppIconInfoProto icons = 6; }
diff --git a/chrome/browser/web_applications/system_web_app_manager.cc b/chrome/browser/web_applications/system_web_app_manager.cc index 5469784..ed3ec02 100644 --- a/chrome/browser/web_applications/system_web_app_manager.cc +++ b/chrome/browser/web_applications/system_web_app_manager.cc
@@ -9,6 +9,7 @@ #include <vector> #include "base/bind.h" +#include "base/run_loop.h" #include "base/stl_util.h" #include "base/strings/string_number_conversions.h" #include "base/version.h"
diff --git a/chrome/browser/web_applications/test/test_web_app_registry_controller.cc b/chrome/browser/web_applications/test/test_web_app_registry_controller.cc index 03b44559..845e569 100644 --- a/chrome/browser/web_applications/test/test_web_app_registry_controller.cc +++ b/chrome/browser/web_applications/test/test_web_app_registry_controller.cc
@@ -7,7 +7,6 @@ #include "base/run_loop.h" #include "base/test/bind_test_util.h" #include "chrome/browser/web_applications/test/test_web_app_database_factory.h" -#include "chrome/browser/web_applications/web_app_registrar.h" #include "chrome/browser/web_applications/web_app_sync_bridge.h" namespace web_app { @@ -18,10 +17,10 @@ void TestWebAppRegistryController::SetUp(Profile* profile) { database_factory_ = std::make_unique<TestWebAppDatabaseFactory>(); - registrar_ = std::make_unique<WebAppRegistrar>(profile); + mutable_registrar_ = std::make_unique<WebAppRegistrarMutable>(profile); sync_bridge_ = std::make_unique<WebAppSyncBridge>( - profile, database_factory_.get(), registrar_.get(), + profile, database_factory_.get(), mutable_registrar_.get(), mock_processor_.CreateForwardingProcessor()); ON_CALL(processor(), IsTrackingMetadata()) @@ -35,7 +34,7 @@ } void TestWebAppRegistryController::DestroySubsystems() { - registrar_.reset(); + mutable_registrar_.reset(); sync_bridge_.reset(); database_factory_.reset(); }
diff --git a/chrome/browser/web_applications/test/test_web_app_registry_controller.h b/chrome/browser/web_applications/test/test_web_app_registry_controller.h index aa17d830..cf92ff1 100644 --- a/chrome/browser/web_applications/test/test_web_app_registry_controller.h +++ b/chrome/browser/web_applications/test/test_web_app_registry_controller.h
@@ -7,6 +7,7 @@ #include <memory> +#include "chrome/browser/web_applications/web_app_registrar.h" #include "components/sync/model/mock_model_type_change_processor.h" #include "testing/gmock/include/gmock/gmock.h" @@ -15,7 +16,6 @@ namespace web_app { class TestWebAppDatabaseFactory; -class WebAppRegistrar; class WebAppSyncBridge; class TestWebAppRegistryController { @@ -32,13 +32,14 @@ void DestroySubsystems(); TestWebAppDatabaseFactory& database_factory() { return *database_factory_; } - WebAppRegistrar& registrar() { return *registrar_; } + WebAppRegistrar& registrar() { return *mutable_registrar_; } + WebAppRegistrarMutable& mutable_registrar() { return *mutable_registrar_; } syncer::MockModelTypeChangeProcessor& processor() { return mock_processor_; } WebAppSyncBridge& sync_bridge() { return *sync_bridge_; } private: std::unique_ptr<TestWebAppDatabaseFactory> database_factory_; - std::unique_ptr<WebAppRegistrar> registrar_; + std::unique_ptr<WebAppRegistrarMutable> mutable_registrar_; testing::NiceMock<syncer::MockModelTypeChangeProcessor> mock_processor_; std::unique_ptr<WebAppSyncBridge> sync_bridge_; };
diff --git a/chrome/browser/web_applications/web_app_database.cc b/chrome/browser/web_applications/web_app_database.cc index 7b007972..cc8edc7 100644 --- a/chrome/browser/web_applications/web_app_database.cc +++ b/chrome/browser/web_applications/web_app_database.cc
@@ -12,6 +12,7 @@ #include "chrome/browser/web_applications/web_app_database_factory.h" #include "components/sync/base/model_type.h" #include "components/sync/model/model_error.h" +#include "components/sync/protocol/web_app_specifics.pb.h" namespace web_app { @@ -25,16 +26,16 @@ } void WebAppDatabase::OpenDatabase(RegistryOpenedCallback callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!store_); syncer::OnceModelTypeStoreFactory store_factory = database_factory_->GetStoreFactory(); - // CreateStore then ReadRegistry. - CreateStore( - std::move(store_factory), - base::BindOnce(&WebAppDatabase::ReadRegistry, - weak_ptr_factory_.GetWeakPtr(), std::move(callback))); + std::move(store_factory) + .Run(syncer::WEB_APPS, + base::BindOnce(&WebAppDatabase::OnDatabaseOpened, + weak_ptr_factory_.GetWeakPtr(), std::move(callback))); } void WebAppDatabase::WriteWebApps(AppsToWrite apps, @@ -77,15 +78,17 @@ DCHECK(!web_app.app_id().empty()); DCHECK_EQ(web_app.app_id(), GenerateAppIdFromURL(launch_url)); - proto->set_launch_url(launch_url.spec()); + sync_pb::WebAppSpecifics* specifics = proto->mutable_specifics(); - proto->set_name(web_app.name()); + specifics->set_launch_url(launch_url.spec()); + + specifics->set_name(web_app.name()); DCHECK_NE(LaunchContainer::kDefault, web_app.launch_container()); - proto->set_launch_container(web_app.launch_container() == - LaunchContainer::kWindow - ? WebAppProto::WINDOW - : WebAppProto::TAB); + specifics->set_launch_container(web_app.launch_container() == + LaunchContainer::kWindow + ? sync_pb::WebAppSpecifics::WINDOW + : sync_pb::WebAppSpecifics::TAB); DCHECK(web_app.sources_.any()); proto->mutable_sources()->set_system(web_app.sources_[Source::kSystem]); @@ -102,7 +105,7 @@ if (!web_app.scope().is_empty()) proto->set_scope(web_app.scope().spec()); if (web_app.theme_color().has_value()) - proto->set_theme_color(web_app.theme_color().value()); + specifics->set_theme_color(web_app.theme_color().value()); for (const WebApp::IconInfo& icon : web_app.icons()) { WebAppIconInfoProto* icon_proto = proto->add_icons(); @@ -115,8 +118,15 @@ // static std::unique_ptr<WebApp> WebAppDatabase::CreateWebApp(const WebAppProto& proto) { + if (!proto.has_specifics()) { + DLOG(ERROR) << "WebApp proto parse error: no specifics field"; + return nullptr; + } + + const sync_pb::WebAppSpecifics& specifics = proto.specifics(); + // AppId is a hash of launch_url. Read launch_url first: - GURL launch_url(proto.launch_url()); + GURL launch_url(specifics.launch_url()); if (launch_url.is_empty() || !launch_url.is_valid()) { DLOG(ERROR) << "WebApp proto launch_url parse error: " << launch_url.possibly_invalid_spec(); @@ -146,17 +156,18 @@ } web_app->sources_ = sources; - if (!proto.has_name()) { + if (!specifics.has_name()) { DLOG(ERROR) << "WebApp proto parse error: no name field"; return nullptr; } - web_app->SetName(proto.name()); + web_app->SetName(specifics.name()); - if (!proto.has_launch_container()) { + if (!specifics.has_launch_container()) { DLOG(ERROR) << "WebApp proto parse error: no launch_container field"; return nullptr; } - web_app->SetLaunchContainer(proto.launch_container() == WebAppProto::WINDOW + web_app->SetLaunchContainer(specifics.launch_container() == + sync_pb::WebAppSpecifics::WINDOW ? LaunchContainer::kWindow : LaunchContainer::kTab); @@ -180,8 +191,8 @@ web_app->SetScope(scope); } - if (proto.has_theme_color()) - web_app->SetThemeColor(proto.theme_color()); + if (specifics.has_theme_color()) + web_app->SetThemeColor(specifics.theme_color()); WebApp::Icons icons; for (int i = 0; i < proto.icons_size(); ++i) { @@ -201,27 +212,8 @@ return web_app; } -void WebAppDatabase::ReadRegistry(RegistryOpenedCallback callback) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(store_); - store_->ReadAllData(base::BindOnce(&WebAppDatabase::OnAllDataRead, - weak_ptr_factory_.GetWeakPtr(), - std::move(callback))); -} - -void WebAppDatabase::CreateStore( - syncer::OnceModelTypeStoreFactory store_factory, - base::OnceClosure closure) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - std::move(store_factory) - .Run(syncer::WEB_APPS, - base::BindOnce(&WebAppDatabase::OnStoreCreated, - weak_ptr_factory_.GetWeakPtr(), std::move(closure))); -} - -void WebAppDatabase::OnStoreCreated( - base::OnceClosure closure, +void WebAppDatabase::OnDatabaseOpened( + RegistryOpenedCallback callback, const base::Optional<syncer::ModelError>& error, std::unique_ptr<syncer::ModelTypeStore> store) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -231,7 +223,9 @@ } store_ = std::move(store); - std::move(closure).Run(); + store_->ReadAllData(base::BindOnce(&WebAppDatabase::OnAllDataRead, + weak_ptr_factory_.GetWeakPtr(), + std::move(callback))); } void WebAppDatabase::OnAllDataRead(
diff --git a/chrome/browser/web_applications/web_app_database.h b/chrome/browser/web_applications/web_app_database.h index bf95c11..9ef4edf 100644 --- a/chrome/browser/web_applications/web_app_database.h +++ b/chrome/browser/web_applications/web_app_database.h
@@ -45,19 +45,15 @@ // Exposed for testing. static std::unique_ptr<WebAppProto> CreateWebAppProto(const WebApp& web_app); // Exposed for testing. - static std::unique_ptr<WebApp> CreateWebApp(const WebAppProto& proto); - // Exposed for testing. - void ReadRegistry(RegistryOpenedCallback callback); - // Exposed for testing. static std::unique_ptr<WebApp> ParseWebApp(const AppId& app_id, const std::string& value); private: - void CreateStore(syncer::OnceModelTypeStoreFactory store_factory, - base::OnceClosure closure); - void OnStoreCreated(base::OnceClosure closure, - const base::Optional<syncer::ModelError>& error, - std::unique_ptr<syncer::ModelTypeStore> store); + static std::unique_ptr<WebApp> CreateWebApp(const WebAppProto& proto); + + void OnDatabaseOpened(RegistryOpenedCallback callback, + const base::Optional<syncer::ModelError>& error, + std::unique_ptr<syncer::ModelTypeStore> store); void OnAllDataRead( RegistryOpenedCallback callback,
diff --git a/chrome/browser/web_applications/web_app_database_unittest.cc b/chrome/browser/web_applications/web_app_database_unittest.cc index 763948c..3f6e4c68 100644 --- a/chrome/browser/web_applications/web_app_database_unittest.cc +++ b/chrome/browser/web_applications/web_app_database_unittest.cc
@@ -10,11 +10,12 @@ #include "base/run_loop.h" #include "base/strings/string_number_conversions.h" #include "base/test/bind_test_util.h" -#include "base/test/task_environment.h" #include "chrome/browser/web_applications/components/web_app_constants.h" #include "chrome/browser/web_applications/components/web_app_helpers.h" #include "chrome/browser/web_applications/proto/web_app.pb.h" #include "chrome/browser/web_applications/test/test_web_app_database_factory.h" +#include "chrome/browser/web_applications/test/test_web_app_registry_controller.h" +#include "chrome/browser/web_applications/test/web_app_test.h" #include "chrome/browser/web_applications/web_app.h" #include "chrome/browser/web_applications/web_app_registrar.h" #include "chrome/browser/web_applications/web_app_sync_bridge.h" @@ -24,21 +25,14 @@ namespace web_app { -class WebAppDatabaseTest : public testing::Test { +class WebAppDatabaseTest : public WebAppTest { public: - WebAppDatabaseTest() { - database_factory_ = std::make_unique<TestWebAppDatabaseFactory>(); - registrar_ = std::make_unique<WebAppRegistrar>(nullptr); - sync_bridge_ = std::make_unique<WebAppSyncBridge>( - nullptr, database_factory_.get(), registrar_.get()); - } + void SetUp() override { + WebAppTest::SetUp(); - void InitRegistrar() { - base::RunLoop run_loop; - - sync_bridge().Init(base::BindLambdaForTesting([&]() { run_loop.Quit(); })); - - run_loop.Run(); + test_registry_controller_ = + std::make_unique<TestWebAppRegistryController>(); + test_registry_controller_->SetUp(profile()); } static std::unique_ptr<WebApp> CreateWebApp(const std::string& base_url, @@ -91,14 +85,14 @@ bool IsDatabaseRegistryEqualToRegistrar() { Registry registry = database_factory().ReadRegistry(); - return IsRegistryEqual(registrar_->registry_for_testing(), registry); + return IsRegistryEqual(mutable_registrar().registry(), registry); } void WriteBatch( std::unique_ptr<syncer::ModelTypeStore::WriteBatch> write_batch) { base::RunLoop run_loop; - database_factory_->store()->CommitWriteBatch( + database_factory().store()->CommitWriteBatch( std::move(write_batch), base::BindLambdaForTesting( [&](const base::Optional<syncer::ModelError>& error) { @@ -112,7 +106,7 @@ Registry WriteWebApps(const std::string& base_url, int num_apps) { Registry registry; - auto write_batch = database_factory_->store()->CreateWriteBatch(); + auto write_batch = database_factory().store()->CreateWriteBatch(); for (int i = 0; i < num_apps; ++i) { auto app = CreateWebApp(base_url, i); @@ -130,22 +124,32 @@ } protected: - TestWebAppDatabaseFactory& database_factory() { return *database_factory_; } - WebAppDatabase& database() { return sync_bridge().database_for_testing(); } - WebAppSyncBridge& sync_bridge() { return *sync_bridge_; } - WebAppRegistrar& registrar() { return *registrar_; } + TestWebAppRegistryController& controller() { + return *test_registry_controller_; + } + + TestWebAppDatabaseFactory& database_factory() { + return controller().database_factory(); + } + + WebAppDatabase& database() { + return controller().sync_bridge().database_for_testing(); + } + + WebAppRegistrar& registrar() { return controller().registrar(); } + + WebAppRegistrarMutable& mutable_registrar() { + return controller().mutable_registrar(); + } + + WebAppSyncBridge& sync_bridge() { return controller().sync_bridge(); } private: - // Must be created before TestWebAppDatabaseFactory. - base::test::SingleThreadTaskEnvironment task_environment_; - - std::unique_ptr<TestWebAppDatabaseFactory> database_factory_; - std::unique_ptr<WebAppSyncBridge> sync_bridge_; - std::unique_ptr<WebAppRegistrar> registrar_; + std::unique_ptr<TestWebAppRegistryController> test_registry_controller_; }; TEST_F(WebAppDatabaseTest, WriteAndReadRegistry) { - InitRegistrar(); + controller().Init(); EXPECT_TRUE(registrar().is_empty()); const int num_apps = 100; @@ -170,7 +174,7 @@ } TEST_F(WebAppDatabaseTest, WriteAndDeleteAppsWithCallbacks) { - InitRegistrar(); + controller().Init(); EXPECT_TRUE(registrar().is_empty()); const int num_apps = 10; @@ -217,12 +221,12 @@ TEST_F(WebAppDatabaseTest, OpenDatabaseAndReadRegistry) { Registry registry = WriteWebApps("https://example.com/path", 100); - InitRegistrar(); - EXPECT_TRUE(IsRegistryEqual(registrar().registry_for_testing(), registry)); + controller().Init(); + EXPECT_TRUE(IsRegistryEqual(mutable_registrar().registry(), registry)); } TEST_F(WebAppDatabaseTest, WebAppWithoutOptionalFields) { - InitRegistrar(); + controller().Init(); const auto launch_url = GURL("https://example.com/"); const AppId app_id = GenerateAppIdFromURL(GURL(launch_url)); @@ -276,7 +280,7 @@ } TEST_F(WebAppDatabaseTest, WebAppWithManyIcons) { - InitRegistrar(); + controller().Init(); const int num_icons = 32; const std::string base_url = "https://example.com/path";
diff --git a/chrome/browser/web_applications/web_app_provider.cc b/chrome/browser/web_applications/web_app_provider.cc index 8d7bb0f..3ef1905e 100644 --- a/chrome/browser/web_applications/web_app_provider.cc +++ b/chrome/browser/web_applications/web_app_provider.cc
@@ -161,15 +161,28 @@ void WebAppProvider::CreateWebAppsSubsystems(Profile* profile) { database_factory_ = std::make_unique<WebAppDatabaseFactory>(profile); - auto registrar = std::make_unique<WebAppRegistrar>(profile); - auto sync_bridge = std::make_unique<WebAppSyncBridge>( - profile, database_factory_.get(), registrar.get()); + + std::unique_ptr<WebAppRegistrar> registrar; + std::unique_ptr<WebAppSyncBridge> sync_bridge; + + // Only WebAppSyncBridge must have an access to mutable WebAppRegistrar. + { + auto mutable_registrar = std::make_unique<WebAppRegistrarMutable>(profile); + + sync_bridge = std::make_unique<WebAppSyncBridge>( + profile, database_factory_.get(), mutable_registrar.get()); + + // Upcast to read-only WebAppRegistrar. + registrar = std::move(mutable_registrar); + } + auto icon_manager = std::make_unique<WebAppIconManager>( profile, *registrar, std::make_unique<FileUtilsWrapper>()); install_finalizer_ = std::make_unique<WebAppInstallFinalizer>( sync_bridge.get(), icon_manager.get()); file_handler_manager_ = std::make_unique<WebAppFileHandlerManager>(profile); + // Upcast to unified subsystem types: registrar_ = std::move(registrar); registry_controller_ = std::move(sync_bridge); icon_manager_ = std::move(icon_manager);
diff --git a/chrome/browser/web_applications/web_app_registrar.cc b/chrome/browser/web_applications/web_app_registrar.cc index b202767..eaa3de8 100644 --- a/chrome/browser/web_applications/web_app_registrar.cc +++ b/chrome/browser/web_applications/web_app_registrar.cc
@@ -25,11 +25,6 @@ return it == registry_.end() ? nullptr : it->second.get(); } -void WebAppRegistrar::InitRegistry(Registry&& registry) { - DCHECK(is_empty()); - registry_ = std::move(registry); -} - bool WebAppRegistrar::IsInstalled(const AppId& app_id) const { return GetAppById(app_id) != nullptr; } @@ -162,12 +157,8 @@ return AppSet(this); } -WebApp* WebAppRegistrar::GetAppByIdMutable(const AppId& app_id) { - return const_cast<WebApp*>(GetAppById(app_id)); -} - -WebAppRegistrar::AppSet WebAppRegistrar::AllAppsMutable() { - return AppSet(this); +void WebAppRegistrar::SetRegistry(Registry&& registry) { + registry_ = std::move(registry); } void WebAppRegistrar::CountMutation() { @@ -176,6 +167,24 @@ #endif } +WebAppRegistrarMutable::WebAppRegistrarMutable(Profile* profile) + : WebAppRegistrar(profile) {} + +WebAppRegistrarMutable::~WebAppRegistrarMutable() = default; + +void WebAppRegistrarMutable::InitRegistry(Registry&& registry) { + DCHECK(is_empty()); + SetRegistry(std::move(registry)); +} + +WebApp* WebAppRegistrarMutable::GetAppByIdMutable(const AppId& app_id) { + return const_cast<WebApp*>(GetAppById(app_id)); +} + +WebAppRegistrar::AppSet WebAppRegistrarMutable::AllAppsMutable() { + return AppSet(this); +} + bool IsRegistryEqual(const Registry& registry, const Registry& registry2) { if (registry.size() != registry2.size()) return false;
diff --git a/chrome/browser/web_applications/web_app_registrar.h b/chrome/browser/web_applications/web_app_registrar.h index 11206c9..5f61255 100644 --- a/chrome/browser/web_applications/web_app_registrar.h +++ b/chrome/browser/web_applications/web_app_registrar.h
@@ -9,7 +9,6 @@ #include <memory> #include <string> -#include "base/gtest_prod_util.h" #include "base/logging.h" #include "base/macros.h" #include "base/optional.h" @@ -22,7 +21,7 @@ using Registry = std::map<AppId, std::unique_ptr<WebApp>>; -// A registry. This is a read-only container, which owns WebApp objects. +// A registry model. This is a read-only container, which owns WebApp objects. class WebAppRegistrar : public AppRegistrar { public: explicit WebAppRegistrar(Profile* profile); @@ -95,29 +94,34 @@ const AppSet AllApps() const; - const Registry& registry_for_testing() const { return registry_; } + protected: + Registry& registry() { return registry_; } + void SetRegistry(Registry&& registry); + + void CountMutation(); private: - friend class WebAppSyncBridge; - FRIEND_TEST_ALL_PREFIXES(WebAppRegistrarTest, AllAppsMutable); + Registry registry_; +#if DCHECK_IS_ON() + size_t mutations_count_ = 0; +#endif + DISALLOW_COPY_AND_ASSIGN(WebAppRegistrar); +}; + +// A writable API for the registry model. Mutable WebAppRegistrar must be used +// only by WebAppSyncBridge. +class WebAppRegistrarMutable : public WebAppRegistrar { + public: + explicit WebAppRegistrarMutable(Profile* profile); + ~WebAppRegistrarMutable() override; + + void InitRegistry(Registry&& registry); WebApp* GetAppByIdMutable(const AppId& app_id); AppSet AllAppsMutable(); - void InitRegistry(Registry&& registry); - - void CountMutation(); - - // Used by WebAppSyncBridge controller to to raw updates. - Registry& registry() { return registry_; } - - Registry registry_; - -#if DCHECK_IS_ON() - size_t mutations_count_ = 0; -#endif - - DISALLOW_COPY_AND_ASSIGN(WebAppRegistrar); + using WebAppRegistrar::CountMutation; + using WebAppRegistrar::registry; }; // For testing and debug purposes.
diff --git a/chrome/browser/web_applications/web_app_registrar_unittest.cc b/chrome/browser/web_applications/web_app_registrar_unittest.cc index 735e5e0..b8374d7 100644 --- a/chrome/browser/web_applications/web_app_registrar_unittest.cc +++ b/chrome/browser/web_applications/web_app_registrar_unittest.cc
@@ -237,7 +237,7 @@ TEST_F(WebAppRegistrarTest, AllAppsMutable) { std::set<AppId> ids = InitRegistrarWithApps("https://example.com/path", 10); - for (WebApp& web_app : registrar().AllAppsMutable()) { + for (WebApp& web_app : controller().mutable_registrar().AllAppsMutable()) { web_app.SetLaunchContainer(LaunchContainer::kWindow); const size_t num_removed = ids.erase(web_app.app_id()); EXPECT_EQ(1U, num_removed); @@ -274,11 +274,11 @@ sync_bridge().RegisterApp(std::move(web_app)); EXPECT_EQ(101UL, database_factory().ReadAllAppIds().size()); - EXPECT_EQ(101UL, registrar().registry_for_testing().size()); + EXPECT_EQ(101UL, controller().mutable_registrar().registry().size()); // Remove 1 app after Init. sync_bridge().UnregisterApp(app_id); - EXPECT_EQ(100UL, registrar().registry_for_testing().size()); + EXPECT_EQ(100UL, controller().mutable_registrar().registry().size()); EXPECT_EQ(100UL, database_factory().ReadAllAppIds().size()); // Remove 100 apps after Init.
diff --git a/chrome/browser/web_applications/web_app_registry_update.cc b/chrome/browser/web_applications/web_app_registry_update.cc index 02c650e..d747b50d 100644 --- a/chrome/browser/web_applications/web_app_registry_update.cc +++ b/chrome/browser/web_applications/web_app_registry_update.cc
@@ -5,28 +5,36 @@ #include "chrome/browser/web_applications/web_app_registry_update.h" #include "base/bind_helpers.h" +#include "chrome/browser/web_applications/web_app_registrar.h" #include "chrome/browser/web_applications/web_app_sync_bridge.h" namespace web_app { -WebAppRegistryUpdate::WebAppRegistryUpdate(WebAppSyncBridge* sync_bridge) - : sync_bridge_(sync_bridge) {} +WebAppRegistryUpdate::WebAppRegistryUpdate( + WebAppRegistrarMutable* mutable_registrar) + : mutable_registrar_(mutable_registrar) {} WebAppRegistryUpdate::~WebAppRegistryUpdate() = default; WebApp* WebAppRegistryUpdate::UpdateApp(const AppId& app_id) { - WebApp* app = sync_bridge_->GetAppByIdMutable(app_id); + WebApp* app = mutable_registrar_->GetAppByIdMutable(app_id); if (app) apps_to_update_.insert(app); return app; } +WebAppRegistryUpdate::AppsToUpdate WebAppRegistryUpdate::TakeAppsToUpdate() { + AppsToUpdate apps_to_update = std::move(apps_to_update_); + apps_to_update_.clear(); + return apps_to_update; +} + ScopedRegistryUpdate::ScopedRegistryUpdate(WebAppSyncBridge* sync_bridge) - : update_(sync_bridge->BeginUpdate()) {} + : update_(sync_bridge->BeginUpdate()), sync_bridge_(sync_bridge) {} ScopedRegistryUpdate::~ScopedRegistryUpdate() { - update_->sync_bridge_->CommitUpdate(std::move(update_), base::DoNothing()); + sync_bridge_->CommitUpdate(std::move(update_), base::DoNothing()); } } // namespace web_app
diff --git a/chrome/browser/web_applications/web_app_registry_update.h b/chrome/browser/web_applications/web_app_registry_update.h index 724a4a9..1bb1dd5 100644 --- a/chrome/browser/web_applications/web_app_registry_update.h +++ b/chrome/browser/web_applications/web_app_registry_update.h
@@ -15,28 +15,29 @@ namespace web_app { class WebApp; +class WebAppRegistrarMutable; class WebAppSyncBridge; // An explicit writable "view" for the registry. Any write operations must be -// batched as a part of WebAppRegistryUpdate object. +// batched as a part of WebAppRegistryUpdate object. Effectively +// WebAppRegistryUpdate is a part of WebAppSyncBridge class. // // TODO(loyso): Support creation and deletion of apps as a part of single // update (As in Database CRUD: Create/Update/Delete). class WebAppRegistryUpdate { public: + explicit WebAppRegistryUpdate(WebAppRegistrarMutable* mutable_registrar); ~WebAppRegistryUpdate(); // Acquire a mutable app object to set new field values. WebApp* UpdateApp(const AppId& app_id); + using AppsToUpdate = base::flat_set<const WebApp*>; + AppsToUpdate TakeAppsToUpdate(); + private: - friend class WebAppSyncBridge; - friend class ScopedRegistryUpdate; - - explicit WebAppRegistryUpdate(WebAppSyncBridge* sync_bridge); - - base::flat_set<const WebApp*> apps_to_update_; - WebAppSyncBridge* sync_bridge_; + AppsToUpdate apps_to_update_; + WebAppRegistrarMutable* mutable_registrar_; DISALLOW_COPY_AND_ASSIGN(WebAppRegistryUpdate); }; @@ -52,6 +53,7 @@ private: std::unique_ptr<WebAppRegistryUpdate> update_; + WebAppSyncBridge* sync_bridge_; DISALLOW_COPY_AND_ASSIGN(ScopedRegistryUpdate); };
diff --git a/chrome/browser/web_applications/web_app_sync_bridge.cc b/chrome/browser/web_applications/web_app_sync_bridge.cc index 9aa2de54..6033368 100644 --- a/chrome/browser/web_applications/web_app_sync_bridge.cc +++ b/chrome/browser/web_applications/web_app_sync_bridge.cc
@@ -24,7 +24,7 @@ WebAppSyncBridge::WebAppSyncBridge( Profile* profile, AbstractWebAppDatabaseFactory* database_factory, - WebAppRegistrar* registrar) + WebAppRegistrarMutable* registrar) : WebAppSyncBridge( profile, database_factory, @@ -37,7 +37,7 @@ WebAppSyncBridge::WebAppSyncBridge( Profile* profile, AbstractWebAppDatabaseFactory* database_factory, - WebAppRegistrar* registrar, + WebAppRegistrarMutable* registrar, std::unique_ptr<syncer::ModelTypeChangeProcessor> change_processor) : AppRegistryController(profile), syncer::ModelTypeSyncBridge(std::move(change_processor)), @@ -74,7 +74,7 @@ DCHECK(it != registrar_->registry().end()); auto web_app = std::move(it->second); - registrar_->registry_.erase(it); + registrar_->registry().erase(it); return web_app; } @@ -90,7 +90,7 @@ DCHECK(!is_in_update_); is_in_update_ = true; - return base::WrapUnique(new WebAppRegistryUpdate(this)); + return base::WrapUnique(new WebAppRegistryUpdate(registrar_)); } void WebAppSyncBridge::CommitUpdate( @@ -98,18 +98,27 @@ CommitCallback callback) { DCHECK(is_in_update_); is_in_update_ = false; - if (update == nullptr || update->apps_to_update_.empty()) { + + if (update == nullptr) { + std::move(callback).Run(/*success*/ true); + return; + } + + WebAppRegistryUpdate::AppsToUpdate apps_to_update = + update->TakeAppsToUpdate(); + + if (apps_to_update.empty()) { std::move(callback).Run(/*success*/ true); return; } #if DCHECK_IS_ON() - for (auto* app : update->apps_to_update_) + for (auto* app : apps_to_update) DCHECK(registrar_->GetAppById(app->app_id())); #endif database_->WriteWebApps( - std::move(update->apps_to_update_), + std::move(apps_to_update), base::BindOnce(&WebAppSyncBridge::OnDataWritten, weak_ptr_factory_.GetWeakPtr(), std::move(callback))); } @@ -132,10 +141,6 @@ return this; } -WebApp* WebAppSyncBridge::GetAppByIdMutable(const AppId& app_id) { - return registrar_->GetAppByIdMutable(app_id); -} - void WebAppSyncBridge::OnDatabaseOpened(base::OnceClosure callback, Registry registry) { registrar_->InitRegistry(std::move(registry));
diff --git a/chrome/browser/web_applications/web_app_sync_bridge.h b/chrome/browser/web_applications/web_app_sync_bridge.h index f3eba0f..88b384a7 100644 --- a/chrome/browser/web_applications/web_app_sync_bridge.h +++ b/chrome/browser/web_applications/web_app_sync_bridge.h
@@ -35,12 +35,12 @@ public: WebAppSyncBridge(Profile* profile, AbstractWebAppDatabaseFactory* database_factory, - WebAppRegistrar* registrar); + WebAppRegistrarMutable* registrar); // Tests may inject mocks using this ctor. WebAppSyncBridge( Profile* profile, AbstractWebAppDatabaseFactory* database_factory, - WebAppRegistrar* registrar, + WebAppRegistrarMutable* registrar, std::unique_ptr<syncer::ModelTypeChangeProcessor> change_processor); ~WebAppSyncBridge() override; @@ -66,10 +66,6 @@ WebAppDatabase& database_for_testing() { return *database_; } private: - friend class WebAppRegistryUpdate; - - WebApp* GetAppByIdMutable(const AppId& app_id); - void OnDatabaseOpened(base::OnceClosure callback, Registry registry); void OnDataWritten(CommitCallback callback, bool success); @@ -88,7 +84,7 @@ std::string GetStorageKey(const syncer::EntityData& entity_data) override; std::unique_ptr<WebAppDatabase> database_; - WebAppRegistrar* registrar_; + WebAppRegistrarMutable* registrar_; bool is_in_update_ = false;
diff --git a/chrome/chrome_cleaner/parsers/target/sandbox_setup.cc b/chrome/chrome_cleaner/parsers/target/sandbox_setup.cc index d76775b..6ca95e1 100644 --- a/chrome/chrome_cleaner/parsers/target/sandbox_setup.cc +++ b/chrome/chrome_cleaner/parsers/target/sandbox_setup.cc
@@ -6,10 +6,11 @@ #include <utility> +#include "base/run_loop.h" #include "base/task/single_thread_task_executor.h" -#include "chrome/chrome_cleaner/mojom/parser_interface.mojom.h" #include "chrome/chrome_cleaner/ipc/mojo_sandbox_hooks.h" #include "chrome/chrome_cleaner/ipc/mojo_task_runner.h" +#include "chrome/chrome_cleaner/mojom/parser_interface.mojom.h" #include "chrome/chrome_cleaner/os/early_exit.h" #include "chrome/chrome_cleaner/parsers/target/parser_impl.h" #include "components/chrome_cleaner/public/constants/result_codes.h"
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc index 4cf3935..febb1e8 100644 --- a/chrome/common/chrome_features.cc +++ b/chrome/common/chrome_features.cc
@@ -513,6 +513,11 @@ base::FEATURE_ENABLED_BY_DEFAULT}; #endif // OS_ANDROID +// When kNoReferrers is enabled, most HTTP requests will provide empty +// referrers instead of their ordinary behavior. +const base::Feature kNoReferrers{"NoReferrers", + base::FEATURE_DISABLED_BY_DEFAULT}; + #if defined(OS_POSIX) // Enables NTLMv2, which implicitly disables NTLMv1. const base::Feature kNtlmV2Enabled{"NtlmV2Enabled",
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h index 1395ff2..48f9e8f0 100644 --- a/chrome/common/chrome_features.h +++ b/chrome/common/chrome_features.h
@@ -331,6 +331,8 @@ COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kNewNetErrorPageUI; #endif +COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kNoReferrers; + #if defined(OS_POSIX) COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kNtlmV2Enabled; #endif
diff --git a/chrome/common/importer/profile_import.mojom b/chrome/common/importer/profile_import.mojom index a61e549..6ea9e8f 100644 --- a/chrome/common/importer/profile_import.mojom +++ b/chrome/common/importer/profile_import.mojom
@@ -72,7 +72,7 @@ SourceProfile source_profile, uint16 items, map<uint32, string> localized_strings, - ProfileImportObserver observer); + pending_remote<ProfileImportObserver> observer); // Stop the importer. CancelImport();
diff --git a/chrome/common/media_router/mojom/media_router.mojom b/chrome/common/media_router/mojom/media_router.mojom index db3c481..d0a17b4 100644 --- a/chrome/common/media_router/mojom/media_router.mojom +++ b/chrome/common/media_router/mojom/media_router.mojom
@@ -484,7 +484,7 @@ // between error conditions for metrics/debugging. CreateMediaRouteController(string route_id, pending_receiver<MediaController> media_controller, - MediaStatusObserver observer) => + pending_remote<MediaStatusObserver> observer) => (bool success); }; @@ -523,8 +523,8 @@ // Returns a string that uniquely identifies the Media Router browser // process. RegisterMediaRouteProvider(MediaRouteProvider.Id provider_id, - MediaRouteProvider media_router_provider) => - (string instance_id, MediaRouteProviderConfig config); + pending_remote<MediaRouteProvider> media_router_provider) => + (string instance_id, MediaRouteProviderConfig config); // Called when a MediaRouteProvider receives a new list of |sinks| // compatible with |media_source|. The result is only valid for |origins|. If
diff --git a/chrome/credential_provider/common/BUILD.gn b/chrome/credential_provider/common/BUILD.gn index 69a9bf52..1c3689a 100644 --- a/chrome/credential_provider/common/BUILD.gn +++ b/chrome/credential_provider/common/BUILD.gn
@@ -10,4 +10,7 @@ "gcp_strings.cc", "gcp_strings.h", ] + deps = [ + "//build:branding_buildflags", + ] }
diff --git a/chrome/credential_provider/common/gcp_strings.cc b/chrome/credential_provider/common/gcp_strings.cc index cbe8d4b9..0b231a9 100644 --- a/chrome/credential_provider/common/gcp_strings.cc +++ b/chrome/credential_provider/common/gcp_strings.cc
@@ -4,6 +4,8 @@ #include "chrome/credential_provider/common/gcp_strings.h" +#include "build/branding_buildflags.h" + namespace credential_provider { // Names of keys returned on json data from UI process. @@ -81,10 +83,10 @@ const wchar_t kRunAsCrashpadHandlerEntryPoint[] = L"RunAsCrashpadHandler"; -#if defined(GOOGLE_CHROME_BUILD) +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) const wchar_t kRegHkcuAccountsPath[] = L"Software\\Google\\Accounts"; #else const wchar_t kRegHkcuAccountsPath[] = L"Software\\Chromium\\Accounts"; -#endif // defined(GOOGLE_CHROME_BUILD) +#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING) } // namespace credential_provider
diff --git a/chrome/credential_provider/gaiacp/BUILD.gn b/chrome/credential_provider/gaiacp/BUILD.gn index 38c9123..2efc879 100644 --- a/chrome/credential_provider/gaiacp/BUILD.gn +++ b/chrome/credential_provider/gaiacp/BUILD.gn
@@ -37,6 +37,7 @@ deps = [ ":string_resources", "//base", + "//build:branding_buildflags", "//chrome/common:version_header", "//components/crash/core/common", "//components/version_info", @@ -105,6 +106,7 @@ ":gaia_credential_provider_idl", ":static_resources", "../eventlog:gcp_eventlog_messages", + "//build:branding_buildflags", "//chrome/common:version_header", "//chrome/installer/launcher_support", "//components/crash/content/app:app", @@ -212,6 +214,7 @@ ":common", ":gaiacp_lib", ":version", + "//build:branding_buildflags", "//chrome/common:version_header", ] configs += [ "//build/config/win:windowed" ]
diff --git a/chrome/credential_provider/gaiacp/associated_user_validator_unittests.cc b/chrome/credential_provider/gaiacp/associated_user_validator_unittests.cc index 109cbb0..e0100d7 100644 --- a/chrome/credential_provider/gaiacp/associated_user_validator_unittests.cc +++ b/chrome/credential_provider/gaiacp/associated_user_validator_unittests.cc
@@ -9,6 +9,7 @@ #include "base/synchronization/waitable_event.h" #include "base/test/test_reg_util_win.h" #include "base/time/time_override.h" +#include "build/branding_buildflags.h" #include "chrome/credential_provider/common/gcp_strings.h" #include "chrome/credential_provider/gaiacp/associated_user_validator.h" #include "chrome/credential_provider/gaiacp/gaia_credential_provider.h" @@ -377,7 +378,7 @@ const bool contains_stored_password = std::get<6>(GetParam()); GoogleMdmEnrolledStatusForTesting forced_status(mdm_enrolled); -#if !defined(GOOGLE_CHROME_BUILD) +#if !BUILDFLAG(GOOGLE_CHROME_BRANDING) GoogleMdmEscrowServiceEnablerForTesting escrow_service_enabler(true); #endif @@ -513,7 +514,7 @@ } TEST_F(AssociatedUserValidatorTest, InvalidTokenHandle_MissingPasswordLsaData) { -#if !defined(GOOGLE_CHROME_BUILD) +#if !BUILDFLAG(GOOGLE_CHROME_BRANDING) GoogleMdmEscrowServiceEnablerForTesting escrow_service_enabler(true); #endif @@ -544,7 +545,7 @@ } TEST_F(AssociatedUserValidatorTest, ValidTokenHandle_PresentPasswordLsaData) { -#if !defined(GOOGLE_CHROME_BUILD) +#if !BUILDFLAG(GOOGLE_CHROME_BRANDING) GoogleMdmEscrowServiceEnablerForTesting escrow_service_enabler(true); #endif
diff --git a/chrome/credential_provider/gaiacp/dllmain.cc b/chrome/credential_provider/gaiacp/dllmain.cc index 0422735..b3eb9c0 100644 --- a/chrome/credential_provider/gaiacp/dllmain.cc +++ b/chrome/credential_provider/gaiacp/dllmain.cc
@@ -24,6 +24,7 @@ #include "base/win/current_module.h" #include "base/win/registry.h" #include "base/win/scoped_com_initializer.h" +#include "build/branding_buildflags.h" #include "chrome/common/chrome_version.h" #include "chrome/credential_provider/common/gcp_strings.h" #include "chrome/credential_provider/gaiacp/gaia_credential.h" @@ -99,7 +100,7 @@ LOGFN(INFO) << "_AtlModule.DllRegisterServer hr=" << putHR(hr); } -#if defined(GOOGLE_CHROME_BUILD) +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) // Register with Google Update. if (SUCCEEDED(hr)) { base::win::RegKey key(HKEY_LOCAL_MACHINE, @@ -119,14 +120,14 @@ } } } -#endif // defined(GOOGLE_CHROME_BUILD) +#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING) return hr; } // DllUnregisterServer - Removes entries from the system registry. STDAPI DllUnregisterServer(void) { -#if defined(GOOGLE_CHROME_BUILD) +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) // Unregister with Google Update. base::win::RegKey key(HKEY_LOCAL_MACHINE, L"", DELETE | KEY_WOW64_32KEY); LONG sts = key.DeleteKey(credential_provider::kRegUpdaterClientsAppPath);
diff --git a/chrome/credential_provider/gaiacp/gaia_credential_base.cc b/chrome/credential_provider/gaiacp/gaia_credential_base.cc index 60fd50d..a2328282 100644 --- a/chrome/credential_provider/gaiacp/gaia_credential_base.cc +++ b/chrome/credential_provider/gaiacp/gaia_credential_base.cc
@@ -31,6 +31,7 @@ #include "base/win/registry.h" #include "base/win/scoped_com_initializer.h" #include "base/win/scoped_handle.h" +#include "build/branding_buildflags.h" #include "chrome/credential_provider/common/gcp_strings.h" #include "chrome/credential_provider/gaiacp/associated_user_validator.h" #include "chrome/credential_provider/gaiacp/auth_utils.h" @@ -1116,7 +1117,7 @@ // static void CGaiaCredentialBase::TellOmahaDidRun() { -#if defined(GOOGLE_CHROME_BUILD) +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) // Tell omaha that product was used. Best effort only. // // This code always runs as LocalSystem, which means that HKCU maps to @@ -1132,7 +1133,7 @@ if (sts != ERROR_SUCCESS) LOGFN(INFO) << "Unable to write omaha dr value sts=" << sts; } -#endif // defined(GOOGLE_CHROME_BUILD) +#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING) } void CGaiaCredentialBase::PreventDenyAccessUpdate() {
diff --git a/chrome/credential_provider/gaiacp/gaia_credential_base_unittests.cc b/chrome/credential_provider/gaiacp/gaia_credential_base_unittests.cc index 9fdc63b8..56840227 100644 --- a/chrome/credential_provider/gaiacp/gaia_credential_base_unittests.cc +++ b/chrome/credential_provider/gaiacp/gaia_credential_base_unittests.cc
@@ -8,6 +8,7 @@ #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" +#include "build/branding_buildflags.h" #include "chrome/credential_provider/common/gcp_strings.h" #include "chrome/credential_provider/gaiacp/gaia_credential_base.h" #include "chrome/credential_provider/gaiacp/gaia_resources.h" @@ -1273,7 +1274,7 @@ TEST_P(GcpGaiaCredentialBasePasswordRecoveryTest, PasswordRecovery) { // Enable standard escrow service features in non-Chrome builds so that // the escrow service code can be tested by the build machines. -#if !defined(GOOGLE_CHROME_BUILD) +#if !BUILDFLAG(GOOGLE_CHROME_BRANDING) GoogleMdmEscrowServiceEnablerForTesting escrow_service_enabler(true); #endif USES_CONVERSION; @@ -1497,7 +1498,7 @@ PasswordRecovery_Disabled) { // Enable standard escrow service features in non-Chrome builds so that // the escrow service code can be tested by the build machines. -#if !defined(GOOGLE_CHROME_BUILD) +#if !BUILDFLAG(GOOGLE_CHROME_BRANDING) GoogleMdmEscrowServiceEnablerForTesting escrow_service_enabler(true); #endif USES_CONVERSION;
diff --git a/chrome/credential_provider/gaiacp/gcp_crash_reporter_client.cc b/chrome/credential_provider/gaiacp/gcp_crash_reporter_client.cc index 90e1d99c..6734218 100644 --- a/chrome/credential_provider/gaiacp/gcp_crash_reporter_client.cc +++ b/chrome/credential_provider/gaiacp/gcp_crash_reporter_client.cc
@@ -8,6 +8,7 @@ #include "base/files/file_path.h" #include "base/strings/utf_string_conversions.h" #include "base/win/registry.h" +#include "build/branding_buildflags.h" #include "chrome/credential_provider/gaiacp/gcp_crash_reporting_utils.h" namespace credential_provider { @@ -101,7 +102,7 @@ } bool GcpCrashReporterClient::GetCollectStatsConsent() { -#if defined(GOOGLE_CHROME_BUILD) +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) return GetGCPWCollectStatsConsent(); #else return false;
diff --git a/chrome/credential_provider/gaiacp/gcp_crash_reporting.cc b/chrome/credential_provider/gaiacp/gcp_crash_reporting.cc index 82cb01f..5190f6f 100644 --- a/chrome/credential_provider/gaiacp/gcp_crash_reporting.cc +++ b/chrome/credential_provider/gaiacp/gcp_crash_reporting.cc
@@ -8,6 +8,7 @@ #include "base/debug/leak_annotations.h" #include "base/strings/utf_string_conversions.h" #include "base/win/current_module.h" +#include "build/branding_buildflags.h" #include "chrome/credential_provider/common/gcp_strings.h" #include "chrome/credential_provider/gaiacp/gcp_crash_reporter_client.h" #include "chrome/credential_provider/gaiacp/gcp_crash_reporting_utils.h" @@ -87,9 +88,9 @@ process_type.empty(), "GCPW DLL", "", dll_main_cmd_line.GetProgram(), {base::UTF16ToUTF8(dll_main_cmd_line.GetArgs()[0])}); -#if defined(GOOGLE_CHROME_BUILD) +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) SetCommonCrashKeys(command_line); -#endif // defined(GOOGLE_CHROME_BUILD) +#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING) } } // namespace credential_provider
diff --git a/chrome/credential_provider/gaiacp/reg_utils.cc b/chrome/credential_provider/gaiacp/reg_utils.cc index f253448..11a7d229 100644 --- a/chrome/credential_provider/gaiacp/reg_utils.cc +++ b/chrome/credential_provider/gaiacp/reg_utils.cc
@@ -12,16 +12,17 @@ #include "base/strings/stringprintf.h" #include "base/win/registry.h" #include "base/win/win_util.h" +#include "build/branding_buildflags.h" #include "chrome/credential_provider/common/gcp_strings.h" namespace credential_provider { // Root registry key for GCP configuration and state. -#if defined(GOOGLE_CHROME_BUILD) +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) #define CREDENTIAL_PROVIDER_REGISTRY_KEY L"Software\\Google\\GCP" #else #define CREDENTIAL_PROVIDER_REGISTRY_KEY L"Software\\Chromium\\GCP" -#endif // defined(GOOGLE_CHROME_BUILD) +#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING) const wchar_t kGcpRootKeyName[] = CREDENTIAL_PROVIDER_REGISTRY_KEY;
diff --git a/chrome/credential_provider/setup/BUILD.gn b/chrome/credential_provider/setup/BUILD.gn index 8906ae3..1bfacb7 100644 --- a/chrome/credential_provider/setup/BUILD.gn +++ b/chrome/credential_provider/setup/BUILD.gn
@@ -70,6 +70,7 @@ ":version", "../eventlog:gcp_eventlog_messages", "../gaiacp:common", + "//build:branding_buildflags", "//chrome/common:version_header", "//components/crash/content/app:app", "//components/crash/content/app:crash_export_thunks",
diff --git a/chrome/credential_provider/setup/gcp_installer_crash_reporting.cc b/chrome/credential_provider/setup/gcp_installer_crash_reporting.cc index ba11420..7bce44be6 100644 --- a/chrome/credential_provider/setup/gcp_installer_crash_reporting.cc +++ b/chrome/credential_provider/setup/gcp_installer_crash_reporting.cc
@@ -13,6 +13,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/version.h" #include "base/win/registry.h" +#include "build/branding_buildflags.h" #include "chrome/common/chrome_paths.h" #include "chrome/credential_provider/common/gcp_strings.h" #include "chrome/credential_provider/gaiacp/gcp_crash_reporter_client.h" @@ -39,7 +40,7 @@ crash_reporter::InitializeCrashpadWithEmbeddedHandler(true, "GCPW Installer", "", base::FilePath()); -#if defined(GOOGLE_CHROME_BUILD) +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) SetCommonCrashKeys(command_line); static crash_reporter::CrashKeyString<64> operation("operation"); @@ -48,7 +49,7 @@ command_line.HasSwitch(credential_provider::switches::kUninstall); operation.Set(is_uninstall ? "uninstall" : "install"); -#endif // defined(GOOGLE_CHROME_BUILD) +#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING) } } // namespace credential_provider
diff --git a/chrome/credential_provider/test/BUILD.gn b/chrome/credential_provider/test/BUILD.gn index 5455dcc..6ed135a 100644 --- a/chrome/credential_provider/test/BUILD.gn +++ b/chrome/credential_provider/test/BUILD.gn
@@ -32,6 +32,7 @@ "../gaiacp:version", "../setup:common", "//base", + "//build:branding_buildflags", "//chrome/test:credential_provider_test_utils", "//net:test_support", "//testing/gmock",
diff --git a/chrome/install_static/BUILD.gn b/chrome/install_static/BUILD.gn index a9d691e..67301b6 100644 --- a/chrome/install_static/BUILD.gn +++ b/chrome/install_static/BUILD.gn
@@ -11,6 +11,7 @@ # Please don't add dependencies on other system libraries. static_library("install_static_util") { deps = [ + "//build:branding_buildflags", "//components/nacl/common:buildflags", "//components/version_info:channel", "//components/version_info:generate_version_info", @@ -94,6 +95,7 @@ "//base", "//base/test:run_all_unittests", "//base/test:test_support", + "//build:branding_buildflags", "//chrome/install_static:install_static_util", "//chrome/install_static/test:test_support", "//testing/gmock",
diff --git a/chrome/install_static/install_util.cc b/chrome/install_static/install_util.cc index 75a855f..07d4542 100644 --- a/chrome/install_static/install_util.cc +++ b/chrome/install_static/install_util.cc
@@ -14,6 +14,7 @@ #include <memory> #include <sstream> +#include "build/branding_buildflags.h" #include "chrome/chrome_elf/nt_registry/nt_registry.h" #include "chrome/install_static/install_details.h" #include "chrome/install_static/install_modes.h" @@ -664,7 +665,7 @@ } version_info::Channel GetChromeChannel() { -#if defined(GOOGLE_CHROME_BUILD) +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) std::wstring channel_name(GetChromeChannelName()); if (channel_name.empty()) { return version_info::Channel::STABLE;
diff --git a/chrome/install_static/install_util_unittest.cc b/chrome/install_static/install_util_unittest.cc index 71081f0..e94e63d 100644 --- a/chrome/install_static/install_util_unittest.cc +++ b/chrome/install_static/install_util_unittest.cc
@@ -12,6 +12,7 @@ #include "base/strings/string_util.h" #include "base/test/test_reg_util_win.h" #include "base/win/win_util.h" +#include "build/branding_buildflags.h" #include "chrome/chrome_elf/nt_registry/nt_registry.h" #include "chrome/install_static/install_details.h" #include "chrome/install_static/install_modes.h" @@ -318,7 +319,7 @@ } void SetMetricsReportingPolicy(DWORD value) { -#if defined(GOOGLE_CHROME_BUILD) +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) static constexpr wchar_t kPolicyKey[] = L"Software\\Policies\\Google\\Chrome"; #else @@ -360,7 +361,7 @@ }; TEST_P(InstallStaticUtilTest, GetChromeInstallSubDirectory) { -#if defined(GOOGLE_CHROME_BUILD) +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) // The directory strings for the brand's install modes; parallel to // kInstallModes. static constexpr const wchar_t* kInstallDirs[] = { @@ -381,7 +382,7 @@ } TEST_P(InstallStaticUtilTest, GetRegistryPath) { -#if defined(GOOGLE_CHROME_BUILD) +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) // The registry path strings for the brand's install modes; parallel to // kInstallModes. static constexpr const wchar_t* kRegistryPaths[] = { @@ -402,7 +403,7 @@ } TEST_P(InstallStaticUtilTest, GetUninstallRegistryPath) { -#if defined(GOOGLE_CHROME_BUILD) +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) // The uninstall registry path strings for the brand's install modes; parallel // to kInstallModes. static constexpr const wchar_t* kUninstallRegistryPaths[] = { @@ -435,7 +436,7 @@ return; } -#if defined(GOOGLE_CHROME_BUILD) +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) // The app guids for the brand's install modes; parallel to kInstallModes. static constexpr const wchar_t* kAppGuids[] = { L"{8A69D345-D564-463c-AFF1-A69D9E530F96}", // Google Chrome. @@ -452,7 +453,7 @@ } TEST_P(InstallStaticUtilTest, GetBaseAppId) { -#if defined(GOOGLE_CHROME_BUILD) +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) // The base app ids for the brand's install modes; parallel to kInstallModes. static constexpr const wchar_t* kBaseAppIds[] = { L"Chrome", L"ChromeBeta", L"ChromeDev", L"ChromeCanary", @@ -469,7 +470,7 @@ } TEST_P(InstallStaticUtilTest, GetToastActivatorClsid) { -#if defined(GOOGLE_CHROME_BUILD) +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) // The toast activator CLSIDs for the brand's install modes; parallel to // kInstallModes. static constexpr CLSID kToastActivatorClsids[] = { @@ -527,7 +528,7 @@ } TEST_P(InstallStaticUtilTest, GetElevatorClsid) { -#if defined(GOOGLE_CHROME_BUILD) +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) // The Elevator CLSIDs, one for each of the kInstallModes. static constexpr CLSID kElevatorClsids[] = { {0x708860E0, @@ -581,7 +582,7 @@ } TEST_P(InstallStaticUtilTest, GetElevatorIid) { -#if defined(GOOGLE_CHROME_BUILD) +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) // The Elevator IIDs, one for each of the kInstallModes. static constexpr IID kElevatorIids[] = { {0x463abecf, @@ -710,7 +711,7 @@ } TEST_P(InstallStaticUtilTest, GetSandboxSidPrefix) { -#if defined(GOOGLE_CHROME_BUILD) +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) static constexpr const wchar_t* kSandBoxSids[] = { L"S-1-15-2-3251537155-1984446955-2931258699-841473695-1938553385-" L"924012149-", // Google Chrome. @@ -730,7 +731,7 @@ EXPECT_STREQ(GetSandboxSidPrefix(), kSandBoxSids[std::get<0>(GetParam())]); } -#if defined(GOOGLE_CHROME_BUILD) +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) // Stable supports user and system levels. INSTANTIATE_TEST_SUITE_P(Stable, InstallStaticUtilTest, @@ -751,12 +752,12 @@ InstallStaticUtilTest, testing::Combine(testing::Values(CANARY_INDEX), testing::Values("user"))); -#else // GOOGLE_CHROME_BUILD +#else // BUILDFLAG(GOOGLE_CHROME_BRANDING) // Chromium supports user and system levels. INSTANTIATE_TEST_SUITE_P(Chromium, InstallStaticUtilTest, testing::Combine(testing::Values(CHROMIUM_INDEX), testing::Values("user", "system"))); -#endif // !GOOGLE_CHROME_BUILD +#endif // !BUILDFLAG(GOOGLE_CHROME_BRANDING) } // namespace install_static
diff --git a/chrome/install_static/product_install_details_unittest.cc b/chrome/install_static/product_install_details_unittest.cc index b3213f2..641a568 100644 --- a/chrome/install_static/product_install_details_unittest.cc +++ b/chrome/install_static/product_install_details_unittest.cc
@@ -13,6 +13,7 @@ #include "base/test/test_reg_util_win.h" #include "base/win/registry.h" #include "base/win/windows_version.h" +#include "build/branding_buildflags.h" #include "chrome/chrome_elf/nt_registry/nt_registry.h" #include "chrome/install_static/install_constants.h" #include "chrome/install_static/install_details.h" @@ -128,7 +129,7 @@ const wchar_t* channel; }; -#if defined(GOOGLE_CHROME_BUILD) +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) constexpr TestData kTestData[] = { { L"C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe", @@ -169,7 +170,7 @@ CANARY_INDEX, false, L"canary", }, }; -#else // GOOGLE_CHROME_BUILD +#else // BUILDFLAG(GOOGLE_CHROME_BRANDING) constexpr TestData kTestData[] = { { L"C:\\Program Files (x86)\\Chromium\\Application\\chrome.exe", @@ -180,7 +181,7 @@ CHROMIUM_INDEX, false, L"", }, }; -#endif // !GOOGLE_CHROME_BUILD +#endif // !BUILDFLAG(GOOGLE_CHROME_BRANDING) } // namespace
diff --git a/chrome/install_static/user_data_dir_win_unittest.cc b/chrome/install_static/user_data_dir_win_unittest.cc index 2e987f0..54f86a3 100644 --- a/chrome/install_static/user_data_dir_win_unittest.cc +++ b/chrome/install_static/user_data_dir_win_unittest.cc
@@ -5,6 +5,7 @@ #include <algorithm> #include "base/test/test_reg_util_win.h" +#include "build/branding_buildflags.h" #include "chrome/chrome_elf/nt_registry/nt_registry.h" #include "chrome/install_static/install_details.h" #include "chrome/install_static/user_data_dir.h" @@ -19,7 +20,7 @@ return std::equal(ending.rbegin(), ending.rend(), value.rbegin()); } -#if defined(GOOGLE_CHROME_BUILD) +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) const wchar_t kPolicyRegistryKey[] = L"SOFTWARE\\Policies\\Google\\Chrome"; const wchar_t kUserDataDirNameSuffix[] = L"\\Google\\Chrome\\User Data"; #else
diff --git a/chrome/renderer/safe_browsing/phishing_classifier_delegate.cc b/chrome/renderer/safe_browsing/phishing_classifier_delegate.cc index 37117f0a..b2a77bf4 100644 --- a/chrome/renderer/safe_browsing/phishing_classifier_delegate.cc +++ b/chrome/renderer/safe_browsing/phishing_classifier_delegate.cc
@@ -21,6 +21,7 @@ #include "content/public/renderer/document_state.h" #include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_thread.h" +#include "mojo/public/cpp/bindings/self_owned_receiver.h" #include "services/service_manager/public/cpp/interface_provider.h" #include "third_party/blink/public/platform/web_url.h" #include "third_party/blink/public/web/web_document.h" @@ -52,9 +53,9 @@ // static void PhishingClassifierFilter::Create( - mojom::PhishingModelSetterRequest request) { - mojo::MakeStrongBinding(std::make_unique<PhishingClassifierFilter>(), - std::move(request)); + mojo::PendingReceiver<mojom::PhishingModelSetter> receiver) { + mojo::MakeSelfOwnedReceiver(std::make_unique<PhishingClassifierFilter>(), + std::move(receiver)); } PhishingClassifierFilter::PhishingClassifierFilter() {} @@ -105,7 +106,7 @@ SetPhishingScorer(g_phishing_scorer.Get().get()); registry_.AddInterface( - base::BindRepeating(&PhishingClassifierDelegate::PhishingDetectorRequest, + base::BindRepeating(&PhishingClassifierDelegate::PhishingDetectorReceiver, base::Unretained(this))); } @@ -131,9 +132,9 @@ MaybeStartClassification(); } -void PhishingClassifierDelegate::PhishingDetectorRequest( - mojom::PhishingDetectorRequest request) { - phishing_detector_bindings_.AddBinding(this, std::move(request)); +void PhishingClassifierDelegate::PhishingDetectorReceiver( + mojo::PendingReceiver<mojom::PhishingDetector> receiver) { + phishing_detector_receivers_.Add(this, std::move(receiver)); } void PhishingClassifierDelegate::OnInterfaceRequestForFrame(
diff --git a/chrome/renderer/safe_browsing/phishing_classifier_delegate.h b/chrome/renderer/safe_browsing/phishing_classifier_delegate.h index f052d725..91755fe 100644 --- a/chrome/renderer/safe_browsing/phishing_classifier_delegate.h +++ b/chrome/renderer/safe_browsing/phishing_classifier_delegate.h
@@ -14,8 +14,8 @@ #include "components/safe_browsing/common/safe_browsing.mojom.h" #include "content/public/renderer/render_frame_observer.h" #include "content/public/renderer/render_thread_observer.h" -#include "mojo/public/cpp/bindings/binding_set.h" -#include "mojo/public/cpp/bindings/strong_binding.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/receiver_set.h" #include "services/service_manager/public/cpp/binder_registry.h" #include "ui/base/page_transition_types.h" #include "url/gurl.h" @@ -30,14 +30,13 @@ PhishingClassifierFilter(); ~PhishingClassifierFilter() override; - static void Create(mojom::PhishingModelSetterRequest request); + static void Create( + mojo::PendingReceiver<mojom::PhishingModelSetter> receiver); private: // mojom::PhishingModelSetter void SetPhishingModel(const std::string& model) override; - mojo::StrongBindingPtr<mojom::PhishingModelSetter> binding_; - DISALLOW_COPY_AND_ASSIGN(PhishingClassifierFilter); }; @@ -86,7 +85,8 @@ CANCEL_CLASSIFICATION_MAX // Always add new values before this one. }; - void PhishingDetectorRequest(mojom::PhishingDetectorRequest request); + void PhishingDetectorReceiver( + mojo::PendingReceiver<mojom::PhishingDetector> receiver); // Cancels any pending classification and frees the page text. void CancelPendingClassification(CancelClassificationReason reason); @@ -153,7 +153,7 @@ // The callback from the most recent call to StartPhishingDetection. StartPhishingDetectionCallback callback_; - mojo::BindingSet<mojom::PhishingDetector> phishing_detector_bindings_; + mojo::ReceiverSet<mojom::PhishingDetector> phishing_detector_receivers_; service_manager::BinderRegistry registry_;
diff --git a/chrome/test/base/memory_tracing_browsertest.cc b/chrome/test/base/memory_tracing_browsertest.cc index 85ac8c74..f50cdae7 100644 --- a/chrome/test/base/memory_tracing_browsertest.cc +++ b/chrome/test/base/memory_tracing_browsertest.cc
@@ -26,6 +26,7 @@ namespace { +using base::trace_event::MemoryDumpDeterminism; using base::trace_event::MemoryDumpManager; using base::trace_event::MemoryDumpType; using tracing::BeginTracingWithTraceConfig; @@ -44,6 +45,7 @@ memory_instrumentation::MemoryInstrumentation::GetInstance() ->RequestGlobalDumpAndAppendToTrace( MemoryDumpType::EXPLICITLY_TRIGGERED, explicit_dump_type, + MemoryDumpDeterminism::NONE, Bind(&RequestGlobalDumpCallback, quit_closure)); }
diff --git a/chrome/test/data/webui/settings/chromeos/app_management/pwa_permission_view_test.js b/chrome/test/data/webui/settings/chromeos/app_management/pwa_permission_view_test.js index c49f165..954b64f 100644 --- a/chrome/test/data/webui/settings/chromeos/app_management/pwa_permission_view_test.js +++ b/chrome/test/data/webui/settings/chromeos/app_management/pwa_permission_view_test.js
@@ -8,20 +8,13 @@ let pwaPermissionView; let fakeHandler; - function getPermissionToggleByType(permissionType) { - return pwaPermissionView.root - .querySelector('[permission-type=' + permissionType + ']') - .root.querySelector('app-management-permission-toggle') - .root.querySelector('cr-toggle'); - } - function getPermissionBoolByType(permissionType) { return app_management.util.getPermissionValueBool( pwaPermissionView.app_, permissionType); } async function clickToggle(permissionType) { - getPermissionToggleByType(permissionType).click(); + getPermissionToggleByType(pwaPermissionView, permissionType).click(); await fakeHandler.flushPipesForTesting(); } @@ -54,17 +47,20 @@ test('toggle permissions', async function() { const checkToggle = async (permissionType) => { assertTrue(getPermissionBoolByType(permissionType)); - assertTrue(getPermissionToggleByType(permissionType).checked); + assertTrue(getPermissionCrToggleByType(pwaPermissionView, permissionType) + .checked); // Toggle off. await clickToggle(permissionType); assertFalse(getPermissionBoolByType(permissionType)); - assertFalse(getPermissionToggleByType(permissionType).checked); + assertFalse(getPermissionCrToggleByType(pwaPermissionView, permissionType) + .checked); // Toggle on. await clickToggle(permissionType); assertTrue(getPermissionBoolByType(permissionType)); - assertTrue(getPermissionToggleByType(permissionType).checked); + assertTrue(getPermissionCrToggleByType(pwaPermissionView, permissionType) + .checked); }; await checkToggle('CONTENT_SETTINGS_TYPE_NOTIFICATIONS');
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js index 8f9dcb0..8612521 100644 --- a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js +++ b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
@@ -253,11 +253,9 @@ } }; -TEST_F( - 'OSSettingsAppManagementPwaPermissionViewTest', 'DISABLED_AllJsTests', - () => { - mocha.run(); - }); +TEST_F('OSSettingsAppManagementPwaPermissionViewTest', 'AllJsTests', () => { + mocha.run(); +}); // Test fixture for the app management arc permission view element. // eslint-disable-next-line no-var @@ -276,11 +274,9 @@ } }; -TEST_F( - 'OSSettingsAppManagementArcPermissionViewTest', 'DISABLED_AllJsTests', - () => { - mocha.run(); - }); +TEST_F('OSSettingsAppManagementArcPermissionViewTest', 'AllJsTests', () => { + mocha.run(); +}); // Test fixture for the app management managed app view. // eslint-disable-next-line no-var @@ -316,7 +312,7 @@ } }; -TEST_F('OSSettingsAppManagementReducersTest', 'DISABLED_AllJsTests', () => { +TEST_F('OSSettingsAppManagementReducersTest', 'AllJsTests', () => { mocha.run(); });
diff --git a/chrome/test/media_router/media_router_ui_for_test.cc b/chrome/test/media_router/media_router_ui_for_test.cc index 2c7c4aa..45ad243 100644 --- a/chrome/test/media_router/media_router_ui_for_test.cc +++ b/chrome/test/media_router/media_router_ui_for_test.cc
@@ -5,6 +5,7 @@ #include "chrome/test/media_router/media_router_ui_for_test.h" #include "base/bind.h" +#include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/media/router/media_router_factory.h" #include "chrome/browser/media/router/media_routes_observer.h"
diff --git a/chrome/utility/importer/external_process_importer_bridge.cc b/chrome/utility/importer/external_process_importer_bridge.cc index 9c9c671..cc684e1 100644 --- a/chrome/utility/importer/external_process_importer_bridge.cc +++ b/chrome/utility/importer/external_process_importer_bridge.cc
@@ -4,6 +4,9 @@ #include "chrome/utility/importer/external_process_importer_bridge.h" +#include <algorithm> +#include <utility> + #include "base/bind.h" #include "base/debug/dump_without_crashing.h" #include "base/logging.h" @@ -16,8 +19,6 @@ #include "chrome/common/importer/importer_data_types.h" #include "components/autofill/core/common/password_form.h" -using chrome::mojom::ProfileImportObserver; - namespace { // Rather than sending all import items over IPC at once we chunk them into @@ -32,14 +33,14 @@ ExternalProcessImporterBridge::ExternalProcessImporterBridge( const base::flat_map<uint32_t, std::string>& localized_strings, - scoped_refptr<chrome::mojom::ThreadSafeProfileImportObserverPtr> observer) + mojo::SharedRemote<chrome::mojom::ProfileImportObserver> observer) : localized_strings_(std::move(localized_strings)), observer_(std::move(observer)) {} void ExternalProcessImporterBridge::AddBookmarks( const std::vector<ImportedBookmarkEntry>& bookmarks, const base::string16& first_folder_name) { - (*observer_)->OnBookmarksImportStart(first_folder_name, bookmarks.size()); + observer_->OnBookmarksImportStart(first_folder_name, bookmarks.size()); // |bookmarks_left| is required for the checks below as Windows has a // Debug bounds-check which prevents pushing an iterator beyond its end() @@ -50,7 +51,7 @@ auto end_group = it + std::min(bookmarks_left, kNumBookmarksToSend); bookmark_group.assign(it, end_group); - (*observer_)->OnBookmarksImportGroup(bookmark_group); + observer_->OnBookmarksImportGroup(bookmark_group); bookmarks_left -= end_group - it; it = end_group; } @@ -58,12 +59,12 @@ } void ExternalProcessImporterBridge::AddHomePage(const GURL& home_page) { - (*observer_)->OnHomePageImportReady(home_page); + observer_->OnHomePageImportReady(home_page); } void ExternalProcessImporterBridge::SetFavicons( const favicon_base::FaviconUsageDataList& favicons) { - (*observer_)->OnFaviconsImportStart(favicons.size()); + observer_->OnFaviconsImportStart(favicons.size()); // |favicons_left| is required for the checks below as Windows has a // Debug bounds-check which prevents pushing an iterator beyond its end() @@ -74,7 +75,7 @@ auto end_group = it + std::min(favicons_left, kNumFaviconsToSend); favicons_group.assign(it, end_group); - (*observer_)->OnFaviconsImportGroup(favicons_group); + observer_->OnFaviconsImportGroup(favicons_group); favicons_left -= end_group - it; it = end_group; } @@ -84,7 +85,7 @@ void ExternalProcessImporterBridge::SetHistoryItems( const std::vector<ImporterURLRow>& rows, importer::VisitSource visit_source) { - (*observer_)->OnHistoryImportStart(rows.size()); + observer_->OnHistoryImportStart(rows.size()); // |rows_left| is required for the checks below as Windows has a // Debug bounds-check which prevents pushing an iterator beyond its end() @@ -95,7 +96,7 @@ auto end_group = it + std::min(rows_left, kNumHistoryRowsToSend); row_group.assign(it, end_group); - (*observer_)->OnHistoryImportGroup(row_group, visit_source); + observer_->OnHistoryImportGroup(row_group, visit_source); rows_left -= end_group - it; it = end_group; } @@ -105,22 +106,22 @@ void ExternalProcessImporterBridge::SetKeywords( const std::vector<importer::SearchEngineInfo>& search_engines, bool unique_on_host_and_path) { - (*observer_)->OnKeywordsImportReady(search_engines, unique_on_host_and_path); + observer_->OnKeywordsImportReady(search_engines, unique_on_host_and_path); } void ExternalProcessImporterBridge::SetFirefoxSearchEnginesXMLData( const std::vector<std::string>& search_engine_data) { - (*observer_)->OnFirefoxSearchEngineDataReceived(search_engine_data); + observer_->OnFirefoxSearchEngineDataReceived(search_engine_data); } void ExternalProcessImporterBridge::SetPasswordForm( const autofill::PasswordForm& form) { - (*observer_)->OnPasswordFormImportReady(form); + observer_->OnPasswordFormImportReady(form); } void ExternalProcessImporterBridge::SetAutofillFormData( const std::vector<ImporterAutofillFormDataEntry>& entries) { - (*observer_)->OnAutofillFormDataImportStart(entries.size()); + observer_->OnAutofillFormDataImportStart(entries.size()); // |autofill_form_data_entries_left| is required for the checks below as // Windows has a Debug bounds-check which prevents pushing an iterator beyond @@ -133,7 +134,7 @@ kNumAutofillFormDataToSend); autofill_form_data_entry_group.assign(it, end_group); - (*observer_)->OnAutofillFormDataImportGroup(autofill_form_data_entry_group); + observer_->OnAutofillFormDataImportGroup(autofill_form_data_entry_group); autofill_form_data_entries_left -= end_group - it; it = end_group; } @@ -141,20 +142,20 @@ } void ExternalProcessImporterBridge::NotifyStarted() { - (*observer_)->OnImportStart(); + observer_->OnImportStart(); } void ExternalProcessImporterBridge::NotifyItemStarted( importer::ImportItem item) { - (*observer_)->OnImportItemStart(item); + observer_->OnImportItemStart(item); } void ExternalProcessImporterBridge::NotifyItemEnded(importer::ImportItem item) { - (*observer_)->OnImportItemFinished(item); + observer_->OnImportItemFinished(item); } void ExternalProcessImporterBridge::NotifyEnded() { - (*observer_)->OnImportFinished(true, std::string()); + observer_->OnImportFinished(true, std::string()); } base::string16 ExternalProcessImporterBridge::GetLocalizedString(
diff --git a/chrome/utility/importer/external_process_importer_bridge.h b/chrome/utility/importer/external_process_importer_bridge.h index 5fd2913..58db1e3c5 100644 --- a/chrome/utility/importer/external_process_importer_bridge.h +++ b/chrome/utility/importer/external_process_importer_bridge.h
@@ -5,7 +5,6 @@ #ifndef CHROME_UTILITY_IMPORTER_EXTERNAL_PROCESS_IMPORTER_BRIDGE_H_ #define CHROME_UTILITY_IMPORTER_EXTERNAL_PROCESS_IMPORTER_BRIDGE_H_ -#include <memory> #include <string> #include <vector> @@ -15,6 +14,7 @@ #include "chrome/common/importer/importer_bridge.h" #include "chrome/common/importer/profile_import.mojom.h" #include "components/favicon_base/favicon_usage_data.h" +#include "mojo/public/cpp/bindings/shared_remote.h" class GURL; struct ImportedBookmarkEntry; @@ -38,8 +38,7 @@ // |observer| must outlive this object. ExternalProcessImporterBridge( const base::flat_map<uint32_t, std::string>& localized_strings, - scoped_refptr<chrome::mojom::ThreadSafeProfileImportObserverPtr> - observer); + mojo::SharedRemote<chrome::mojom::ProfileImportObserver> observer); // Begin ImporterBridge implementation: void AddBookmarks(const std::vector<ImportedBookmarkEntry>& bookmarks, @@ -79,7 +78,7 @@ // bundle isn't available to the external process. base::flat_map<uint32_t, std::string> localized_strings_; - scoped_refptr<chrome::mojom::ThreadSafeProfileImportObserverPtr> observer_; + mojo::SharedRemote<chrome::mojom::ProfileImportObserver> observer_; DISALLOW_COPY_AND_ASSIGN(ExternalProcessImporterBridge); };
diff --git a/chrome/utility/importer/profile_import_impl.cc b/chrome/utility/importer/profile_import_impl.cc index 98517c09..d5044a3 100644 --- a/chrome/utility/importer/profile_import_impl.cc +++ b/chrome/utility/importer/profile_import_impl.cc
@@ -4,6 +4,9 @@ #include "chrome/utility/importer/profile_import_impl.h" +#include <string> +#include <utility> + #include "base/bind.h" #include "base/location.h" #include "base/memory/ref_counted.h" @@ -11,10 +14,13 @@ #include "base/threading/thread.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" +#include "chrome/common/importer/profile_import.mojom.h" #include "chrome/utility/importer/external_process_importer_bridge.h" #include "chrome/utility/importer/importer.h" #include "chrome/utility/importer/importer_creator.h" #include "content/public/utility/utility_thread.h" +#include "mojo/public/cpp/bindings/remote.h" +#include "mojo/public/cpp/bindings/shared_remote.h" #if defined(OS_MACOSX) #include <stdlib.h> @@ -22,8 +28,6 @@ #include "chrome/common/importer/firefox_importer_utils.h" #endif -using chrome::mojom::ThreadSafeProfileImportObserverPtr; - ProfileImportImpl::ProfileImportImpl( mojo::PendingReceiver<chrome::mojom::ProfileImport> receiver) : receiver_(this, std::move(receiver)) { @@ -41,11 +45,12 @@ const importer::SourceProfile& source_profile, uint16_t items, const base::flat_map<uint32_t, std::string>& localized_strings, - chrome::mojom::ProfileImportObserverPtr observer) { + mojo::PendingRemote<chrome::mojom::ProfileImportObserver> observer) { content::UtilityThread::Get()->EnsureBlinkInitialized(); importer_ = importer::CreateImporterByType(source_profile.importer_type); if (!importer_.get()) { - observer->OnImportFinished(false, "Importer could not be created."); + mojo::Remote<chrome::mojom::ProfileImportObserver>(std::move(observer)) + ->OnImportFinished(false, "Importer could not be created."); return; } @@ -62,7 +67,8 @@ } bridge_ = new ExternalProcessImporterBridge( localized_strings, - ThreadSafeProfileImportObserverPtr::Create(std::move(observer))); + mojo::SharedRemote<chrome::mojom::ProfileImportObserver>( + std::move(observer))); import_thread_->task_runner()->PostTask( FROM_HERE, base::BindOnce(&Importer::StartImport, importer_, source_profile, items,
diff --git a/chrome/utility/importer/profile_import_impl.h b/chrome/utility/importer/profile_import_impl.h index ebd0986..081fc8f 100644 --- a/chrome/utility/importer/profile_import_impl.h +++ b/chrome/utility/importer/profile_import_impl.h
@@ -8,11 +8,13 @@ #include <stdint.h> #include <memory> +#include <string> #include "base/compiler_specific.h" #include "base/memory/ref_counted.h" #include "chrome/common/importer/profile_import.mojom.h" #include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/receiver.h" class ExternalProcessImporterBridge; @@ -38,7 +40,8 @@ const importer::SourceProfile& source_profile, uint16_t items, const base::flat_map<uint32_t, std::string>& localized_strings, - chrome::mojom::ProfileImportObserverPtr observer) override; + mojo::PendingRemote<chrome::mojom::ProfileImportObserver> observer) + override; void CancelImport() override; void ReportImportItemFinished(importer::ImportItem item) override;
diff --git a/components/autofill/content/renderer/password_autofill_agent.cc b/components/autofill/content/renderer/password_autofill_agent.cc index 8ea4cb3..82363b1 100644 --- a/components/autofill/content/renderer/password_autofill_agent.cc +++ b/components/autofill/content/renderer/password_autofill_agent.cc
@@ -1362,34 +1362,7 @@ CleanupOnDocumentShutdown(); } -void PasswordAutofillAgent::OnProbablyFormSubmitted() { - std::unique_ptr<RendererSavePasswordProgressLogger> logger; - if (logging_state_active_) { - logger.reset(new RendererSavePasswordProgressLogger( - GetPasswordManagerDriver().get())); - logger->LogMessage(Logger::STRING_DID_START_PROVISIONAL_LOAD_METHOD); - } - - if (!FrameCanAccessPasswordManager()) { - if (logger) - logger->LogMessage(Logger::STRING_SECURITY_ORIGIN_FAILURE); - return; - } - - // If onsubmit has been called, try and save that form. - if (provisionally_saved_form_.IsSet()) { - if (logger) { - logger->LogPasswordForm(Logger::STRING_PROVISIONALLY_SAVED_FORM_FOR_FRAME, - provisionally_saved_form_.password_form()); - } - provisionally_saved_form_.SetSubmissionIndicatorEvent( - SubmissionIndicatorEvent:: - PROVISIONALLY_SAVED_FORM_ON_START_PROVISIONAL_LOAD); - GetPasswordManagerDriver()->PasswordFormSubmitted( - provisionally_saved_form_.password_form()); - provisionally_saved_form_.Reset(); - } -} +void PasswordAutofillAgent::OnProbablyFormSubmitted() {} // mojom::PasswordAutofillAgent: void PasswordAutofillAgent::FillPasswordForm(
diff --git a/components/autofill/core/common/form_field_data.cc b/components/autofill/core/common/form_field_data.cc index 6aec9bf..fd68782 100644 --- a/components/autofill/core/common/form_field_data.cc +++ b/components/autofill/core/common/form_field_data.cc
@@ -146,7 +146,7 @@ FormFieldData::FormFieldData(const FormFieldData& other) = default; -FormFieldData::~FormFieldData() {} +FormFieldData::~FormFieldData() = default; bool FormFieldData::SameFieldAs(const FormFieldData& field) const { // TODO(crbug.com/896689): On iOS the unique_id member uniquely addresses @@ -206,6 +206,22 @@ form_control_type == "url" || form_control_type == "email"; } +bool FormFieldData::IsPasswordInputElement() const { + return form_control_type == "password"; +} + +bool FormFieldData::DidUserType() const { + return properties_mask & USER_TYPED; +} + +bool FormFieldData::HadFocus() const { + return properties_mask & HAD_FOCUS; +} + +bool FormFieldData::WasAutofilled() const { + return properties_mask & AUTOFILLED; +} + bool FormFieldData::operator==(const FormFieldData& field) const { return SameFieldAs(field) && unique_renderer_id == field.unique_renderer_id && form_control_ax_id == field.form_control_ax_id &&
diff --git a/components/autofill/core/common/form_field_data.h b/components/autofill/core/common/form_field_data.h index 301b200..c343c454 100644 --- a/components/autofill/core/common/form_field_data.h +++ b/components/autofill/core/common/form_field_data.h
@@ -83,11 +83,19 @@ // a textarea. bool IsTextInputElement() const; + bool IsPasswordInputElement() const; + // Returns true if the field is visible to the user. bool IsVisible() const { return is_focusable && role != RoleAttribute::kPresentation; } + // These functions do not work for Autofill code. + // TODO(https://crbug.com/1006745): Fix this. + bool DidUserType() const; + bool HadFocus() const; + bool WasAutofilled() const; + // Note: operator==() performs a full-field-comparison(byte by byte), this is // different from SameFieldAs(), which ignores comparison for those "values" // not regarded as part of identity of the field, such as is_autofilled and
diff --git a/components/crash/content/app/crashpad_linux.cc b/components/crash/content/app/crashpad_linux.cc index 6378668..8df2da2 100644 --- a/components/crash/content/app/crashpad_linux.cc +++ b/components/crash/content/app/crashpad_linux.cc
@@ -10,6 +10,7 @@ #include "base/path_service.h" #include "base/posix/global_descriptors.h" #include "base/strings/string_number_conversions.h" +#include "build/branding_buildflags.h" #include "components/crash/content/app/crash_reporter_client.h" #include "components/crash/content/app/crash_switches.h" #include "content/public/common/content_descriptors.h" @@ -84,7 +85,7 @@ // to ChromeOS's /sbin/crash_reporter which in turn passes the dump to // crash_sender which handles the upload. std::string url; -#if defined(GOOGLE_CHROME_BUILD) && defined(OFFICIAL_BUILD) && \ +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) && defined(OFFICIAL_BUILD) && \ !defined(OS_CHROMEOS) url = "https://clients2.google.com/cr/report"; #else @@ -99,7 +100,7 @@ annotations["prod"] = product_name; annotations["ver"] = product_version; -#if defined(GOOGLE_CHROME_BUILD) +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) // Empty means stable. const bool allow_empty_channel = true; #else
diff --git a/components/cronet/cronet_url_request_context.h b/components/cronet/cronet_url_request_context.h index 84ea2e5..eab25b5 100644 --- a/components/cronet/cronet_url_request_context.h +++ b/components/cronet/cronet_url_request_context.h
@@ -15,6 +15,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/threading/thread.h" +#include "base/threading/thread_checker.h" #include "components/prefs/json_pref_store.h" #include "net/nqe/effective_connection_type.h" #include "net/nqe/effective_connection_type_observer.h"
diff --git a/components/heap_profiling/supervisor.cc b/components/heap_profiling/supervisor.cc index c4e153e5..4123812 100644 --- a/components/heap_profiling/supervisor.cc +++ b/components/heap_profiling/supervisor.cc
@@ -153,6 +153,7 @@ ->RequestGlobalDumpAndAppendToTrace( base::trace_event::MemoryDumpType::EXPLICITLY_TRIGGERED, base::trace_event::MemoryDumpLevelOfDetail::BACKGROUND, + base::trace_event::MemoryDumpDeterminism::NONE, base::AdaptCallbackForRepeating( std::move(finished_dump_callback))); },
diff --git a/components/network_session_configurator/browser/network_session_configurator.cc b/components/network_session_configurator/browser/network_session_configurator.cc index 3157ffec..237c7b3 100644 --- a/components/network_session_configurator/browser/network_session_configurator.cc +++ b/components/network_session_configurator/browser/network_session_configurator.cc
@@ -321,6 +321,12 @@ "true"); } +bool ShouldQuicAllowPortMigration( + const VariationParameters& quic_trial_params) { + return base::LowerCaseEqualsASCII( + GetVariationParam(quic_trial_params, "allow_port_migration"), "true"); +} + bool ShouldQuicRetryOnAlternateNetworkBeforeHandshake( const VariationParameters& quic_trial_params) { return base::LowerCaseEqualsASCII( @@ -404,12 +410,6 @@ return 0; } -bool ShouldQuicAllowServerMigration( - const VariationParameters& quic_trial_params) { - return base::LowerCaseEqualsASCII( - GetVariationParam(quic_trial_params, "allow_server_migration"), "true"); -} - int GetQuicInitialRttForHandshakeMilliseconds( const VariationParameters& quic_trial_params) { int value; @@ -533,6 +533,8 @@ ShouldQuicMigrateSessionsOnNetworkChangeV2(quic_trial_params); params->quic_params.migrate_sessions_early_v2 = ShouldQuicMigrateSessionsEarlyV2(quic_trial_params); + params->quic_params.allow_port_migration = + ShouldQuicAllowPortMigration(quic_trial_params); params->quic_params.retry_on_alternate_network_before_handshake = ShouldQuicRetryOnAlternateNetworkBeforeHandshake(quic_trial_params); params->quic_params.go_away_on_path_degrading = @@ -580,8 +582,6 @@ .max_migrations_to_non_default_network_on_path_degrading = max_migrations_to_non_default_network_on_path_degrading; } - params->quic_params.allow_server_migration = - ShouldQuicAllowServerMigration(quic_trial_params); params->quic_host_allowlist = GetQuicHostAllowlist(quic_trial_params); SetQuicFlags(quic_trial_params);
diff --git a/components/network_session_configurator/browser/network_session_configurator_unittest.cc b/components/network_session_configurator/browser/network_session_configurator_unittest.cc index e6deb28..7049d68 100644 --- a/components/network_session_configurator/browser/network_session_configurator_unittest.cc +++ b/components/network_session_configurator/browser/network_session_configurator_unittest.cc
@@ -458,15 +458,15 @@ } TEST_F(NetworkSessionConfiguratorTest, - QuicAllowServerMigrationFromFieldTrialParams) { + QuicAllowPortMigrationFromFieldTrialParams) { std::map<std::string, std::string> field_trial_params; - field_trial_params["allow_server_migration"] = "true"; + field_trial_params["allow_port_migration"] = "true"; variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); - EXPECT_TRUE(params_.quic_params.allow_server_migration); + EXPECT_TRUE(params_.quic_params.allow_port_migration); } TEST_F(NetworkSessionConfiguratorTest, PacketLengthFromFieldTrialParams) {
diff --git a/components/password_manager/core/browser/credentials_filter.h b/components/password_manager/core/browser/credentials_filter.h index 13b83d6..21b4520 100644 --- a/components/password_manager/core/browser/credentials_filter.h +++ b/components/password_manager/core/browser/credentials_filter.h
@@ -10,7 +10,7 @@ namespace password_manager { -class PasswordFormManagerInterface; +class PasswordFormManager; // This interface is used to filter credentials during saving, retrieval from // PasswordStore, etc. @@ -35,7 +35,7 @@ // Call this if the form associated with |form_manager| was filled, and the // subsequent sign-in looked like a success. virtual void ReportFormLoginSuccess( - const PasswordFormManagerInterface& form_manager) const {} + const PasswordFormManager& form_manager) const {} // If |username| matches Chrome sync account email. For incognito profile, // it matches |username| against the sync account email used in its original
diff --git a/components/password_manager/core/browser/password_form_manager.h b/components/password_manager/core/browser/password_form_manager.h index 762e7f05..668ce74 100644 --- a/components/password_manager/core/browser/password_form_manager.h +++ b/components/password_manager/core/browser/password_form_manager.h
@@ -36,10 +36,8 @@ struct PossibleUsernameData; // This class helps with filling the observed form and with saving/updating the -// stored information about it. It is aimed to replace PasswordFormManager and -// to be renamed in new Password Manager design. Details -// go/new-cpm-design-refactoring. -class PasswordFormManager : public PasswordFormManagerInterface, +// stored information about it. +class PasswordFormManager : public PasswordFormManagerForUI, public FormFetcher::Consumer { public: // TODO(crbug.com/621355): So far, |form_fetcher| can be null. In that case @@ -159,20 +157,19 @@ void PermanentlyBlacklist() override; void OnPasswordsRevealed() override; - // PasswordFormManagerInterface: - bool IsNewLogin() const override; - FormFetcher* GetFormFetcher() override; - bool IsPendingCredentialsPublicSuffixMatch() const override; - void PresaveGeneratedPassword(const autofill::PasswordForm& form) override; - void PasswordNoLongerGenerated() override; - bool HasGeneratedPassword() const override; + bool IsNewLogin() const; + FormFetcher* GetFormFetcher(); + bool IsPendingCredentialsPublicSuffixMatch() const; + void PresaveGeneratedPassword(const autofill::PasswordForm& form); + void PasswordNoLongerGenerated(); + bool HasGeneratedPassword() const; void SetGenerationPopupWasShown(bool generation_popup_was_shown, - bool is_manual_generation) override; - void SetGenerationElement(const base::string16& generation_element) override; - bool IsPossibleChangePasswordFormWithoutUsername() const override; - bool IsPasswordUpdate() const override; - std::vector<base::WeakPtr<PasswordManagerDriver>> GetDrivers() const override; - const autofill::PasswordForm* GetSubmittedForm() const override; + bool is_manual_generation); + void SetGenerationElement(const base::string16& generation_element); + bool IsPossibleChangePasswordFormWithoutUsername() const; + bool IsPasswordUpdate() const; + std::vector<base::WeakPtr<PasswordManagerDriver>> GetDrivers() const; + const autofill::PasswordForm* GetSubmittedForm() const; #if defined(OS_IOS) // Presaves the form with |generated_password|. This function is called once
diff --git a/components/password_manager/core/browser/password_form_manager_for_ui.h b/components/password_manager/core/browser/password_form_manager_for_ui.h index e92b81b..a859769 100644 --- a/components/password_manager/core/browser/password_form_manager_for_ui.h +++ b/components/password_manager/core/browser/password_form_manager_for_ui.h
@@ -19,7 +19,6 @@ namespace password_manager { -class FormFetcher; struct InteractionsStats; class PasswordFormMetricsRecorder; @@ -98,64 +97,6 @@ virtual void OnPasswordsRevealed() = 0; }; -class PasswordManagerDriver; - -// This is a temporary class for unification of processing of old an new -// PasswordFormManager in PasswordManager. -// TODO(https://crbug.com/831123): Remove when the old PasswordFormManager is -// gone. -class PasswordFormManagerInterface : public PasswordFormManagerForUI { - public: - // Returns whether it is a new (i.e. not saved yet) credentials. - virtual bool IsNewLogin() const = 0; - - // Returns the form fetcher which is responsible for fetching saved matches - // from the store for the observed from. - virtual FormFetcher* GetFormFetcher() = 0; - - // Returns true if the current pending credentials were found using - // origin matching of the public suffix, instead of the signon realm of the - // form. - virtual bool IsPendingCredentialsPublicSuffixMatch() const = 0; - - // Called when generated password is accepted or changed by user. - virtual void PresaveGeneratedPassword(const autofill::PasswordForm& form) = 0; - - // Called when user removed a generated password. - virtual void PasswordNoLongerGenerated() = 0; - - // Returns if the password was generated. - virtual bool HasGeneratedPassword() const = 0; - - // Called when the generation popup is shown. |is_manual_generation| true if - // the generation was initiated by the user. It is used for metrics and votes - // uploading. - // TODO(https://crbug.com/831123): Remove |generation_popup_was_shown| it is - // always true. - virtual void SetGenerationPopupWasShown(bool generation_popup_was_shown, - bool is_manual_generation) = 0; - - // Called when the generation element with identifier |generation_element| is - // found on the page. It is used for metrics and votes uploading. - virtual void SetGenerationElement( - const base::string16& generation_element) = 0; - - // True if we consider this form to be a change password form without username - // field. We use only client heuristics, so it could include signup forms. - virtual bool IsPossibleChangePasswordFormWithoutUsername() const = 0; - - // Helper function that determines whether update or save prompt should be - // shown for credentials in |provisional_save_manager|. - virtual bool IsPasswordUpdate() const = 0; - - // Returns the drivers representing all the frames for the form. - virtual std::vector<base::WeakPtr<PasswordManagerDriver>> GetDrivers() - const = 0; - - // Returns the submitted form, if it exists, otherwise nullptr. - virtual const autofill::PasswordForm* GetSubmittedForm() const = 0; -}; - } // namespace password_manager #endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_FORM_MANAGER_FOR_UI_H_
diff --git a/components/password_manager/core/browser/password_form_metrics_recorder.cc b/components/password_manager/core/browser/password_form_metrics_recorder.cc index c55f3ff..9390846 100644 --- a/components/password_manager/core/browser/password_form_metrics_recorder.cc +++ b/components/password_manager/core/browser/password_form_metrics_recorder.cc
@@ -268,6 +268,11 @@ } } + if (submit_result_ == kSubmitResultPassed && js_only_input_) { + UMA_HISTOGRAM_ENUMERATION( + "PasswordManager.JavaScriptOnlyValueInSubmittedForm", *js_only_input_); + } + if (user_typed_password_on_chrome_sign_in_page_ || password_hash_saved_on_chrome_sing_in_page_) { auto value = password_hash_saved_on_chrome_sing_in_page_ @@ -495,6 +500,8 @@ const std::set<base::string16>& saved_passwords, bool is_blacklisted, const std::vector<InteractionsStats>& interactions_stats) { + CalculateJsOnlyInput(submitted_form); + if (saved_passwords.empty() && is_blacklisted) { filling_assistance_ = FillingAssistance::kNoSavedCredentialsAndBlacklisted; return; @@ -551,6 +558,25 @@ NOTREACHED(); } +void PasswordFormMetricsRecorder::CalculateJsOnlyInput( + const FormData& submitted_form) { + bool had_focus = false; + bool had_user_input_or_autofill_on_password = false; + for (const auto& field : submitted_form.fields) { + if (field.HadFocus()) + had_focus = true; + if (field.IsPasswordInputElement() && + (field.DidUserType() || field.WasAutofilled())) { + had_user_input_or_autofill_on_password = true; + } + } + + js_only_input_ = had_user_input_or_autofill_on_password + ? JsOnlyInput::kAutofillOrUserInput + : (had_focus ? JsOnlyInput::kOnlyJsInputWithFocus + : JsOnlyInput::kOnlyJsInputNoFocus); +} + int PasswordFormMetricsRecorder::GetActionsTaken() const { return static_cast<int>(user_action_) + static_cast<int>(UserAction::kMax) *
diff --git a/components/password_manager/core/browser/password_form_metrics_recorder.h b/components/password_manager/core/browser/password_form_metrics_recorder.h index aecca7b3..cd083d0 100644 --- a/components/password_manager/core/browser/password_form_metrics_recorder.h +++ b/components/password_manager/core/browser/password_form_metrics_recorder.h
@@ -276,6 +276,15 @@ kMaxValue = kNotSaved, }; + // Used in UMA histogram, please do NOT reorder. + // Metric: "PasswordManager.JavaScriptOnlyValueInSubmittedForm" + enum class JsOnlyInput { + kOnlyJsInputNoFocus = 0, + kOnlyJsInputWithFocus = 1, + kAutofillOrUserInput = 2, + kMaxValue = kAutofillOrUserInput, + }; + // The maximum number of combinations of the ManagerAction, UserAction and // SubmitResult enums. // This is used when recording the actions taken by the form in UMA. @@ -394,6 +403,10 @@ bool is_blacklisted, const std::vector<InteractionsStats>& interactions_stats); + // Calculates whether all field values in |submitted_form| came from + // JavaScript. The result is stored in |js_only_input_|. + void CalculateJsOnlyInput(const autofill::FormData& submitted_form); + void set_user_typed_password_on_chrome_sign_in_page() { user_typed_password_on_chrome_sign_in_page_ = true; } @@ -501,6 +514,8 @@ bool possible_username_used_ = false; bool username_updated_in_bubble_ = false; + base::Optional<JsOnlyInput> js_only_input_; + DISALLOW_COPY_AND_ASSIGN(PasswordFormMetricsRecorder); };
diff --git a/components/password_manager/core/browser/password_manager.cc b/components/password_manager/core/browser/password_manager.cc index f65a24c..dc3c32f3 100644 --- a/components/password_manager/core/browser/password_manager.cc +++ b/components/password_manager/core/browser/password_manager.cc
@@ -120,8 +120,7 @@ // Returns true if the user needs to be prompted before a password can be // saved (instead of automatically saving the password), based on inspecting // the state of |manager|. -bool ShouldPromptUserToSavePassword( - const PasswordFormManagerInterface& manager) { +bool ShouldPromptUserToSavePassword(const PasswordFormManager& manager) { if (manager.IsPasswordUpdate()) { // Updating a credential might erase a useful stored value by accident. // Always ask the user to confirm. @@ -275,7 +274,7 @@ void PasswordManager::OnPresaveGeneratedPassword(PasswordManagerDriver* driver, const PasswordForm& form) { DCHECK(client_->IsSavingAndFillingEnabled(form.origin)); - PasswordFormManagerInterface* form_manager = GetMatchedManager(driver, form); + PasswordFormManager* form_manager = GetMatchedManager(driver, form); UMA_HISTOGRAM_BOOLEAN("PasswordManager.GeneratedFormHasNoFormManager", !form_manager); if (form_manager) @@ -286,7 +285,7 @@ const PasswordForm& form) { DCHECK(client_->IsSavingAndFillingEnabled(form.origin)); - PasswordFormManagerInterface* form_manager = GetMatchedManager(driver, form); + PasswordFormManager* form_manager = GetMatchedManager(driver, form); if (form_manager) form_manager->PasswordNoLongerGenerated(); } @@ -298,7 +297,7 @@ bool is_manually_triggered) { DCHECK(client_->IsSavingAndFillingEnabled(form.origin)); - PasswordFormManagerInterface* form_manager = GetMatchedManager(driver, form); + PasswordFormManager* form_manager = GetMatchedManager(driver, form); if (form_manager) { form_manager->SetGenerationElement(generation_element); form_manager->SetGenerationPopupWasShown(true, is_manually_triggered); @@ -321,7 +320,7 @@ // (ntp). OnPasswordFormsRendered is not called on ntp. That is why the // standard flow for saving hash does not work. Save a password hash now // since a navigation to ntp is the sign of successful sign-in. - PasswordFormManagerInterface* manager = GetSubmittedManager(); + PasswordFormManager* manager = GetSubmittedManager(); if (manager && manager->GetSubmittedForm() ->form_data.is_gaia_with_skip_save_password_form) { MaybeSavePasswordHash(manager); @@ -340,14 +339,14 @@ } void PasswordManager::UpdateFormManagers() { - std::vector<PasswordFormManagerInterface*> form_managers; + std::vector<PasswordFormManager*> form_managers; for (const auto& form_manager : form_managers_) form_managers.push_back(form_manager.get()); // Get the fetchers and all the drivers. std::vector<FormFetcher*> fetchers; std::vector<PasswordManagerDriver*> drivers; - for (PasswordFormManagerInterface* form_manager : form_managers) { + for (PasswordFormManager* form_manager : form_managers) { fetchers.push_back(form_manager->GetFormFetcher()); for (const auto& driver : form_manager->GetDrivers()) { if (driver) @@ -707,7 +706,7 @@ logger->LogMessage(Logger::STRING_CAN_PROVISIONAL_MANAGER_SAVE_METHOD); } - PasswordFormManagerInterface* submitted_manager = GetSubmittedManager(); + PasswordFormManager* submitted_manager = GetSubmittedManager(); if (!submitted_manager) { if (logger) { @@ -751,7 +750,7 @@ if (!IsAutomaticSavePromptAvailable()) return; - PasswordFormManagerInterface* submitted_manager = GetSubmittedManager(); + PasswordFormManager* submitted_manager = GetSubmittedManager(); // If the server throws an internal error, access denied page, page not // found etc. after a login attempt, we do not save the credentials. @@ -828,7 +827,7 @@ logger->LogMessage(Logger::STRING_ON_ASK_USER_OR_SAVE_PASSWORD); } - PasswordFormManagerInterface* submitted_manager = GetSubmittedManager(); + PasswordFormManager* submitted_manager = GetSubmittedManager(); DCHECK(submitted_manager); DCHECK(submitted_manager->GetSubmittedForm()); @@ -907,7 +906,7 @@ } void PasswordManager::MaybeSavePasswordHash( - PasswordFormManagerInterface* submitted_manager) { + PasswordFormManager* submitted_manager) { #if defined(SYNC_PASSWORD_REUSE_DETECTION_ENABLED) const PasswordForm* submitted_form = submitted_manager->GetSubmittedForm(); // When |username_value| is empty, it's not clear whether the submitted @@ -1003,7 +1002,7 @@ } -PasswordFormManagerInterface* PasswordManager::GetSubmittedManager() const { +PasswordFormManager* PasswordManager::GetSubmittedManager() const { if (owned_submitted_form_manager_) return owned_submitted_form_manager_.get(); @@ -1045,7 +1044,7 @@ // TODO(https://crbug.com/831123): Implement creating missing // PasswordFormManager when PasswordFormManager is gone. -PasswordFormManagerInterface* PasswordManager::GetMatchedManager( +PasswordFormManager* PasswordManager::GetMatchedManager( const PasswordManagerDriver* driver, const PasswordForm& form) { return GetMatchedManager(driver, form.form_data);
diff --git a/components/password_manager/core/browser/password_manager.h b/components/password_manager/core/browser/password_manager.h index b08c907..a9e5ca0 100644 --- a/components/password_manager/core/browser/password_manager.h +++ b/components/password_manager/core/browser/password_manager.h
@@ -43,9 +43,8 @@ class PasswordManagerClient; class PasswordManagerDriver; class PasswordFormManagerForUI; -class PasswordFormManagerInterface; -class PasswordManagerMetricsRecorder; class PasswordFormManager; +class PasswordManagerMetricsRecorder; struct PossibleUsernameData; // Per-tab password manager. Handles creation and management of UI elements, @@ -151,7 +150,7 @@ return form_managers_; } - PasswordFormManagerInterface* GetSubmittedManagerForTest() const { + PasswordFormManager* GetSubmittedManagerForTest() const { return GetSubmittedManager(); } #if !defined(OS_IOS) @@ -227,7 +226,7 @@ // Helper function called inside OnLoginSuccessful() to save password hash // data from |submitted_manager| for password reuse detection purpose. - void MaybeSavePasswordHash(PasswordFormManagerInterface* submitted_manager); + void MaybeSavePasswordHash(PasswordFormManager* submitted_manager); // Checks for every form in |forms| whether |pending_login_managers_| already // contain a manager for that form. If not, adds a manager for each such form. @@ -262,7 +261,7 @@ // be nullptr if there is no submitted form. // TODO(https://crbug.com/831123): Remove when the old PasswordFormManager is // gone. - PasswordFormManagerInterface* GetSubmittedManager() const; + PasswordFormManager* GetSubmittedManager() const; // Returns the form manager that corresponds to the submitted form. It also // sets |submitted_form_manager_| to nullptr. @@ -279,9 +278,8 @@ // Returns the manager which manages |form|. |driver| is needed to determine // the match. Returns nullptr when no matched manager is found. - PasswordFormManagerInterface* GetMatchedManager( - const PasswordManagerDriver* driver, - const autofill::PasswordForm& form); + PasswordFormManager* GetMatchedManager(const PasswordManagerDriver* driver, + const autofill::PasswordForm& form); // Returns the manager which manages |form|. |driver| is needed to determine // the match. Returns nullptr when no matched manager is found.
diff --git a/components/password_manager/core/browser/password_manager_unittest.cc b/components/password_manager/core/browser/password_manager_unittest.cc index ba3308e..e9943a9d 100644 --- a/components/password_manager/core/browser/password_manager_unittest.cc +++ b/components/password_manager/core/browser/password_manager_unittest.cc
@@ -110,7 +110,7 @@ public: MOCK_CONST_METHOD1(ShouldSave, bool(const autofill::PasswordForm& form)); MOCK_CONST_METHOD1(ReportFormLoginSuccess, - void(const PasswordFormManagerInterface& form_manager)); + void(const PasswordFormManager& form_manager)); MOCK_CONST_METHOD1(IsSyncAccountEmail, bool(const std::string&)); MOCK_CONST_METHOD1(ShouldSaveGaiaPasswordHash, bool(const autofill::PasswordForm&)); @@ -2123,7 +2123,7 @@ EXPECT_CALL(*store_, AddLogin(_)); manager()->OnPresaveGeneratedPassword(&driver_, form); - const PasswordFormManagerInterface* form_manager = + const PasswordFormManager* form_manager = manager()->form_managers().front().get(); EXPECT_TRUE(form_manager->HasGeneratedPassword());
diff --git a/components/password_manager/core/browser/stub_credentials_filter.cc b/components/password_manager/core/browser/stub_credentials_filter.cc index e00176f..8b06737 100644 --- a/components/password_manager/core/browser/stub_credentials_filter.cc +++ b/components/password_manager/core/browser/stub_credentials_filter.cc
@@ -26,7 +26,7 @@ } void StubCredentialsFilter::ReportFormLoginSuccess( - const PasswordFormManagerInterface& form_manager) const {} + const PasswordFormManager& form_manager) const {} bool StubCredentialsFilter::IsSyncAccountEmail( const std::string& username) const {
diff --git a/components/password_manager/core/browser/stub_credentials_filter.h b/components/password_manager/core/browser/stub_credentials_filter.h index 4a6d98e..b85a14b 100644 --- a/components/password_manager/core/browser/stub_credentials_filter.h +++ b/components/password_manager/core/browser/stub_credentials_filter.h
@@ -25,7 +25,7 @@ bool ShouldSaveEnterprisePasswordHash( const autofill::PasswordForm& form) const override; void ReportFormLoginSuccess( - const PasswordFormManagerInterface& form_manager) const override; + const PasswordFormManager& form_manager) const override; bool IsSyncAccountEmail(const std::string& username) const override; private:
diff --git a/components/password_manager/core/browser/sync_credentials_filter.cc b/components/password_manager/core/browser/sync_credentials_filter.cc index 7b8155a9..a453c4b 100644 --- a/components/password_manager/core/browser/sync_credentials_filter.cc +++ b/components/password_manager/core/browser/sync_credentials_filter.cc
@@ -10,7 +10,7 @@ #include "base/metrics/field_trial.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/user_metrics.h" -#include "components/password_manager/core/browser/password_form_manager_for_ui.h" +#include "components/password_manager/core/browser/password_form_manager.h" #include "components/password_manager/core/browser/password_manager_util.h" #include "components/password_manager/core/browser/password_sync_util.h" #include "components/password_manager/core/common/password_manager_features.h" @@ -61,7 +61,7 @@ } void SyncCredentialsFilter::ReportFormLoginSuccess( - const PasswordFormManagerInterface& form_manager) const { + const PasswordFormManager& form_manager) const { if (!form_manager.IsNewLogin() && sync_util::IsSyncAccountCredential(form_manager.GetPendingCredentials(), sync_service_factory_function_.Run(),
diff --git a/components/password_manager/core/browser/sync_credentials_filter.h b/components/password_manager/core/browser/sync_credentials_filter.h index ba17e12..b29c030 100644 --- a/components/password_manager/core/browser/sync_credentials_filter.h +++ b/components/password_manager/core/browser/sync_credentials_filter.h
@@ -39,7 +39,7 @@ bool ShouldSaveEnterprisePasswordHash( const autofill::PasswordForm& form) const override; void ReportFormLoginSuccess( - const PasswordFormManagerInterface& form_manager) const override; + const PasswordFormManager& form_manager) const override; bool IsSyncAccountEmail(const std::string& username) const override; private:
diff --git a/components/plugins/renderer/webview_plugin.cc b/components/plugins/renderer/webview_plugin.cc index b632d29..967bb3a7d 100644 --- a/components/plugins/renderer/webview_plugin.cc +++ b/components/plugins/renderer/webview_plugin.cc
@@ -21,6 +21,7 @@ #include "mojo/public/cpp/bindings/pending_remote.h" #include "skia/ext/platform_canvas.h" #include "third_party/blink/public/mojom/frame/document_interface_broker.mojom.h" +#include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h" #include "third_party/blink/public/platform/web_coalesced_input_event.h" #include "third_party/blink/public/platform/web_url.h" #include "third_party/blink/public/platform/web_url_response.h" @@ -192,10 +193,12 @@ // Plugin updates are forbidden during Blink layout. Therefore, // UpdatePluginForNewGeometry must be posted to a task to run asynchronously. - GetTaskRunner()->PostTask( - FROM_HERE, - base::BindOnce(&WebViewPlugin::UpdatePluginForNewGeometry, - weak_factory_.GetWeakPtr(), window_rect, unobscured_rect)); + blink::scheduler::WebThreadScheduler::MainThreadScheduler() + ->CompositorTaskRunner() + ->PostTask(FROM_HERE, + base::BindOnce(&WebViewPlugin::UpdatePluginForNewGeometry, + weak_factory_.GetWeakPtr(), window_rect, + unobscured_rect)); } void WebViewPlugin::UpdateFocus(bool focused, blink::WebFocusType focus_type) {
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index 2862bc0..811b274 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -17753,7 +17753,7 @@ 'id': 601, 'caption': '''List of names that will bypass the HSTS policy check''', 'tags': ['system-security'], - 'desc': '''Hostnames specified in this list will be exempt from the HSTS policy check that could potentially upgrade requests from http to https. Only single-label hostnames are allowed in this policy. Hostnames must be canonicalized: any IDNs must be convered to their A-label format, and all ASCII letters must be lowercase. This policy only applies to the specific hostnames specified; it does not apply to subdomains of the names specified.''', + 'desc': '''Hostnames specified in this list will be exempt from the HSTS policy check that could potentially upgrade requests from http to https. Only single-label hostnames are allowed in this policy. Hostnames must be canonicalized: any IDNs must be converted to their A-label format, and all ASCII letters must be lowercase. This policy only applies to the specific hostnames specified; it does not apply to subdomains of the names specified.''', }, { 'name': 'AllowSyncXHRInPageDismissal',
diff --git a/components/safe_browsing/password_protection/password_protection_request.h b/components/safe_browsing/password_protection/password_protection_request.h index bf23783..c9612c3 100644 --- a/components/safe_browsing/password_protection/password_protection_request.h +++ b/components/safe_browsing/password_protection/password_protection_request.h
@@ -19,6 +19,7 @@ #include "components/safe_browsing/proto/csd.pb.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/web_contents_observer.h" +#include "mojo/public/cpp/bindings/remote.h" #include "third_party/skia/include/core/SkBitmap.h" class GURL; @@ -257,7 +258,7 @@ base::TimeTicks visual_feature_start_time_; // The Mojo pipe used for extracting DOM features from the renderer. - safe_browsing::mojom::PhishingDetectorPtr phishing_detector_; + mojo::Remote<safe_browsing::mojom::PhishingDetector> phishing_detector_; // When we start extracting DOM features. Used to compute the duration of DOM // feature extraction, which is logged at
diff --git a/components/safe_browsing/password_protection/password_protection_service.cc b/components/safe_browsing/password_protection/password_protection_service.cc index 3a54056..a100ae3 100644 --- a/components/safe_browsing/password_protection/password_protection_service.cc +++ b/components/safe_browsing/password_protection/password_protection_service.cc
@@ -560,8 +560,8 @@ #if BUILDFLAG(FULL_SAFE_BROWSING) void PasswordProtectionService::GetPhishingDetector( service_manager::InterfaceProvider* provider, - mojom::PhishingDetectorPtr* phishing_detector) { - provider->GetInterface(phishing_detector); + mojo::Remote<mojom::PhishingDetector>* phishing_detector) { + provider->GetInterface(phishing_detector->BindNewPipeAndPassReceiver()); } #endif
diff --git a/components/safe_browsing/password_protection/password_protection_service.h b/components/safe_browsing/password_protection/password_protection_service.h index 420e1b8a..e436282 100644 --- a/components/safe_browsing/password_protection/password_protection_service.h +++ b/components/safe_browsing/password_protection/password_protection_service.h
@@ -28,6 +28,7 @@ #include "components/safe_browsing/proto/csd.pb.h" #include "components/sessions/core/session_id.h" #include "components/signin/public/identity_manager/account_info.h" +#include "mojo/public/cpp/bindings/remote.h" #include "services/network/public/cpp/shared_url_loader_factory.h" #include "services/service_manager/public/cpp/interface_provider.h" #include "third_party/protobuf/src/google/protobuf/repeated_field.h" @@ -411,7 +412,7 @@ // |provider|. virtual void GetPhishingDetector( service_manager::InterfaceProvider* provider, - mojom::PhishingDetectorPtr* phishing_detector); + mojo::Remote<mojom::PhishingDetector>* phishing_detector); #endif // The username of the account which password has been reused on. It is only
diff --git a/components/safe_browsing/password_protection/password_protection_service_unittest.cc b/components/safe_browsing/password_protection/password_protection_service_unittest.cc index 50548b7..f889410 100644 --- a/components/safe_browsing/password_protection/password_protection_service_unittest.cc +++ b/components/safe_browsing/password_protection/password_protection_service_unittest.cc
@@ -34,6 +34,8 @@ #include "content/public/test/test_browser_context.h" #include "content/public/test/test_renderer_host.h" #include "content/public/test/web_contents_tester.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/system/message_pipe.h" #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" #include "services/network/test/test_url_loader_factory.h" @@ -81,11 +83,12 @@ class TestPhishingDetector : public mojom::PhishingDetector { public: - TestPhishingDetector() : should_timeout_(false), binding_(this) {} + TestPhishingDetector() : should_timeout_(false) {} ~TestPhishingDetector() override {} void Bind(mojo::ScopedMessagePipeHandle handle) { - binding_.Bind(mojom::PhishingDetectorRequest(std::move(handle))); + receiver_.Bind( + mojo::PendingReceiver<mojom::PhishingDetector>(std::move(handle))); } void StartPhishingDetection( @@ -110,7 +113,7 @@ private: bool should_timeout_; std::vector<StartPhishingDetectionCallback> deferred_callbacks_; - mojo::Binding<mojom::PhishingDetector> binding_; + mojo::Receiver<mojom::PhishingDetector> receiver_{this}; DISALLOW_COPY_AND_ASSIGN(TestPhishingDetector); }; @@ -153,13 +156,13 @@ void GetPhishingDetector( service_manager::InterfaceProvider* provider, - mojom::PhishingDetectorPtr* phishing_detector) override { + mojo::Remote<mojom::PhishingDetector>* phishing_detector) override { service_manager::InterfaceProvider::TestApi test_api(provider); test_api.SetBinderForName( mojom::PhishingDetector::Name_, base::BindRepeating(&TestPhishingDetector::Bind, base::Unretained(&test_phishing_detector_))); - provider->GetInterface(phishing_detector); + provider->GetInterface(phishing_detector->BindNewPipeAndPassReceiver()); test_api.ClearBinderForName(mojom::PhishingDetector::Name_); }
diff --git a/components/signin/internal/identity_manager/fake_profile_oauth2_token_service.cc b/components/signin/internal/identity_manager/fake_profile_oauth2_token_service.cc index feffe3b..f3aa3e0 100644 --- a/components/signin/internal/identity_manager/fake_profile_oauth2_token_service.cc +++ b/components/signin/internal/identity_manager/fake_profile_oauth2_token_service.cc
@@ -10,14 +10,9 @@ FakeProfileOAuth2TokenService::FakeProfileOAuth2TokenService( PrefService* user_prefs) - : FakeProfileOAuth2TokenService( + : ProfileOAuth2TokenService( user_prefs, - std::make_unique<FakeProfileOAuth2TokenServiceDelegate>()) {} - -FakeProfileOAuth2TokenService::FakeProfileOAuth2TokenService( - PrefService* user_prefs, - std::unique_ptr<ProfileOAuth2TokenServiceDelegate> delegate) - : ProfileOAuth2TokenService(user_prefs, std::move(delegate)) { + std::make_unique<FakeProfileOAuth2TokenServiceDelegate>()) { OverrideAccessTokenManagerForTesting( std::make_unique<FakeOAuth2AccessTokenManager>( this /* OAuth2AccessTokenManager::Delegate* */));
diff --git a/components/signin/internal/identity_manager/fake_profile_oauth2_token_service.h b/components/signin/internal/identity_manager/fake_profile_oauth2_token_service.h index 09d09e1..dc8f4ba 100644 --- a/components/signin/internal/identity_manager/fake_profile_oauth2_token_service.h +++ b/components/signin/internal/identity_manager/fake_profile_oauth2_token_service.h
@@ -36,9 +36,6 @@ class FakeProfileOAuth2TokenService : public ProfileOAuth2TokenService { public: explicit FakeProfileOAuth2TokenService(PrefService* user_prefs); - FakeProfileOAuth2TokenService( - PrefService* user_prefs, - std::unique_ptr<ProfileOAuth2TokenServiceDelegate> delegate); ~FakeProfileOAuth2TokenService() override; // Gets a list of active requests (can be used by tests to validate that the
diff --git a/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.cc b/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.cc index 46b5457..6b8be382 100644 --- a/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.cc +++ b/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.cc
@@ -438,6 +438,7 @@ set_load_credentials_state( signin::LoadCredentialsState:: LOAD_CREDENTIALS_FINISHED_WITH_UNKNOWN_ERRORS); + MaybeDeletePreDiceTokens(); FinishLoadingCredentials(); return; } @@ -476,6 +477,7 @@ set_load_credentials_state( signin::LoadCredentialsState:: LOAD_CREDENTIALS_FINISHED_WITH_DB_CANNOT_BE_OPENED); + MaybeDeletePreDiceTokens(); } // Make sure that we have an entry for |loading_primary_account_id_| in the @@ -848,6 +850,10 @@ } void MutableProfileOAuth2TokenServiceDelegate::FinishLoadingCredentials() { +#if !defined(OS_CHROMEOS) + if (account_consistency_ == signin::AccountConsistencyMethod::kDice) + DCHECK(client_->GetPrefs()->GetBoolean(prefs::kTokenServiceDiceCompatible)); +#endif FireRefreshTokensLoaded(); } @@ -868,3 +874,18 @@ FireRefreshTokenRevoked(account_id); } } + +void MutableProfileOAuth2TokenServiceDelegate::MaybeDeletePreDiceTokens() { + DCHECK(load_credentials_state() == + signin::LoadCredentialsState:: + LOAD_CREDENTIALS_FINISHED_WITH_UNKNOWN_ERRORS || + load_credentials_state() == + signin::LoadCredentialsState:: + LOAD_CREDENTIALS_FINISHED_WITH_DB_CANNOT_BE_OPENED); + + if (account_consistency_ == signin::AccountConsistencyMethod::kDice && + !client_->GetPrefs()->GetBoolean(prefs::kTokenServiceDiceCompatible)) { + RevokeAllCredentials(); + client_->GetPrefs()->SetBoolean(prefs::kTokenServiceDiceCompatible, true); + } +}
diff --git a/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.h b/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.h index 5f0380d..41b71cd 100644 --- a/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.h +++ b/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.h
@@ -189,6 +189,11 @@ void RevokeCredentialsImpl(const CoreAccountId& account_id, bool revoke_on_server); + // If the Dice migration happened before the tokens could be migrated, delete + // all the tokens. This is only called if the tokens could not be loaded + // successfully. + void MaybeDeletePreDiceTokens(); + // Maps the |account_id| of accounts known to ProfileOAuth2TokenService // to information about the account. typedef std::map<CoreAccountId, AccountStatus> AccountStatusMap;
diff --git a/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate_unittest.cc b/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate_unittest.cc index 2df7204..336de645 100644 --- a/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate_unittest.cc +++ b/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate_unittest.cc
@@ -708,6 +708,51 @@ EXPECT_TRUE(pref_service_.GetBoolean(prefs::kTokenServiceDiceCompatible)); } +// Checks that tokens are loaded and prefs::kTokenServiceDiceCompatible is set +// to true if the tokens are loaded after the Dice migration. +TEST_F(MutableProfileOAuth2TokenServiceDelegateTest, LoadAfterDiceMigration) { + InitializeOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDice); + ASSERT_FALSE(pref_service_.GetBoolean(prefs::kTokenServiceDiceCompatible)); + + // Add account info to the account tracker. + AccountInfo primary_account = CreateTestAccountInfo( + "primary_account", false /* is_hosted_domain*/, true /* is_valid*/); + account_tracker_service_.SeedAccountInfo(primary_account); + AddAuthTokenManually("AccountId-" + primary_account.account_id.id, + "refresh_token"); + + oauth2_service_delegate_->LoadCredentials(std::string()); + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(oauth2_service_delegate_->RefreshTokenIsAvailable( + primary_account.account_id)); + EXPECT_EQ( + signin::LoadCredentialsState::LOAD_CREDENTIALS_FINISHED_WITH_SUCCESS, + oauth2_service_delegate_->load_credentials_state()); + + ASSERT_TRUE(pref_service_.GetBoolean(prefs::kTokenServiceDiceCompatible)); +} + +// Checks that prefs::kTokenServiceDiceCompatible is set to true if the tokens +// are loaded after the Dice migration, even if there was a database read error. +TEST_F(MutableProfileOAuth2TokenServiceDelegateTest, + LoadAfterDiceMigrationWithError) { + InitializeOAuth2ServiceDelegate(signin::AccountConsistencyMethod::kDice); + ASSERT_FALSE(pref_service_.GetBoolean(prefs::kTokenServiceDiceCompatible)); + + // Shutdown the database to trigger a database read error. + token_web_data_->ShutdownDatabase(); + + oauth2_service_delegate_->LoadCredentials(std::string()); + base::RunLoop().RunUntilIdle(); + + EXPECT_EQ(0u, oauth2_service_delegate_->GetAccounts().size()); + EXPECT_EQ(signin::LoadCredentialsState:: + LOAD_CREDENTIALS_FINISHED_WITH_DB_CANNOT_BE_OPENED, + oauth2_service_delegate_->load_credentials_state()); + + ASSERT_TRUE(pref_service_.GetBoolean(prefs::kTokenServiceDiceCompatible)); +} #endif // BUILDFLAG(ENABLE_DICE_SUPPORT) #if !defined(OS_CHROMEOS)
diff --git a/components/signin/internal/identity_manager/primary_account_manager.cc b/components/signin/internal/identity_manager/primary_account_manager.cc index 10a91ae..4628e18 100644 --- a/components/signin/internal/identity_manager/primary_account_manager.cc +++ b/components/signin/internal/identity_manager/primary_account_manager.cc
@@ -153,22 +153,6 @@ return authenticated_account_info_.has_value(); } -void PrimaryAccountManager::SetGoogleSigninSucceededCallback( - AccountSigninCallback callback) { - DCHECK(!on_google_signin_succeeded_callback_) - << "GoogleSigninSucceededCallback shouldn't be set multiple times."; - on_google_signin_succeeded_callback_ = callback; -} - -#if !defined(OS_CHROMEOS) -void PrimaryAccountManager::SetGoogleSignedOutCallback( - AccountSigninCallback callback) { - DCHECK(!on_google_signed_out_callback_) - << "GoogleSignedOutCallback shouldn't be set multiple times."; - on_google_signed_out_callback_ = callback; -} -#endif // !defined(OS_CHROMEOS) - void PrimaryAccountManager::SignIn(const std::string& username) { CoreAccountInfo info = account_tracker_service_->FindAccountInfoByEmail(username); @@ -184,8 +168,8 @@ SetAuthenticatedAccountInfo(info); - if (on_google_signin_succeeded_callback_) - on_google_signin_succeeded_callback_.Run(GetAuthenticatedAccountInfo()); + for (Observer& observer : observers_) + observer.GoogleSigninSucceeded(info); } void PrimaryAccountManager::UpdateAuthenticatedAccountInfo() { @@ -196,6 +180,14 @@ authenticated_account_info_ = info; } +void PrimaryAccountManager::AddObserver(Observer* observer) { + observers_.AddObserver(observer); +} + +void PrimaryAccountManager::RemoveObserver(const Observer* observer) { + observers_.RemoveObserver(observer); +} + #if !defined(OS_CHROMEOS) void PrimaryAccountManager::SignOut( signin_metrics::ProfileSignout signout_source_metric, @@ -283,8 +275,8 @@ break; } - if (on_google_signed_out_callback_) - on_google_signed_out_callback_.Run(account_info); + for (Observer& observer : observers_) + observer.GoogleSignedOut(account_info); } void PrimaryAccountManager::OnRefreshTokensLoaded() {
diff --git a/components/signin/internal/identity_manager/primary_account_manager.h b/components/signin/internal/identity_manager/primary_account_manager.h index a5aebf54..128a47a7 100644 --- a/components/signin/internal/identity_manager/primary_account_manager.h +++ b/components/signin/internal/identity_manager/primary_account_manager.h
@@ -21,9 +21,9 @@ #include <memory> #include <string> -#include "base/callback.h" -#include "base/callback_list.h" #include "base/macros.h" +#include "base/observer_list.h" +#include "base/observer_list_types.h" #include "base/optional.h" #include "components/signin/internal/identity_manager/profile_oauth2_token_service_observer.h" #include "components/signin/public/base/account_consistency_method.h" @@ -43,8 +43,17 @@ class PrimaryAccountManager : public ProfileOAuth2TokenServiceObserver { public: - typedef base::RepeatingCallback<void(const CoreAccountInfo&)> - AccountSigninCallback; + class Observer : public base::CheckedObserver { + public: + // Called whenever a user signs into Google services such as sync. + // Not called during a reauth. + virtual void GoogleSigninSucceeded(const CoreAccountInfo& info) {} + +#if !defined(OS_CHROMEOS) + // Called whenever the currently signed-in user has been signed out. + virtual void GoogleSignedOut(const CoreAccountInfo& info) {} +#endif + }; #if !defined(OS_CHROMEOS) // Used to remove accounts from the token service and the account tracker. @@ -95,16 +104,6 @@ // Returns true if there is an authenticated user. bool IsAuthenticated() const; - // If set, this callback will be invoked whenever a user signs into Google - // services such as sync. This callback is not called during a reauth. - void SetGoogleSigninSucceededCallback(AccountSigninCallback callback); - -#if !defined(OS_CHROMEOS) - // If set, this callback will be invoked whenever the currently signed-in user - // for a user has been signed out. - void SetGoogleSignedOutCallback(AccountSigninCallback callback); -#endif - // Signs a user in. PrimaryAccountManager assumes that |username| can be used // to look up the corresponding account_id and gaia_id for this email. void SignIn(const std::string& username); @@ -140,6 +139,10 @@ signin_metrics::SignoutDelete signout_delete_metric); #endif + // Adds and removes observers. + void AddObserver(Observer* observer); + void RemoveObserver(const Observer* observer); + private: // Sets the authenticated user's account id. // If the user is already authenticated with the same account id, then this @@ -179,20 +182,12 @@ // Account id after successful authentication. base::Optional<CoreAccountInfo> authenticated_account_info_; - // Callbacks which will be invoked, if set, for signin-related events. - AccountSigninCallback on_google_signin_succeeded_callback_; -#if !defined(OS_CHROMEOS) - AccountSigninCallback on_google_signed_out_callback_; -#endif - - // The list of callbacks notified on shutdown. - base::CallbackList<void()> on_shutdown_callback_list_; - #if !defined(OS_CHROMEOS) signin::AccountConsistencyMethod account_consistency_; #endif std::unique_ptr<PrimaryAccountPolicyManager> policy_manager_; + base::ObserverList<Observer> observers_; DISALLOW_COPY_AND_ASSIGN(PrimaryAccountManager); };
diff --git a/components/signin/internal/identity_manager/primary_account_manager_unittest.cc b/components/signin/internal/identity_manager/primary_account_manager_unittest.cc index 8a5d236..76f9a6f 100644 --- a/components/signin/internal/identity_manager/primary_account_manager_unittest.cc +++ b/components/signin/internal/identity_manager/primary_account_manager_unittest.cc
@@ -31,7 +31,8 @@ #include "components/signin/internal/identity_manager/primary_account_policy_manager_impl.h" #endif -class PrimaryAccountManagerTest : public testing::Test { +class PrimaryAccountManagerTest : public testing::Test, + public PrimaryAccountManager::Observer { public: PrimaryAccountManagerTest() : test_signin_client_(&user_prefs_), @@ -94,21 +95,13 @@ &test_signin_client_, &token_service_, &account_tracker_, account_consistency_, std::move(policy_manager)); manager_->Initialize(&local_state_); - - // PrimaryAccountManagerTest will outlive the PrimaryAccountManager, so - // base::Unretained is safe. - manager_->SetGoogleSigninSucceededCallback( - base::BindRepeating(&PrimaryAccountManagerTest::GoogleSigninSucceeded, - base::Unretained(this))); -#if !defined(OS_CHROMEOS) - manager_->SetGoogleSignedOutCallback(base::BindRepeating( - &PrimaryAccountManagerTest::GoogleSignedOut, base::Unretained(this))); -#endif + manager_->AddObserver(this); } // Shuts down |manager_|. void ShutDownManager() { DCHECK(manager_); + manager_->RemoveObserver(this); manager_.reset(); } @@ -124,11 +117,15 @@ EXPECT_EQ(1, num_successful_signins_); } - void GoogleSigninSucceeded(const CoreAccountInfo& account_info) { + void GoogleSigninSucceeded(const CoreAccountInfo& account_info) override { num_successful_signins_++; } - void GoogleSignedOut(const CoreAccountInfo& account_info) { num_signouts_++; } +#if !defined(OS_CHROMEOS) + void GoogleSignedOut(const CoreAccountInfo& account_info) override { + num_signouts_++; + } +#endif base::test::TaskEnvironment task_environment_; sync_preferences::TestingPrefServiceSyncable user_prefs_;
diff --git a/components/signin/public/identity_manager/identity_manager.cc b/components/signin/public/identity_manager/identity_manager.cc index 4e6987a4..a5cd63c 100644 --- a/components/signin/public/identity_manager/identity_manager.cc +++ b/components/signin/public/identity_manager/identity_manager.cc
@@ -11,7 +11,6 @@ #include "components/signin/internal/identity_manager/account_fetcher_service.h" #include "components/signin/internal/identity_manager/account_tracker_service.h" #include "components/signin/internal/identity_manager/gaia_cookie_manager_service.h" -#include "components/signin/internal/identity_manager/primary_account_manager.h" #include "components/signin/internal/identity_manager/profile_oauth2_token_service.h" #include "components/signin/internal/identity_manager/ubertoken_fetcher_impl.h" #include "components/signin/public/identity_manager/accounts_cookie_mutator.h" @@ -52,21 +51,14 @@ std::move(accounts_mutator), std::move(accounts_cookie_mutator), std::move(device_accounts_synchronizer)), - diagnostics_provider_(std::move(diagnostics_provider)) { + diagnostics_provider_(std::move(diagnostics_provider)), + primary_account_manager_observer_(this), + token_service_observer_(this) { DCHECK(account_fetcher_service_); DCHECK(diagnostics_provider_); - // IdentityManager will outlive the PrimaryAccountManager, so base::Unretained - // is safe. - primary_account_manager_->SetGoogleSigninSucceededCallback( - base::BindRepeating(&IdentityManager::GoogleSigninSucceeded, - base::Unretained(this))); -#if !defined(OS_CHROMEOS) - primary_account_manager_->SetGoogleSignedOutCallback(base::BindRepeating( - &IdentityManager::GoogleSignedOut, base::Unretained(this))); -#endif - - token_service_->AddObserver(this); + primary_account_manager_observer_.Add(primary_account_manager_.get()); + token_service_observer_.Add(token_service_.get()); token_service_->AddAccessTokenDiagnosticsObserver(this); // IdentityManager owns the ATS, GCMS and PO2TS instances and will outlive @@ -106,7 +98,6 @@ token_service_->Shutdown(); account_tracker_service_->Shutdown(); - token_service_->RemoveObserver(this); token_service_->RemoveAccessTokenDiagnosticsObserver(this); #if defined(OS_ANDROID) @@ -526,6 +517,7 @@ #endif } +#if !defined(OS_CHROMEOS) void IdentityManager::GoogleSignedOut(const CoreAccountInfo& account_info) { DCHECK(!HasPrimaryAccount()); DCHECK(!account_info.IsEmpty()); @@ -542,6 +534,7 @@ } #endif } +#endif // !defined(OS_CHROMEOS) void IdentityManager::OnRefreshTokenAvailable(const CoreAccountId& account_id) { UpdateUnconsentedPrimaryAccount();
diff --git a/components/signin/public/identity_manager/identity_manager.h b/components/signin/public/identity_manager/identity_manager.h index 7d2ecb1c..1bd4ecd 100644 --- a/components/signin/public/identity_manager/identity_manager.h +++ b/components/signin/public/identity_manager/identity_manager.h
@@ -10,8 +10,10 @@ #include "base/macros.h" #include "base/observer_list.h" +#include "base/scoped_observer.h" #include "build/build_config.h" #include "components/keyed_service/core/keyed_service.h" +#include "components/signin/internal/identity_manager/primary_account_manager.h" #include "components/signin/internal/identity_manager/profile_oauth2_token_service_observer.h" #include "components/signin/public/identity_manager/access_token_fetcher.h" #include "components/signin/public/identity_manager/account_info.h" @@ -55,6 +57,7 @@ // ./README.md for detailed documentation. class IdentityManager : public KeyedService, public OAuth2AccessTokenManager::DiagnosticsObserver, + public PrimaryAccountManager::Observer, public ProfileOAuth2TokenServiceObserver { public: class Observer { @@ -596,9 +599,11 @@ // current cookies. base::Optional<CoreAccountInfo> ComputeUnconsentedPrimaryAccountInfo() const; - // PrimaryAccountManager callbacks: - void GoogleSigninSucceeded(const CoreAccountInfo& account_info); - void GoogleSignedOut(const CoreAccountInfo& account_info); + // PrimaryAccountManager::Observer: + void GoogleSigninSucceeded(const CoreAccountInfo& account_info) override; +#if !defined(OS_CHROMEOS) + void GoogleSignedOut(const CoreAccountInfo& account_info) override; +#endif // ProfileOAuth2TokenServiceObserver: void OnRefreshTokenAvailable(const CoreAccountId& account_id) override; @@ -650,6 +655,12 @@ // DiagnosticsProvider instance. std::unique_ptr<DiagnosticsProvider> diagnostics_provider_; + // Scoped observers. + ScopedObserver<PrimaryAccountManager, IdentityManager> + primary_account_manager_observer_; + ScopedObserver<ProfileOAuth2TokenService, IdentityManager> + token_service_observer_; + // Lists of observers. // Makes sure lists are empty on destruction. base::ObserverList<Observer, true>::Unchecked observer_list_;
diff --git a/components/sync/BUILD.gn b/components/sync/BUILD.gn index 0c0e3a30..d360d64 100644 --- a/components/sync/BUILD.gn +++ b/components/sync/BUILD.gn
@@ -344,6 +344,8 @@ "syncable/directory_backing_store.cc", "syncable/directory_backing_store.h", "syncable/directory_change_delegate.h", + "syncable/directory_cryptographer.cc", + "syncable/directory_cryptographer.h", "syncable/entry.cc", "syncable/entry.h", "syncable/entry_kernel.cc", @@ -640,7 +642,6 @@ "model_impl/model_type_store_impl_unittest.cc", "model_impl/processor_entity_unittest.cc", "model_impl/syncable_service_based_bridge_unittest.cc", - "nigori/cryptographer_unittest.cc", "nigori/nigori_key_bag_unittest.cc", "nigori/nigori_model_type_processor_unittest.cc", "nigori/nigori_storage_impl_unittest.cc", @@ -650,6 +651,7 @@ "protocol/proto_value_conversions_unittest.cc", "syncable/change_record_unittest.cc", "syncable/directory_backing_store_unittest.cc", + "syncable/directory_cryptographer_unittest.cc", "syncable/directory_unittest.cc", "syncable/directory_unittest.h", "syncable/entry_kernel_unittest.cc",
diff --git a/components/sync/driver/generic_change_processor.cc b/components/sync/driver/generic_change_processor.cc index 52d9d87e..c3e3082 100644 --- a/components/sync/driver/generic_change_processor.cc +++ b/components/sync/driver/generic_change_processor.cc
@@ -575,7 +575,7 @@ // We only access the cryptographer while holding a transaction. ReadTransaction trans(FROM_HERE, share_handle()); const ModelTypeSet encrypted_types = trans.GetEncryptedTypes(); - return !encrypted_types.Has(type_) || trans.GetCryptographer()->is_ready(); + return !encrypted_types.Has(type_) || trans.GetCryptographer()->CanEncrypt(); } void GenericChangeProcessor::StartImpl() {}
diff --git a/components/sync/engine_impl/all_status.h b/components/sync/engine_impl/all_status.h index 4fade76..48cb51c 100644 --- a/components/sync/engine_impl/all_status.h +++ b/components/sync/engine_impl/all_status.h
@@ -55,6 +55,8 @@ void IncrementNotificationsReceived(); void SetEncryptedTypes(ModelTypeSet types); + // TODO(crbug.com/967417): Rename Ready->CanEncrypt in consistency with + // Cryptographer's API. void SetCryptographerReady(bool ready); void SetCryptoHasPendingKeys(bool has_pending_keys); void SetPassphraseType(PassphraseType type);
diff --git a/components/sync/engine_impl/apply_control_data_updates.cc b/components/sync/engine_impl/apply_control_data_updates.cc index ebd59ab..6da24e5e 100644 --- a/components/sync/engine_impl/apply_control_data_updates.cc +++ b/components/sync/engine_impl/apply_control_data_updates.cc
@@ -12,8 +12,8 @@ #include "components/sync/engine_impl/conflict_resolver.h" #include "components/sync/engine_impl/conflict_util.h" #include "components/sync/engine_impl/syncer_util.h" -#include "components/sync/nigori/cryptographer.h" #include "components/sync/syncable/directory.h" +#include "components/sync/syncable/directory_cryptographer.h" #include "components/sync/syncable/mutable_entry.h" #include "components/sync/syncable/nigori_handler.h" #include "components/sync/syncable/nigori_util.h" @@ -35,7 +35,14 @@ void ApplyNigoriUpdate(syncable::Directory* dir) { syncable::WriteTransaction trans(FROM_HERE, syncable::SYNCER, dir); syncable::MutableEntry entry(&trans, syncable::GET_TYPE_ROOT, NIGORI); - const Cryptographer* cryptographer = dir->GetCryptographer(&trans); + const DirectoryCryptographer* cryptographer = + dir->GetNigoriHandler()->GetDirectoryCryptographerForNigori(&trans); + + if (!cryptographer) { + // This indicates that the USS implementation of NIGORI is active, hence + // there's nothing to do here. + return; + } if (!entry.good()) { return; @@ -59,7 +66,7 @@ // re-encrypted at SetDecryptionPassphrase time (via ReEncryptEverything). // This logic covers the case where the nigori update marked new datatypes // for encryption, but didn't change the passphrase. - if (cryptographer->is_ready()) { + if (cryptographer->CanEncrypt()) { // Note that we don't bother to encrypt any data for which IS_UNSYNCED // == false here. The machine that turned on encryption should know about // and re-encrypt all synced data. It's possible it could get interrupted @@ -97,7 +104,7 @@ // Note: we only update the encryption keybag if we're sure that we aren't // invalidating the keystore_decryptor_token (i.e. we're either // not migrated or we copying over all local state). - if (cryptographer->is_ready()) { + if (cryptographer->CanEncrypt()) { if (local_nigori.has_passphrase_type() && server_nigori.has_passphrase_type()) { // They're both migrated, preserve the local nigori if the passphrase
diff --git a/components/sync/engine_impl/apply_control_data_updates_unittest.cc b/components/sync/engine_impl/apply_control_data_updates_unittest.cc index 98e738ad..56d642b 100644 --- a/components/sync/engine_impl/apply_control_data_updates_unittest.cc +++ b/components/sync/engine_impl/apply_control_data_updates_unittest.cc
@@ -53,7 +53,8 @@ void TearDown() override { dir_maker_.TearDown(); } - Cryptographer* GetCryptographer(const syncable::BaseTransaction* trans) { + DirectoryCryptographer* GetCryptographer( + const syncable::BaseTransaction* trans) { return dir_maker_.GetCryptographer(trans); } @@ -75,7 +76,7 @@ TEST_F(ApplyControlDataUpdatesTest, NigoriUpdate) { // Storing the cryptographer separately is bad, but for this test we // know it's safe. - Cryptographer* cryptographer; + DirectoryCryptographer* cryptographer; ModelTypeSet encrypted_types; encrypted_types.PutAll(SyncEncryptionHandler::SensitiveTypes()); @@ -87,7 +88,7 @@ } // Nigori node updates should update the Cryptographer. - Cryptographer other_cryptographer; + DirectoryCryptographer other_cryptographer; KeyParams params = {KeyDerivationParams::CreateForPbkdf2(), "foobar"}; other_cryptographer.AddKey(params); @@ -101,7 +102,7 @@ ApplyNigoriUpdate(directory()); - EXPECT_FALSE(cryptographer->is_ready()); + EXPECT_FALSE(cryptographer->CanEncrypt()); EXPECT_TRUE(cryptographer->has_pending_keys()); { syncable::ReadTransaction trans(FROM_HERE, directory()); @@ -118,7 +119,7 @@ TEST_F(ApplyControlDataUpdatesTest, EncryptUnsyncedChanges) { // Storing the cryptographer separately is bad, but for this test we // know it's safe. - Cryptographer* cryptographer; + DirectoryCryptographer* cryptographer; ModelTypeSet encrypted_types; encrypted_types.PutAll(SyncEncryptionHandler::SensitiveTypes()); { @@ -165,7 +166,7 @@ entry_factory_->CreateUnappliedNewItem(ModelTypeToRootTag(NIGORI), specifics, true); EXPECT_FALSE(cryptographer->has_pending_keys()); - EXPECT_TRUE(cryptographer->is_ready()); + EXPECT_TRUE(cryptographer->CanEncrypt()); { // Ensure we have unsynced nodes that aren't properly encrypted. @@ -180,7 +181,7 @@ ApplyNigoriUpdate(directory()); EXPECT_FALSE(cryptographer->has_pending_keys()); - EXPECT_TRUE(cryptographer->is_ready()); + EXPECT_TRUE(cryptographer->CanEncrypt()); { syncable::ReadTransaction trans(FROM_HERE, directory()); @@ -207,7 +208,7 @@ ApplyNigoriUpdate(directory()); EXPECT_FALSE(cryptographer->has_pending_keys()); - EXPECT_TRUE(cryptographer->is_ready()); + EXPECT_TRUE(cryptographer->CanEncrypt()); { syncable::ReadTransaction trans(FROM_HERE, directory()); @@ -229,7 +230,7 @@ TEST_F(ApplyControlDataUpdatesTest, CannotEncryptUnsyncedChanges) { // Storing the cryptographer separately is bad, but for this test we // know it's safe. - Cryptographer* cryptographer; + DirectoryCryptographer* cryptographer; ModelTypeSet encrypted_types; encrypted_types.PutAll(SyncEncryptionHandler::SensitiveTypes()); { @@ -268,7 +269,7 @@ // We encrypt with new keys, triggering the local cryptographer to be unready // and unable to decrypt data (once updated). - Cryptographer other_cryptographer; + DirectoryCryptographer other_cryptographer; KeyParams params = {KeyDerivationParams::CreateForPbkdf2(), "foobar"}; other_cryptographer.AddKey(params); sync_pb::EntitySpecifics specifics; @@ -291,7 +292,7 @@ ApplyNigoriUpdate(directory()); - EXPECT_FALSE(cryptographer->is_ready()); + EXPECT_FALSE(cryptographer->CanEncrypt()); EXPECT_TRUE(cryptographer->has_pending_keys()); { syncable::ReadTransaction trans(FROM_HERE, directory()); @@ -301,7 +302,7 @@ EXPECT_FALSE(VerifyUnsyncedChangesAreEncrypted(&trans, encrypted_types)); EXPECT_EQ(ModelTypeSet::All(), directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)); - EXPECT_FALSE(cryptographer->is_ready()); + EXPECT_FALSE(cryptographer->CanEncrypt()); EXPECT_TRUE(cryptographer->has_pending_keys()); syncable::Directory::Metahandles handles; @@ -315,7 +316,7 @@ // Initial sync ended should be set. TEST_F(ApplyControlDataUpdatesTest, NigoriConflictPendingKeysServerEncryptEverythingCustom) { - Cryptographer* cryptographer; + DirectoryCryptographer* cryptographer; ModelTypeSet encrypted_types(SyncEncryptionHandler::SensitiveTypes()); KeyParams other_params = {KeyDerivationParams::CreateForPbkdf2(), "foobar"}; KeyParams local_params = {KeyDerivationParams::CreateForPbkdf2(), "local"}; @@ -327,7 +328,7 @@ } // Set up a temporary cryptographer to generate new keys with. - Cryptographer other_cryptographer; + DirectoryCryptographer other_cryptographer; other_cryptographer.AddKey(other_params); // Create server specifics with pending keys, new encrypted types, @@ -342,7 +343,7 @@ // Initialize the local cryptographer with the local keys. cryptographer->AddKey(local_params); - EXPECT_TRUE(cryptographer->is_ready()); + EXPECT_TRUE(cryptographer->CanEncrypt()); // Set up a local nigori with the local encryption keys and default encrypted // types. @@ -367,7 +368,7 @@ EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle)); EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(nigori_handle)); - EXPECT_FALSE(cryptographer->is_ready()); + EXPECT_FALSE(cryptographer->CanEncrypt()); EXPECT_TRUE(cryptographer->is_initialized()); EXPECT_TRUE(cryptographer->has_pending_keys()); EXPECT_TRUE(other_cryptographer.CanDecryptUsingDefaultKey( @@ -392,7 +393,7 @@ // Initial sync ended should be set. TEST_F(ApplyControlDataUpdatesTest, NigoriConflictPendingKeysLocalEncryptEverythingCustom) { - Cryptographer* cryptographer; + DirectoryCryptographer* cryptographer; ModelTypeSet encrypted_types(SyncEncryptionHandler::SensitiveTypes()); KeyParams other_params = {KeyDerivationParams::CreateForPbkdf2(), "foobar"}; KeyParams local_params = {KeyDerivationParams::CreateForPbkdf2(), "local"}; @@ -404,7 +405,7 @@ } // Set up a temporary cryptographer to generate new keys with. - Cryptographer other_cryptographer; + DirectoryCryptographer other_cryptographer; other_cryptographer.AddKey(other_params); // Create server specifics with pending keys, new encrypted types, @@ -419,7 +420,7 @@ // Initialize the local cryptographer with the local keys. cryptographer->AddKey(local_params); - EXPECT_TRUE(cryptographer->is_ready()); + EXPECT_TRUE(cryptographer->CanEncrypt()); // Set up a local nigori with the local encryption keys and default encrypted // types. @@ -444,7 +445,7 @@ EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle)); EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(nigori_handle)); - EXPECT_FALSE(cryptographer->is_ready()); + EXPECT_FALSE(cryptographer->CanEncrypt()); EXPECT_TRUE(cryptographer->is_initialized()); EXPECT_TRUE(cryptographer->has_pending_keys()); EXPECT_TRUE(other_cryptographer.CanDecryptUsingDefaultKey( @@ -468,7 +469,7 @@ // resolution should preserve the full local keys. Initial sync ended should be // set. TEST_F(ApplyControlDataUpdatesTest, NigoriConflictOldKeys) { - Cryptographer* cryptographer; + DirectoryCryptographer* cryptographer; ModelTypeSet encrypted_types(SyncEncryptionHandler::SensitiveTypes()); KeyParams old_params = {KeyDerivationParams::CreateForPbkdf2(), "old"}; KeyParams new_params = {KeyDerivationParams::CreateForPbkdf2(), "new"}; @@ -492,7 +493,7 @@ // Add the new keys to the cryptogrpaher cryptographer->AddKey(new_params); - EXPECT_TRUE(cryptographer->is_ready()); + EXPECT_TRUE(cryptographer->CanEncrypt()); // Set up a local nigori with the superset of keys. sync_pb::EntitySpecifics local_specifics; @@ -515,7 +516,7 @@ EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle)); EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(nigori_handle)); - EXPECT_TRUE(cryptographer->is_ready()); + EXPECT_TRUE(cryptographer->CanEncrypt()); EXPECT_TRUE(cryptographer->CanDecryptUsingDefaultKey( entry_factory_->GetLocalSpecificsForItem(nigori_handle) .nigori() @@ -536,7 +537,7 @@ // If both nigoris are migrated, but we also set a custom passphrase locally, // the local nigori should be preserved. TEST_F(ApplyControlDataUpdatesTest, NigoriConflictBothMigratedLocalCustom) { - Cryptographer* cryptographer; + DirectoryCryptographer* cryptographer; ModelTypeSet encrypted_types(SyncEncryptionHandler::SensitiveTypes()); KeyParams old_params = {KeyDerivationParams::CreateForPbkdf2(), "old"}; KeyParams new_params = {KeyDerivationParams::CreateForPbkdf2(), "new"}; @@ -548,7 +549,7 @@ } // Set up the cryptographer with new keys - Cryptographer other_cryptographer; + DirectoryCryptographer other_cryptographer; other_cryptographer.AddKey(old_params); // Create server specifics with a migrated keystore passphrase type. @@ -566,7 +567,7 @@ // Add the new keys to the cryptographer. cryptographer->AddKey(old_params); cryptographer->AddKey(new_params); - EXPECT_TRUE(cryptographer->is_ready()); + EXPECT_TRUE(cryptographer->CanEncrypt()); // Set up a local nigori with a migrated custom passphrase type sync_pb::EntitySpecifics local_specifics; @@ -592,7 +593,7 @@ EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle)); EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(nigori_handle)); - EXPECT_TRUE(cryptographer->is_ready()); + EXPECT_TRUE(cryptographer->CanEncrypt()); EXPECT_TRUE(cryptographer->CanDecryptUsingDefaultKey( entry_factory_->GetLocalSpecificsForItem(nigori_handle) .nigori() @@ -617,7 +618,7 @@ // If both nigoris are migrated, but a custom passphrase with a new key was // set remotely, the remote nigori should be preserved. TEST_F(ApplyControlDataUpdatesTest, NigoriConflictBothMigratedServerCustom) { - Cryptographer* cryptographer; + DirectoryCryptographer* cryptographer; ModelTypeSet encrypted_types(SyncEncryptionHandler::SensitiveTypes()); KeyParams old_params = {KeyDerivationParams::CreateForPbkdf2(), "old"}; KeyParams new_params = {KeyDerivationParams::CreateForPbkdf2(), "new"}; @@ -629,7 +630,7 @@ } // Set up the cryptographer with both new keys and old keys. - Cryptographer other_cryptographer; + DirectoryCryptographer other_cryptographer; other_cryptographer.AddKey(old_params); other_cryptographer.AddKey(new_params); @@ -646,7 +647,7 @@ // Add the old keys to the cryptographer. cryptographer->AddKey(old_params); - EXPECT_TRUE(cryptographer->is_ready()); + EXPECT_TRUE(cryptographer->CanEncrypt()); // Set up a local nigori with a migrated keystore passphrase type sync_pb::EntitySpecifics local_specifics; @@ -699,7 +700,7 @@ // If the local nigori is migrated but the server is not, preserve the local // nigori. TEST_F(ApplyControlDataUpdatesTest, NigoriConflictLocalMigrated) { - Cryptographer* cryptographer; + DirectoryCryptographer* cryptographer; ModelTypeSet encrypted_types(SyncEncryptionHandler::SensitiveTypes()); KeyParams old_params = {KeyDerivationParams::CreateForPbkdf2(), "old"}; KeyParams new_params = {KeyDerivationParams::CreateForPbkdf2(), "new"}; @@ -711,7 +712,7 @@ } // Set up the cryptographer with both new keys and old keys. - Cryptographer other_cryptographer; + DirectoryCryptographer other_cryptographer; other_cryptographer.AddKey(old_params); // Create server specifics with an unmigrated implicit passphrase type. @@ -726,7 +727,7 @@ // Add the old keys to the cryptographer. cryptographer->AddKey(old_params); cryptographer->AddKey(new_params); - EXPECT_TRUE(cryptographer->is_ready()); + EXPECT_TRUE(cryptographer->CanEncrypt()); // Set up a local nigori with a migrated custom passphrase type sync_pb::EntitySpecifics local_specifics; @@ -752,7 +753,7 @@ EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle)); EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(nigori_handle)); - EXPECT_TRUE(cryptographer->is_ready()); + EXPECT_TRUE(cryptographer->CanEncrypt()); EXPECT_TRUE(cryptographer->CanDecryptUsingDefaultKey( entry_factory_->GetLocalSpecificsForItem(nigori_handle) .nigori() @@ -777,7 +778,7 @@ // If the server nigori is migrated but the local is not, preserve the server // nigori. TEST_F(ApplyControlDataUpdatesTest, NigoriConflictServerMigrated) { - Cryptographer* cryptographer; + DirectoryCryptographer* cryptographer; ModelTypeSet encrypted_types(SyncEncryptionHandler::SensitiveTypes()); KeyParams old_params = {KeyDerivationParams::CreateForPbkdf2(), "old"}; KeyParams new_params = {KeyDerivationParams::CreateForPbkdf2(), "new"}; @@ -789,7 +790,7 @@ } // Set up the cryptographer with both new keys and old keys. - Cryptographer other_cryptographer; + DirectoryCryptographer other_cryptographer; other_cryptographer.AddKey(old_params); // Create server specifics with an migrated keystore passphrase type. @@ -807,7 +808,7 @@ // Add the old keys to the cryptographer. cryptographer->AddKey(old_params); cryptographer->AddKey(new_params); - EXPECT_TRUE(cryptographer->is_ready()); + EXPECT_TRUE(cryptographer->CanEncrypt()); // Set up a local nigori with a migrated custom passphrase type sync_pb::EntitySpecifics local_specifics; @@ -831,7 +832,7 @@ EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle)); EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(nigori_handle)); - EXPECT_TRUE(cryptographer->is_ready()); + EXPECT_TRUE(cryptographer->CanEncrypt()); // Note: we didn't overwrite the encryption keybag with the local keys. The // sync encryption handler will do that when it detects that the new // keybag is out of date (and update the keystore bootstrap if necessary). @@ -860,7 +861,7 @@ TEST_F(ApplyControlDataUpdatesTest, NigoriApplyMarksDownloadCompleted) { EXPECT_FALSE(directory()->InitialSyncEndedForType(NIGORI)); - Cryptographer* cryptographer; + DirectoryCryptographer* cryptographer; { syncable::ReadTransaction trans(FROM_HERE, directory());
diff --git a/components/sync/engine_impl/conflict_resolver.cc b/components/sync/engine_impl/conflict_resolver.cc index f64c178..43b00a8 100644 --- a/components/sync/engine_impl/conflict_resolver.cc +++ b/components/sync/engine_impl/conflict_resolver.cc
@@ -20,11 +20,21 @@ namespace syncer { +namespace { + using syncable::Directory; using syncable::Entry; using syncable::Id; using syncable::MutableEntry; +bool CanDecryptUsingDefaultKey(const Cryptographer& cryptographer, + const sync_pb::EncryptedData& encrypted) { + return !encrypted.key_name().empty() && + encrypted.key_name() == cryptographer.GetDefaultEncryptionKeyName(); +} + +} // namespace + ConflictResolver::ConflictResolver() {} ConflictResolver::~ConflictResolver() {} @@ -112,7 +122,7 @@ bool specifics_match = false; bool server_encrypted_with_default_key = false; if (specifics.has_encrypted()) { - DCHECK(cryptographer->CanDecryptUsingDefaultKey(specifics.encrypted())); + DCHECK(CanDecryptUsingDefaultKey(*cryptographer, specifics.encrypted())); // TODO(crbug.com/908391): what if the decryption below fails? cryptographer->DecryptToString(specifics.encrypted(), &decrypted_specifics); @@ -120,9 +130,8 @@ decrypted_specifics = specifics.SerializeAsString(); } if (server_specifics.has_encrypted()) { - server_encrypted_with_default_key = - cryptographer->CanDecryptUsingDefaultKey( - server_specifics.encrypted()); + server_encrypted_with_default_key = CanDecryptUsingDefaultKey( + *cryptographer, server_specifics.encrypted()); // TODO(crbug.com/908391): what if the decryption below fails? cryptographer->DecryptToString(server_specifics.encrypted(), &decrypted_server_specifics);
diff --git a/components/sync/engine_impl/debug_info_event_listener.cc b/components/sync/engine_impl/debug_info_event_listener.cc index db935e6..7be9e73 100644 --- a/components/sync/engine_impl/debug_info_event_listener.cc +++ b/components/sync/engine_impl/debug_info_event_listener.cc
@@ -102,7 +102,7 @@ Cryptographer* cryptographer) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); cryptographer_has_pending_keys_ = cryptographer->has_pending_keys(); - cryptographer_ready_ = cryptographer->is_ready(); + cryptographer_ready_ = cryptographer->CanEncrypt(); } void DebugInfoEventListener::OnPassphraseTypeChanged(
diff --git a/components/sync/engine_impl/directory_update_handler.cc b/components/sync/engine_impl/directory_update_handler.cc index bd234cd..b470a92 100644 --- a/components/sync/engine_impl/directory_update_handler.cc +++ b/components/sync/engine_impl/directory_update_handler.cc
@@ -16,6 +16,7 @@ #include "components/sync/engine_impl/cycle/status_controller.h" #include "components/sync/engine_impl/update_applicator.h" #include "components/sync/syncable/directory.h" +#include "components/sync/syncable/directory_cryptographer.h" #include "components/sync/syncable/model_neutral_mutable_entry.h" #include "components/sync/syncable/syncable_changes_version.h" #include "components/sync/syncable/syncable_model_neutral_write_transaction.h"
diff --git a/components/sync/engine_impl/directory_update_handler_unittest.cc b/components/sync/engine_impl/directory_update_handler_unittest.cc index 6e5f1f4..0340b0e 100644 --- a/components/sync/engine_impl/directory_update_handler_unittest.cc +++ b/components/sync/engine_impl/directory_update_handler_unittest.cc
@@ -528,7 +528,8 @@ return articles_emitter_.GetUpdateCounters(); } - Cryptographer* GetCryptographer(const syncable::BaseTransaction* trans) { + DirectoryCryptographer* GetCryptographer( + const syncable::BaseTransaction* trans) { return dir_maker_.GetCryptographer(trans); } @@ -947,7 +948,7 @@ // Attempt application of password upates where the passphrase is known. TEST_F(DirectoryUpdateHandlerApplyUpdateTest, DecryptablePassword) { // Decryptable password updates should be applied. - Cryptographer* cryptographer; + DirectoryCryptographer* cryptographer; { // Storing the cryptographer separately is bad, but for this test we // know it's safe. @@ -1031,7 +1032,7 @@ // Test a mix of decryptable and undecryptable updates. TEST_F(DirectoryUpdateHandlerApplyUpdateTest, SomeUndecryptablePassword) { - Cryptographer* cryptographer; + DirectoryCryptographer* cryptographer; int64_t decryptable_handle = -1; int64_t undecryptable_handle = -1; @@ -1056,7 +1057,7 @@ } { // Create a new cryptographer, independent of the one in the cycle. - Cryptographer other_cryptographer; + DirectoryCryptographer other_cryptographer; KeyParams params = {KeyDerivationParams::CreateForPbkdf2(), "bazqux"}; other_cryptographer.AddKey(params);
diff --git a/components/sync/engine_impl/js_sync_encryption_handler_observer.cc b/components/sync/engine_impl/js_sync_encryption_handler_observer.cc index 005f27c3..6c285580 100644 --- a/components/sync/engine_impl/js_sync_encryption_handler_observer.cc +++ b/components/sync/engine_impl/js_sync_encryption_handler_observer.cc
@@ -86,7 +86,7 @@ return; } base::DictionaryValue details; - details.SetBoolean("ready", cryptographer->is_ready()); + details.SetBoolean("canEncrypt", cryptographer->CanEncrypt()); details.SetBoolean("hasPendingKeys", cryptographer->has_pending_keys()); HandleJsEvent(FROM_HERE, "onCryptographerStateChanged", JsEventDetails(&details));
diff --git a/components/sync/engine_impl/js_sync_encryption_handler_observer_unittest.cc b/components/sync/engine_impl/js_sync_encryption_handler_observer_unittest.cc index 9afa1cf..5bf74a2 100644 --- a/components/sync/engine_impl/js_sync_encryption_handler_observer_unittest.cc +++ b/components/sync/engine_impl/js_sync_encryption_handler_observer_unittest.cc
@@ -17,7 +17,7 @@ #include "components/sync/engine/sync_string_conversions.h" #include "components/sync/js/js_event_details.h" #include "components/sync/js/js_test_util.h" -#include "components/sync/nigori/cryptographer.h" +#include "components/sync/syncable/directory_cryptographer.h" #include "testing/gtest/include/gtest/gtest.h" namespace syncer { @@ -136,7 +136,7 @@ base::DictionaryValue expected_details; bool expected_ready = false; bool expected_pending = false; - expected_details.SetBoolean("ready", expected_ready); + expected_details.SetBoolean("canEncrypt", expected_ready); expected_details.SetBoolean("hasPendingKeys", expected_pending); ModelTypeSet encrypted_types; @@ -144,7 +144,7 @@ HandleJsEvent("onCryptographerStateChanged", HasDetailsAsDictionary(expected_details))); - Cryptographer cryptographer; + DirectoryCryptographer cryptographer; js_sync_encryption_handler_observer_.OnCryptographerStateChanged( &cryptographer); PumpLoop();
diff --git a/components/sync/engine_impl/model_type_registry.cc b/components/sync/engine_impl/model_type_registry.cc index 4535273..2946fa1 100644 --- a/components/sync/engine_impl/model_type_registry.cc +++ b/components/sync/engine_impl/model_type_registry.cc
@@ -101,7 +101,7 @@ std::unique_ptr<Cryptographer> cryptographer_copy; if (encrypted_types_.Has(type)) - cryptographer_copy = std::make_unique<Cryptographer>(*cryptographer_); + cryptographer_copy = cryptographer_->Clone(); DataTypeDebugInfoEmitter* emitter = GetEmitter(type); if (emitter == nullptr) { @@ -352,7 +352,7 @@ void ModelTypeRegistry::OnCryptographerStateChanged( Cryptographer* cryptographer) { - cryptographer_ = std::make_unique<Cryptographer>(*cryptographer); + cryptographer_ = cryptographer->Clone(); OnEncryptionStateChanged(); } @@ -369,8 +369,7 @@ void ModelTypeRegistry::OnEncryptionStateChanged() { for (const auto& worker : model_type_workers_) { if (encrypted_types_.Has(worker->GetModelType())) { - worker->UpdateCryptographer( - std::make_unique<Cryptographer>(*cryptographer_)); + worker->UpdateCryptographer(cryptographer_->Clone()); } } }
diff --git a/components/sync/engine_impl/model_type_worker.cc b/components/sync/engine_impl/model_type_worker.cc index deedc58..40cbeef0 100644 --- a/components/sync/engine_impl/model_type_worker.cc +++ b/components/sync/engine_impl/model_type_worker.cc
@@ -125,9 +125,9 @@ // around, and we're not going to receive the normal UpdateCryptographer() or // EncryptionAcceptedApplyUpdates() calls to drive this process. // - // If |cryptographer_->is_ready()| is false, all the rest of this logic can be - // safely skipped, since |UpdateCryptographer(...)| must be called first and - // things should be driven normally after that. + // If |cryptographer_->CanEncrypt()| is false, all the rest of this logic can + // be safely skipped, since |UpdateCryptographer(...)| must be called first + // and things should be driven normally after that. // // If |model_type_state_.initial_sync_done()| is false, |model_type_state_| // may still need to be updated, since UpdateCryptographer() is never going to @@ -135,7 +135,7 @@ // the processor, and we should not push it now. In fact, doing so now would // violate the processor's assumption that the first OnUpdateReceived is will // be changing initial sync done to true. - if (cryptographer_ && cryptographer_->is_ready() && + if (cryptographer_ && cryptographer_->CanEncrypt() && UpdateEncryptionKeyName() && model_type_state_.initial_sync_done()) { ApplyPendingUpdates(); } @@ -387,10 +387,16 @@ // Legacy clients don't populate the guid field in the BookmarkSpecifics, so // we use the originator_client_item_id instead, if it is a valid GUID. // Otherwise, we leave the field empty. - if (model_type == BOOKMARKS && !data->specifics.bookmark().has_guid() && - base::IsValidGUID(update_entity.originator_client_item_id())) { - data->specifics.mutable_bookmark()->set_guid( - update_entity.originator_client_item_id()); + if (model_type == BOOKMARKS) { + if (data->specifics.bookmark().has_guid()) { + LogGUIDSource(BookmarkGUIDSource::kSpecifics); + } else if (base::IsValidGUID(update_entity.originator_client_item_id())) { + data->specifics.mutable_bookmark()->set_guid( + update_entity.originator_client_item_id()); + LogGUIDSource(BookmarkGUIDSource::kValidOCII); + } else { + LogGUIDSource(BookmarkGUIDSource::kLeftEmpty); + } } response_data->entity = std::move(data); response_data->encryption_key_name = specifics.encrypted().key_name(); @@ -423,7 +429,7 @@ void ModelTypeWorker::EncryptionAcceptedMaybeApplyUpdates() { DCHECK(cryptographer_); - DCHECK(cryptographer_->is_ready()); + DCHECK(cryptographer_->CanEncrypt()); // Only push the encryption to the processor if we're already connected. // Otherwise this information can wait for the initial sync's first apply. @@ -566,11 +572,12 @@ return true; // Should be using encryption, but we do not have the keys. - return cryptographer_ && !cryptographer_->is_ready(); + return cryptographer_ && !cryptographer_->CanEncrypt(); } bool ModelTypeWorker::UpdateEncryptionKeyName() { - const std::string& new_key_name = cryptographer_->GetDefaultNigoriKeyName(); + const std::string& new_key_name = + cryptographer_->GetDefaultEncryptionKeyName(); const std::string& old_key_name = model_type_state_.encryption_key_name(); if (old_key_name == new_key_name) { return false;
diff --git a/components/sync/engine_impl/model_type_worker_unittest.cc b/components/sync/engine_impl/model_type_worker_unittest.cc index 61d631dd..654d59e 100644 --- a/components/sync/engine_impl/model_type_worker_unittest.cc +++ b/components/sync/engine_impl/model_type_worker_unittest.cc
@@ -21,6 +21,7 @@ #include "components/sync/engine_impl/commit_contribution.h" #include "components/sync/engine_impl/cycle/non_blocking_type_debug_info_emitter.h" #include "components/sync/engine_impl/cycle/status_controller.h" +#include "components/sync/syncable/directory_cryptographer.h" #include "components/sync/test/engine/mock_model_type_processor.h" #include "components/sync/test/engine/mock_nudge_handler.h" #include "components/sync/test/engine/single_type_mock_server.h" @@ -218,7 +219,7 @@ std::unique_ptr<Cryptographer> cryptographer_copy; if (cryptographer_) { - cryptographer_copy = std::make_unique<Cryptographer>(*cryptographer_); + cryptographer_copy = cryptographer_->Clone(); } worker_ = std::make_unique<ModelTypeWorker>( @@ -229,7 +230,7 @@ void InitializeCryptographer() { if (!cryptographer_) { - cryptographer_ = std::make_unique<Cryptographer>(); + cryptographer_ = std::make_unique<DirectoryCryptographer>(); } } @@ -271,8 +272,7 @@ // Update the worker with the latest cryptographer. if (worker()) { - worker()->UpdateCryptographer( - std::make_unique<Cryptographer>(*cryptographer_)); + worker()->UpdateCryptographer(cryptographer_->Clone()); } } @@ -286,8 +286,7 @@ // Update the worker with the latest cryptographer. if (worker()) { - worker()->UpdateCryptographer( - std::make_unique<Cryptographer>(*cryptographer_)); + worker()->UpdateCryptographer(cryptographer_->Clone()); worker()->EncryptionAcceptedMaybeApplyUpdates(); } } @@ -488,7 +487,7 @@ if (!cryptographer_) { return std::string(); } - return cryptographer_->GetDefaultNigoriKeyName(); + return cryptographer_->GetDefaultEncryptionKeyName(); } MockModelTypeProcessor* processor() { return mock_type_processor_; } @@ -502,7 +501,7 @@ const ModelType model_type_; // The cryptographer itself. Null if we're not encrypting the type. - std::unique_ptr<Cryptographer> cryptographer_; + std::unique_ptr<DirectoryCryptographer> cryptographer_; // The number of the most recent foreign encryption key known to our // cryptographer. Note that not all of these will be decryptable. @@ -1305,7 +1304,6 @@ const SyncEntity entity = server()->GetNthCommitMessage(0).commit().entries(0); - EXPECT_EQ(0, entity.attachment_id_size()); EXPECT_FALSE(entity.has_ctime()); EXPECT_FALSE(entity.has_deleted()); EXPECT_FALSE(entity.has_folder()); @@ -1344,7 +1342,7 @@ *entity.mutable_specifics() = GenerateSpecifics(kTag1, kValue1); UpdateResponseData response_data; - Cryptographer cryptographer; + DirectoryCryptographer cryptographer; base::HistogramTester histogram_tester; EXPECT_EQ(ModelTypeWorker::SUCCESS, @@ -1385,7 +1383,7 @@ // Add default value field for a Bookmark. entity.mutable_specifics()->mutable_bookmark(); - Cryptographer cryptographer; + DirectoryCryptographer cryptographer; UpdateResponseData response_data; EXPECT_EQ(ModelTypeWorker::SUCCESS, @@ -1407,7 +1405,7 @@ *entity.mutable_specifics() = GenerateSpecifics(kTag1, kValue1); UpdateResponseData response_data; - Cryptographer cryptographer; + DirectoryCryptographer cryptographer; base::HistogramTester histogram_tester; EXPECT_EQ(ModelTypeWorker::SUCCESS, @@ -1434,7 +1432,7 @@ *entity.mutable_specifics() = GenerateSpecifics(kTag1, kValue1); UpdateResponseData response_data; - Cryptographer cryptographer; + DirectoryCryptographer cryptographer; base::HistogramTester histogram_tester; EXPECT_EQ(ModelTypeWorker::SUCCESS, @@ -1463,7 +1461,7 @@ *entity.mutable_specifics() = specifics; UpdateResponseData response_data; - Cryptographer cryptographer; + DirectoryCryptographer cryptographer; base::HistogramTester histogram_tester; EXPECT_EQ(ModelTypeWorker::SUCCESS, @@ -1487,7 +1485,7 @@ *entity.mutable_specifics() = GenerateSpecifics(kTag1, kValue1); UpdateResponseData response_data; - Cryptographer cryptographer; + DirectoryCryptographer cryptographer; base::HistogramTester histogram_tester; EXPECT_EQ(ModelTypeWorker::SUCCESS, @@ -1514,7 +1512,7 @@ UniquePosition::InitialPosition(UniquePosition::RandomSuffix()).ToProto(); UpdateResponseData response_data; - Cryptographer cryptographer; + DirectoryCryptographer cryptographer; EXPECT_EQ(ModelTypeWorker::SUCCESS, ModelTypeWorker::PopulateUpdateResponseData( @@ -1538,7 +1536,7 @@ UniquePosition::InitialPosition(UniquePosition::RandomSuffix()).ToProto(); UpdateResponseData response_data; - Cryptographer cryptographer; + DirectoryCryptographer cryptographer; EXPECT_EQ(ModelTypeWorker::SUCCESS, ModelTypeWorker::PopulateUpdateResponseData( @@ -1564,7 +1562,7 @@ UniquePosition::InitialPosition(UniquePosition::RandomSuffix()).ToProto(); UpdateResponseData response_data; - Cryptographer cryptographer; + DirectoryCryptographer cryptographer; EXPECT_EQ(ModelTypeWorker::SUCCESS, ModelTypeWorker::PopulateUpdateResponseData(
diff --git a/components/sync/engine_impl/non_blocking_type_commit_contribution_unittest.cc b/components/sync/engine_impl/non_blocking_type_commit_contribution_unittest.cc index 5066bea..9c6dee7 100644 --- a/components/sync/engine_impl/non_blocking_type_commit_contribution_unittest.cc +++ b/components/sync/engine_impl/non_blocking_type_commit_contribution_unittest.cc
@@ -13,7 +13,7 @@ #include "components/sync/base/hash_util.h" #include "components/sync/base/model_type.h" #include "components/sync/base/unique_position.h" -#include "components/sync/nigori/cryptographer.h" +#include "components/sync/syncable/directory_cryptographer.h" #include "testing/gtest/include/gtest/gtest.h" namespace syncer { @@ -165,7 +165,7 @@ base::ObserverList<TypeDebugInfoObserver>::Unchecked observers; DataTypeDebugInfoEmitter debug_info_emitter(PASSWORDS, &observers); - Cryptographer cryptographer; + DirectoryCryptographer cryptographer; cryptographer.AddKey({KeyDerivationParams::CreateForPbkdf2(), "dummy"}); CommitRequestDataList requests_data; @@ -226,7 +226,7 @@ base::ObserverList<TypeDebugInfoObserver>::Unchecked observers; DataTypeDebugInfoEmitter debug_info_emitter(PASSWORDS, &observers); - Cryptographer cryptographer; + DirectoryCryptographer cryptographer; cryptographer.AddKey({KeyDerivationParams::CreateForPbkdf2(), "dummy"}); CommitRequestDataList requests_data;
diff --git a/components/sync/engine_impl/sync_encryption_handler_impl.cc b/components/sync/engine_impl/sync_encryption_handler_impl.cc index 3e727e5c..bf795d1 100644 --- a/components/sync/engine_impl/sync_encryption_handler_impl.cc +++ b/components/sync/engine_impl/sync_encryption_handler_impl.cc
@@ -302,7 +302,7 @@ bool CanDecryptKeybagWithBase64DecodedKeys( const std::vector<std::string>& keystore_keys, const sync_pb::NigoriSpecifics& specifics) { - Cryptographer cryptographer; + DirectoryCryptographer cryptographer; for (const std::string& keystore_key : keystore_keys) { std::string decoded_key; base::Base64Decode(keystore_key, &decoded_key); @@ -404,7 +404,8 @@ bool has_pending_keys = UnlockVault(trans.GetWrappedTrans()).cryptographer.has_pending_keys(); - bool is_ready = UnlockVault(trans.GetWrappedTrans()).cryptographer.is_ready(); + bool is_ready = + UnlockVault(trans.GetWrappedTrans()).cryptographer.CanEncrypt(); // Log the state of the cryptographer regardless of migration state. UMA_HISTOGRAM_BOOLEAN("Sync.CryptographerReady", is_ready); UMA_HISTOGRAM_BOOLEAN("Sync.CryptographerPendingKeys", has_pending_keys); @@ -472,7 +473,7 @@ // failed to initialize it), we don't want to try and re-encrypt the data. // If we had encrypted types, the DataTypeManager will block, preventing // sync from happening until the the passphrase is provided. - if (UnlockVault(trans.GetWrappedTrans()).cryptographer.is_ready()) + if (UnlockVault(trans.GetWrappedTrans()).cryptographer.CanEncrypt()) ReEncryptEverything(&trans); return true; @@ -495,7 +496,7 @@ return; } - Cryptographer* cryptographer = + DirectoryCryptographer* cryptographer = &UnlockVaultMutable(trans.GetWrappedTrans())->cryptographer; // Once we've migrated to keystore, the only way to set a passphrase for @@ -644,7 +645,7 @@ return; } - Cryptographer* cryptographer = + DirectoryCryptographer* cryptographer = &UnlockVaultMutable(trans.GetWrappedTrans())->cryptographer; if (!cryptographer->has_pending_keys()) { // Note that this *can* happen in a rare situation where data is @@ -684,7 +685,7 @@ // Otherwise, we're in a situation where the pending keys are // encrypted with an old gaia passphrase, while the default is the // current gaia passphrase. In that case, we preserve the default. - Cryptographer temp_cryptographer; + DirectoryCryptographer temp_cryptographer; temp_cryptographer.SetPendingKeys(cryptographer->GetPendingKeys()); if (temp_cryptographer.DecryptPendingKeys(key_params)) { // Check to see if the pending bag of keys contains the current @@ -773,7 +774,7 @@ EnableEncryptEverythingImpl(trans.GetWrappedTrans()); WriteEncryptionStateToNigori( &trans, NigoriMigrationTrigger::kEnableEncryptEverything); - if (UnlockVault(trans.GetWrappedTrans()).cryptographer.is_ready()) + if (UnlockVault(trans.GetWrappedTrans()).cryptographer.CanEncrypt()) ReEncryptEverything(&trans); } @@ -871,7 +872,8 @@ for (size_t i = 0; i < keys.size() - 1; ++i) base::Base64Encode(keys[i], &old_keystore_keys_[i]); - Cryptographer* cryptographer = &UnlockVaultMutable(&trans)->cryptographer; + DirectoryCryptographer* cryptographer = + &UnlockVaultMutable(&trans)->cryptographer; // Update the bootstrap token. If this fails, we persist an empty string, // which will force us to download the keystore keys again on the next @@ -920,6 +922,12 @@ return &UnlockVault(trans).cryptographer; } +const DirectoryCryptographer* +SyncEncryptionHandlerImpl::GetDirectoryCryptographerForNigori( + const syncable::BaseTransaction* const trans) const { + return &UnlockVault(trans).cryptographer; +} + ModelTypeSet SyncEncryptionHandlerImpl::GetEncryptedTypes( const syncable::BaseTransaction* const trans) const { return UnlockVault(trans).encrypted_types; @@ -979,7 +987,8 @@ ApplyNigoriUpdate(nigori_state.nigori_specifics, trans.GetWrappedTrans()); } -Cryptographer* SyncEncryptionHandlerImpl::GetMutableCryptographerForTesting() { +DirectoryCryptographer* +SyncEncryptionHandlerImpl::GetMutableCryptographerForTesting() { return &vault_unsafe_.cryptographer; } @@ -989,7 +998,7 @@ // type. void SyncEncryptionHandlerImpl::ReEncryptEverything(WriteTransaction* trans) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(UnlockVault(trans->GetWrappedTrans()).cryptographer.is_ready()); + DCHECK(UnlockVault(trans->GetWrappedTrans()).cryptographer.CanEncrypt()); for (ModelType type : UnlockVault(trans->GetWrappedTrans()).encrypted_types) { if (type == PASSWORDS || type == WIFI_CONFIGURATIONS || IsControlType(type)) continue; // These types handle encryption differently. @@ -1145,7 +1154,8 @@ } } - Cryptographer* cryptographer = &UnlockVaultMutable(trans)->cryptographer; + DirectoryCryptographer* cryptographer = + &UnlockVaultMutable(trans)->cryptographer; bool nigori_needs_new_keys = false; if (!nigori.encryption_keybag().blob().empty()) { // We only update the default key if this was a new explicit passphrase. @@ -1210,7 +1220,7 @@ observer.OnPassphraseRequired(REASON_DECRYPTION, key_derivation_params, pending_keys); } - } else if (!cryptographer->is_ready()) { + } else if (!cryptographer->CanEncrypt()) { DVLOG(1) << "OnPassphraseRequired sent because cryptographer is not " << "ready"; for (auto& observer : observers_) { @@ -1258,14 +1268,14 @@ return; sync_pb::NigoriSpecifics nigori = nigori_node.GetNigoriSpecifics(); - const Cryptographer& cryptographer = + const DirectoryCryptographer& cryptographer = UnlockVault(trans->GetWrappedTrans()).cryptographer; // Will not do anything if we shouldn't or can't migrate. Otherwise // migrates, writing the full encryption state as it does. if (!AttemptToMigrateNigoriToKeystore(trans, &nigori_node, migration_trigger)) { - if (cryptographer.is_ready() && + if (cryptographer.CanEncrypt() && nigori_overwrite_count_ < kNigoriOverwriteLimit) { // Does not modify the encrypted blob if the unencrypted data already // matches what is about to be written. @@ -1396,7 +1406,7 @@ return; } - Cryptographer* cryptographer = + DirectoryCryptographer* cryptographer = &UnlockVaultMutable(trans->GetWrappedTrans())->cryptographer; if (cryptographer->has_pending_keys()) { // This theoretically shouldn't happen, because the only way to have pending @@ -1468,7 +1478,7 @@ } KeyParams key_params = {key_derivation_params, passphrase}; - Cryptographer* cryptographer = + DirectoryCryptographer* cryptographer = &UnlockVaultMutable(trans->GetWrappedTrans())->cryptographer; if (!cryptographer->has_pending_keys()) { // Note that this *can* happen in a rare situation where data is @@ -1531,7 +1541,7 @@ } } - const Cryptographer& cryptographer = + const DirectoryCryptographer& cryptographer = UnlockVault(trans->GetWrappedTrans()).cryptographer; if (!success) { // If we have not set an explicit method, fall back to PBKDF2 to ensure @@ -1544,7 +1554,7 @@ key_derivation_params = custom_passphrase_key_derivation_params_.value(); } - if (cryptographer.is_ready()) { + if (cryptographer.CanEncrypt()) { LOG(ERROR) << "Attempt to change passphrase failed while cryptographer " << "was ready."; } else if (cryptographer.has_pending_keys()) { @@ -1561,7 +1571,7 @@ return; } DCHECK(success); - DCHECK(cryptographer.is_ready()); + DCHECK(cryptographer.CanEncrypt()); // Will do nothing if we're already properly migrated or unable to migrate // (in otherwords, if GetMigrationReason returns kNoReason). @@ -1649,7 +1659,7 @@ SyncEncryptionHandlerImpl::NigoriMigrationReason SyncEncryptionHandlerImpl::GetMigrationReason( const sync_pb::NigoriSpecifics& nigori, - const Cryptographer& cryptographer, + const DirectoryCryptographer& cryptographer, PassphraseType passphrase_type) const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // Don't migrate if there are pending encryption keys (because data @@ -1689,7 +1699,7 @@ encrypt_everything_) { return NigoriMigrationReason::kEncryptEverythingWithKeystorePassphrase; } - if (cryptographer.is_ready() && + if (cryptographer.CanEncrypt() && !cryptographer.CanDecryptUsingDefaultKey(nigori.encryption_keybag())) { // We need to overwrite the keybag. This might involve overwriting the // keystore decryptor too. @@ -1701,7 +1711,7 @@ // Note that once a key rotation has been performed, we no longer // preserve backwards compatibility, and the keybag will therefore be // encrypted with the current keystore key. - Cryptographer temp_cryptographer; + DirectoryCryptographer temp_cryptographer; KeyParams keystore_params = {KeyDerivationParams::CreateForPbkdf2(), keystore_key_}; temp_cryptographer.AddKey(keystore_params); @@ -1720,7 +1730,7 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); const sync_pb::NigoriSpecifics& old_nigori = nigori_node->GetNigoriSpecifics(); - Cryptographer* cryptographer = + DirectoryCryptographer* cryptographer = &UnlockVaultMutable(trans->GetWrappedTrans())->cryptographer; PassphraseType* passphrase_type = &UnlockVaultMutable(trans->GetWrappedTrans())->passphrase_type; @@ -1786,7 +1796,7 @@ // cryptographer is not initialized), so we can't support backwards // compatibility. Ensure the keystore key is the default key. DVLOG(1) << "Migrating keybag to keystore key."; - bool cryptographer_was_ready = cryptographer->is_ready(); + bool cryptographer_was_ready = cryptographer->CanEncrypt(); if (!cryptographer->AddKey(key_params)) { LOG(ERROR) << "Failed to add keystore key as default key"; UMA_HISTOGRAM_ENUMERATION("Sync.AttemptNigoriMigration", @@ -1794,7 +1804,7 @@ MIGRATION_RESULT_SIZE); return false; } - if (!cryptographer_was_ready && cryptographer->is_ready()) { + if (!cryptographer_was_ready && cryptographer->CanEncrypt()) { for (auto& observer : observers_) { observer.OnPassphraseAccepted(); } @@ -1918,19 +1928,19 @@ } bool SyncEncryptionHandlerImpl::GetKeystoreDecryptor( - const Cryptographer& cryptographer, + const DirectoryCryptographer& cryptographer, const std::string& keystore_key, sync_pb::EncryptedData* encrypted_blob) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!keystore_key.empty()); - DCHECK(cryptographer.is_ready()); + DCHECK(cryptographer.CanEncrypt()); std::string serialized_nigori; serialized_nigori = cryptographer.GetDefaultNigoriKeyData(); if (serialized_nigori.empty()) { LOG(ERROR) << "Failed to get cryptographer bootstrap token."; return false; } - Cryptographer temp_cryptographer; + DirectoryCryptographer temp_cryptographer; KeyParams key_params = {KeyDerivationParams::CreateForPbkdf2(), keystore_key}; if (!temp_cryptographer.AddKey(key_params)) return false; @@ -1942,7 +1952,7 @@ bool SyncEncryptionHandlerImpl::AttemptToInstallKeybag( const sync_pb::EncryptedData& keybag, bool update_default, - Cryptographer* cryptographer) { + DirectoryCryptographer* cryptographer) { if (!cryptographer->CanDecrypt(keybag)) return false; cryptographer->InstallKeys(keybag); @@ -1967,11 +1977,11 @@ bool SyncEncryptionHandlerImpl::DecryptPendingKeysWithKeystoreKey( const sync_pb::EncryptedData& keystore_decryptor_token, - Cryptographer* cryptographer) { + DirectoryCryptographer* cryptographer) { DCHECK(cryptographer->has_pending_keys()); if (keystore_decryptor_token.blob().empty()) return false; - Cryptographer temp_cryptographer; + DirectoryCryptographer temp_cryptographer; // First, go through and all all the old keystore keys to the temporary // cryptographer. @@ -2022,7 +2032,7 @@ DVLOG(1) << "Pending keys based on newest keystore key."; cryptographer->AddNonDefaultKey(keystore_params); } - if (cryptographer->is_ready()) { + if (cryptographer->CanEncrypt()) { std::string bootstrap_token; cryptographer->GetBootstrapToken(*encryptor_, &bootstrap_token); DVLOG(1) << "Keystore decryptor token decrypted pending keys.";
diff --git a/components/sync/engine_impl/sync_encryption_handler_impl.h b/components/sync/engine_impl/sync_encryption_handler_impl.h index 8f9c75c8..9a30acab 100644 --- a/components/sync/engine_impl/sync_encryption_handler_impl.h +++ b/components/sync/engine_impl/sync_encryption_handler_impl.h
@@ -18,8 +18,8 @@ #include "base/sequence_checker.h" #include "base/time/time.h" #include "components/sync/engine/sync_encryption_handler.h" -#include "components/sync/nigori/cryptographer.h" #include "components/sync/nigori/keystore_keys_handler.h" +#include "components/sync/syncable/directory_cryptographer.h" #include "components/sync/syncable/nigori_handler.h" namespace syncer { @@ -82,6 +82,8 @@ // Can be called from any thread. const Cryptographer* GetCryptographer( const syncable::BaseTransaction* const trans) const override; + const DirectoryCryptographer* GetDirectoryCryptographerForNigori( + const syncable::BaseTransaction* const trans) const override; ModelTypeSet GetEncryptedTypes( const syncable::BaseTransaction* const trans) const override; PassphraseType GetPassphraseType( @@ -104,9 +106,9 @@ // Writes the nigori to the Directory and updates the Cryptographer. void RestoreNigori(const SyncEncryptionHandler::NigoriState& nigori_state); - // Returns mutable Cryptographer, used only in tests to manipulate it + // Returns mutable DirectoryCryptographer, used only in tests to manipulate it // directly. - Cryptographer* GetMutableCryptographerForTesting(); + DirectoryCryptographer* GetMutableCryptographerForTesting(); private: friend class SyncEncryptionHandlerImplTest; @@ -147,7 +149,7 @@ ~Vault(); // Sync's cryptographer. Used for encrypting and decrypting sync data. - Cryptographer cryptographer; + DirectoryCryptographer cryptographer; // The set of types that require encryption. ModelTypeSet encrypted_types; // The current state of the passphrase required to decrypt the encryption @@ -301,7 +303,7 @@ // CUSTOM_PASSPHRASE). NigoriMigrationReason GetMigrationReason( const sync_pb::NigoriSpecifics& nigori, - const Cryptographer& cryptographer, + const DirectoryCryptographer& cryptographer, PassphraseType passphrase_type) const; // Tries to perform the actual migration of the |nigori_node| to support @@ -316,7 +318,7 @@ // |encrypted_blob|'s contents didn't already contain the key. // The keystore decryptor token is the serialized current default encryption // key, encrypted with the keystore key. - bool GetKeystoreDecryptor(const Cryptographer& cryptographer, + bool GetKeystoreDecryptor(const DirectoryCryptographer& cryptographer, const std::string& keystore_key, sync_pb::EncryptedData* encrypted_blob); @@ -326,14 +328,14 @@ // Will not update the default key. bool AttemptToInstallKeybag(const sync_pb::EncryptedData& keybag, bool update_default, - Cryptographer* cryptographer); + DirectoryCryptographer* cryptographer); // Helper method for decrypting pending keys with the keystore bootstrap. // If successful, the default will become the key encrypted in the keystore // bootstrap, and will return true. Else will return false. bool DecryptPendingKeysWithKeystoreKey( const sync_pb::EncryptedData& keystore_bootstrap, - Cryptographer* cryptographer); + DirectoryCryptographer* cryptographer); // Helper to enable encrypt everything, notifying observers if necessary. // Will not perform re-encryption.
diff --git a/components/sync/engine_impl/sync_encryption_handler_impl_unittest.cc b/components/sync/engine_impl/sync_encryption_handler_impl_unittest.cc index 7ac4101..2ff865e 100644 --- a/components/sync/engine_impl/sync_encryption_handler_impl_unittest.cc +++ b/components/sync/engine_impl/sync_encryption_handler_impl_unittest.cc
@@ -169,7 +169,7 @@ return encryption_handler_.get(); } SyncEncryptionHandlerObserverMock* observer() { return &observer_; } - Cryptographer* GetCryptographer() { + DirectoryCryptographer* GetCryptographer() { return encryption_handler_->GetMutableCryptographerForTesting(); } @@ -239,14 +239,14 @@ EXPECT_EQ(sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE, nigori.passphrase_type()); EXPECT_FALSE(nigori.has_custom_passphrase_key_derivation_method()); - Cryptographer keystore_cryptographer; + DirectoryCryptographer keystore_cryptographer; KeyParams params = {KeyDerivationParams::CreateForPbkdf2(), kKeystoreKey}; keystore_cryptographer.AddKey(params); EXPECT_TRUE(keystore_cryptographer.CanDecryptUsingDefaultKey( nigori.keystore_decryptor_token())); } - Cryptographer temp_cryptographer; + DirectoryCryptographer temp_cryptographer; if (key_derivation_params.has_value() && passphrase_type == PassphraseType::kCustomPassphrase) { temp_cryptographer.AddKey({key_derivation_params.value(), passphrase}); @@ -267,7 +267,7 @@ const std::string& keystore_key, const base::Optional<std::string>& key_derivation_salt) { DCHECK_NE(passphrase_type, PassphraseType::kImplicitPassphrase); - Cryptographer other_cryptographer; + DirectoryCryptographer other_cryptographer; std::string default_key = default_passphrase; if (default_key.empty()) { @@ -315,7 +315,7 @@ } } - EXPECT_TRUE(other_cryptographer.is_ready()); + EXPECT_TRUE(other_cryptographer.CanEncrypt()); sync_pb::NigoriSpecifics nigori; other_cryptographer.GetKeys(nigori.mutable_encryption_keybag()); @@ -509,11 +509,11 @@ void InitUnmigratedNigori(const std::string& default_passphrase, PassphraseType passphrase_type) { DCHECK_NE(passphrase_type, PassphraseType::kFrozenImplicitPassphrase); - Cryptographer other_cryptographer; + DirectoryCryptographer other_cryptographer; KeyParams default_key = {KeyDerivationParams::CreateForPbkdf2(), default_passphrase}; other_cryptographer.AddKey(default_key); - EXPECT_TRUE(other_cryptographer.is_ready()); + EXPECT_TRUE(other_cryptographer.CanEncrypt()); { WriteTransaction trans(FROM_HERE, user_share()); @@ -761,7 +761,7 @@ KeyParams current_key = {KeyDerivationParams::CreateForPbkdf2(), "cur"}; // Data for testing encryption/decryption. - Cryptographer other_cryptographer; + DirectoryCryptographer other_cryptographer; other_cryptographer.AddKey(old_key); sync_pb::EntitySpecifics other_encrypted_specifics; other_encrypted_specifics.mutable_bookmark()->set_title("title"); @@ -804,7 +804,7 @@ encryption_handler()->ApplyNigoriUpdate(old_nigori, trans.GetWrappedTrans()); } - EXPECT_TRUE(GetCryptographer()->is_ready()); + EXPECT_TRUE(GetCryptographer()->CanEncrypt()); EXPECT_FALSE(GetCryptographer()->has_pending_keys()); // Encryption handler should have posted a task to overwrite the old @@ -904,10 +904,10 @@ TEST_F(SyncEncryptionHandlerImplTest, GetKeystoreDecryptor) { const char kCurKey[] = "cur"; sync_pb::EncryptedData encrypted; - Cryptographer other_cryptographer; + DirectoryCryptographer other_cryptographer; KeyParams cur_key = {KeyDerivationParams::CreateForPbkdf2(), kCurKey}; other_cryptographer.AddKey(cur_key); - EXPECT_TRUE(other_cryptographer.is_ready()); + EXPECT_TRUE(other_cryptographer.CanEncrypt()); EXPECT_TRUE(encryption_handler()->GetKeystoreDecryptor( other_cryptographer, kKeystoreKey, &encrypted)); std::string serialized = encrypted.SerializeAsString(); @@ -932,7 +932,7 @@ WriteTransaction trans(FROM_HERE, user_share()); WriteNode nigori_node(&trans); ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK); - Cryptographer other_cryptographer; + DirectoryCryptographer other_cryptographer; KeyParams other_key = {KeyDerivationParams::CreateForPbkdf2(), kOtherKey}; other_cryptographer.AddKey(other_key); @@ -981,7 +981,7 @@ WriteTransaction trans(FROM_HERE, user_share()); WriteNode nigori_node(&trans); ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK); - Cryptographer other_cryptographer; + DirectoryCryptographer other_cryptographer; KeyParams other_key = {KeyDerivationParams::CreateForPbkdf2(), kOtherKey}; other_cryptographer.AddKey(other_key); @@ -1217,14 +1217,14 @@ TEST_F(SyncEncryptionHandlerImplTest, ReceiveMigratedNigoriKeystorePass) { const char kCurKey[] = "cur"; sync_pb::EncryptedData keystore_decryptor_token; - Cryptographer other_cryptographer; + DirectoryCryptographer other_cryptographer; KeyParams cur_key = {KeyDerivationParams::CreateForPbkdf2(), kCurKey}; other_cryptographer.AddKey(cur_key); - EXPECT_TRUE(other_cryptographer.is_ready()); + EXPECT_TRUE(other_cryptographer.CanEncrypt()); EXPECT_TRUE(encryption_handler()->GetKeystoreDecryptor( other_cryptographer, kKeystoreKey, &keystore_decryptor_token)); EXPECT_FALSE(encryption_handler()->MigratedToKeystore()); - EXPECT_FALSE(GetCryptographer()->is_ready()); + EXPECT_FALSE(GetCryptographer()->CanEncrypt()); { ReadTransaction trans(FROM_HERE, user_share()); EXPECT_NE(encryption_handler()->GetPassphraseType(trans.GetWrappedTrans()), @@ -1260,7 +1260,7 @@ Mock::VerifyAndClearExpectations(observer()); EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); - EXPECT_TRUE(GetCryptographer()->is_ready()); + EXPECT_TRUE(GetCryptographer()->CanEncrypt()); VerifyPassphraseType(PassphraseType::kKeystorePassphrase); EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled()); VerifyMigratedNigoriWithTimestamp(1, PassphraseType::kKeystorePassphrase, @@ -1273,7 +1273,7 @@ EXPECT_TRUE(GetCryptographer()->CanDecryptUsingDefaultKey(current_encrypted)); // Check that the cryptographer can decrypt keystore key based encryption. - Cryptographer keystore_cryptographer; + DirectoryCryptographer keystore_cryptographer; KeyParams keystore_key = {KeyDerivationParams::CreateForPbkdf2(), kKeystoreKey}; keystore_cryptographer.AddKey(keystore_key); @@ -1289,7 +1289,7 @@ TEST_F(SyncEncryptionHandlerImplTest, ReceiveMigratedNigoriFrozenImplicitPass) { const char kCurKey[] = "cur"; sync_pb::EncryptedData encrypted; - Cryptographer other_cryptographer; + DirectoryCryptographer other_cryptographer; KeyParams cur_key = {KeyDerivationParams::CreateForPbkdf2(), kCurKey}; other_cryptographer.AddKey(cur_key); EXPECT_FALSE(encryption_handler()->MigratedToKeystore()); @@ -1334,7 +1334,7 @@ EXPECT_CALL(*observer(), OnPassphraseAccepted()); encryption_handler()->SetDecryptionPassphrase(kCurKey); EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); - EXPECT_TRUE(GetCryptographer()->is_ready()); + EXPECT_TRUE(GetCryptographer()->CanEncrypt()); VerifyMigratedNigoriWithTimestamp( 1, PassphraseType::kFrozenImplicitPassphrase, kCurKey, /*key_derivation_method=*/base::nullopt); @@ -1345,7 +1345,7 @@ EXPECT_TRUE(GetCryptographer()->CanDecryptUsingDefaultKey(current_encrypted)); // Check that the cryptographer can decrypt keystore key based encryption. - Cryptographer keystore_cryptographer; + DirectoryCryptographer keystore_cryptographer; KeyParams keystore_key = {KeyDerivationParams::CreateForPbkdf2(), kKeystoreKey}; keystore_cryptographer.AddKey(keystore_key); @@ -1361,7 +1361,7 @@ TEST_F(SyncEncryptionHandlerImplTest, ReceiveMigratedNigoriCustomPass) { const char kCurKey[] = "cur"; sync_pb::EncryptedData encrypted; - Cryptographer other_cryptographer; + DirectoryCryptographer other_cryptographer; KeyParams cur_key = {KeyDerivationParams::CreateForPbkdf2(), kCurKey}; other_cryptographer.AddKey(cur_key); EXPECT_FALSE(encryption_handler()->MigratedToKeystore()); @@ -1405,7 +1405,7 @@ EXPECT_CALL(*observer(), OnPassphraseAccepted()); encryption_handler()->SetDecryptionPassphrase(kCurKey); EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); - EXPECT_TRUE(GetCryptographer()->is_ready()); + EXPECT_TRUE(GetCryptographer()->CanEncrypt()); VerifyMigratedNigoriWithTimestamp(1, PassphraseType::kCustomPassphrase, kCurKey, {KeyDerivationParams::CreateForPbkdf2()}); @@ -1416,7 +1416,7 @@ EXPECT_TRUE(GetCryptographer()->CanDecryptUsingDefaultKey(current_encrypted)); // Check that the cryptographer can decrypt keystore key based encryption. - Cryptographer keystore_cryptographer; + DirectoryCryptographer keystore_cryptographer; KeyParams keystore_key = {KeyDerivationParams::CreateForPbkdf2(), kKeystoreKey}; keystore_cryptographer.AddKey(keystore_key); @@ -1459,7 +1459,7 @@ EXPECT_CALL(*observer(), OnEncryptionComplete()); encryption_handler()->Init(); EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); - EXPECT_TRUE(GetCryptographer()->is_ready()); + EXPECT_TRUE(GetCryptographer()->CanEncrypt()); VerifyPassphraseType(PassphraseType::kCustomPassphrase); EXPECT_TRUE(encryption_handler()->IsEncryptEverythingEnabled()); VerifyMigratedNigoriWithTimestamp(migration_time, @@ -1480,7 +1480,7 @@ .WillOnce(testing::SaveArg<0>(&captured_nigori_state)); EXPECT_CALL(*observer(), OnEncryptionComplete()); { - Cryptographer other_cryptographer; + DirectoryCryptographer other_cryptographer; other_cryptographer.AddKey(old_key); WriteTransaction trans(FROM_HERE, user_share()); WriteNode nigori_node(&trans); @@ -1496,7 +1496,7 @@ // Verify we're still migrated and have proper encryption state. EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); - EXPECT_TRUE(GetCryptographer()->is_ready()); + EXPECT_TRUE(GetCryptographer()->CanEncrypt()); VerifyPassphraseType(PassphraseType::kCustomPassphrase); EXPECT_TRUE(encryption_handler()->IsEncryptEverythingEnabled()); VerifyMigratedNigoriWithTimestamp(1, PassphraseType::kCustomPassphrase, @@ -1548,7 +1548,7 @@ EXPECT_CALL(*observer(), OnEncryptionComplete()); encryption_handler()->Init(); EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); - EXPECT_TRUE(GetCryptographer()->is_ready()); + EXPECT_TRUE(GetCryptographer()->CanEncrypt()); VerifyPassphraseType(PassphraseType::kCustomPassphrase); EXPECT_TRUE(encryption_handler()->IsEncryptEverythingEnabled()); VerifyMigratedNigoriWithTimestamp(1, PassphraseType::kCustomPassphrase, @@ -1574,7 +1574,7 @@ WriteNode nigori_node(&trans); ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK); sync_pb::NigoriSpecifics nigori; - Cryptographer other_cryptographer; + DirectoryCryptographer other_cryptographer; other_cryptographer.AddKey(old_key); encryption_handler()->GetKeystoreDecryptor( other_cryptographer, kKeystoreKey, @@ -1591,7 +1591,7 @@ // Verify we're still migrated and have proper encryption state. EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); - EXPECT_TRUE(GetCryptographer()->is_ready()); + EXPECT_TRUE(GetCryptographer()->CanEncrypt()); VerifyPassphraseType(PassphraseType::kCustomPassphrase); EXPECT_TRUE(encryption_handler()->IsEncryptEverythingEnabled()); VerifyMigratedNigoriWithTimestamp(migration_time, @@ -1615,14 +1615,14 @@ TEST_F(SyncEncryptionHandlerImplTest, SetKeystoreAfterReceivingMigratedNigori) { const char kCurKey[] = "cur"; sync_pb::EncryptedData keystore_decryptor_token; - Cryptographer other_cryptographer; + DirectoryCryptographer other_cryptographer; KeyParams cur_key = {KeyDerivationParams::CreateForPbkdf2(), kCurKey}; other_cryptographer.AddKey(cur_key); - EXPECT_TRUE(other_cryptographer.is_ready()); + EXPECT_TRUE(other_cryptographer.CanEncrypt()); EXPECT_TRUE(encryption_handler()->GetKeystoreDecryptor( other_cryptographer, kKeystoreKey, &keystore_decryptor_token)); EXPECT_FALSE(encryption_handler()->MigratedToKeystore()); - EXPECT_FALSE(GetCryptographer()->is_ready()); + EXPECT_FALSE(GetCryptographer()->CanEncrypt()); { ReadTransaction trans(FROM_HERE, user_share()); EXPECT_NE(encryption_handler()->GetPassphraseType(trans.GetWrappedTrans()), @@ -1668,7 +1668,7 @@ PumpLoop(); EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); - EXPECT_TRUE(GetCryptographer()->is_ready()); + EXPECT_TRUE(GetCryptographer()->CanEncrypt()); VerifyPassphraseType(PassphraseType::kKeystorePassphrase); EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled()); VerifyMigratedNigoriWithTimestamp(1, PassphraseType::kKeystorePassphrase, @@ -1681,7 +1681,7 @@ EXPECT_TRUE(GetCryptographer()->CanDecryptUsingDefaultKey(current_encrypted)); // Check that the cryptographer can decrypt keystore key based encryption. - Cryptographer keystore_cryptographer; + DirectoryCryptographer keystore_cryptographer; KeyParams keystore_key = {KeyDerivationParams::CreateForPbkdf2(), kKeystoreKey}; keystore_cryptographer.AddKey(keystore_key); @@ -1696,10 +1696,10 @@ TEST_F(SyncEncryptionHandlerImplTest, SetCustomPassAfterMigration) { const char kOldKey[] = "old"; sync_pb::EncryptedData keystore_decryptor_token; - Cryptographer other_cryptographer; + DirectoryCryptographer other_cryptographer; KeyParams cur_key = {KeyDerivationParams::CreateForPbkdf2(), kOldKey}; other_cryptographer.AddKey(cur_key); - EXPECT_TRUE(other_cryptographer.is_ready()); + EXPECT_TRUE(other_cryptographer.CanEncrypt()); EXPECT_TRUE(encryption_handler()->GetKeystoreDecryptor( other_cryptographer, kKeystoreKey, &keystore_decryptor_token)); @@ -1734,7 +1734,7 @@ EXPECT_CALL(*observer(), OnEncryptionComplete()); encryption_handler()->Init(); EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); - EXPECT_TRUE(GetCryptographer()->is_ready()); + EXPECT_TRUE(GetCryptographer()->CanEncrypt()); VerifyPassphraseType(PassphraseType::kKeystorePassphrase); EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled()); Mock::VerifyAndClearExpectations(observer()); @@ -1758,7 +1758,7 @@ EXPECT_FALSE(captured_bootstrap_token.empty()); EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); - EXPECT_TRUE(GetCryptographer()->is_ready()); + EXPECT_TRUE(GetCryptographer()->CanEncrypt()); VerifyPassphraseType(PassphraseType::kCustomPassphrase); EXPECT_TRUE(encryption_handler()->IsEncryptEverythingEnabled()); EXPECT_FALSE(encryption_handler()->custom_passphrase_time().is_null()); @@ -1772,7 +1772,7 @@ EXPECT_TRUE(GetCryptographer()->CanDecrypt(old_encrypted)); // Check that the cryptographer can decrypt keystore key based encryption. - Cryptographer keystore_cryptographer; + DirectoryCryptographer keystore_cryptographer; KeyParams keystore_key = {KeyDerivationParams::CreateForPbkdf2(), kKeystoreKey}; keystore_cryptographer.AddKey(keystore_key); @@ -1783,7 +1783,7 @@ // Check that the cryptographer is encrypting with the new key. KeyParams new_key = {KeyDerivationParams::CreateForScrypt(kScryptSalt), kNewKey}; - Cryptographer new_cryptographer; + DirectoryCryptographer new_cryptographer; new_cryptographer.AddKey(new_key); sync_pb::EncryptedData new_encrypted; new_cryptographer.EncryptString("string", &new_encrypted); @@ -1805,13 +1805,13 @@ SetCustomPassAfterMigrationNoKeystoreKey) { const char kOldKey[] = "old"; sync_pb::EncryptedData keystore_decryptor_token; - Cryptographer other_cryptographer; + DirectoryCryptographer other_cryptographer; KeyParams cur_key = {KeyDerivationParams::CreateForPbkdf2(), kOldKey}; other_cryptographer.AddKey(cur_key); KeyParams keystore_key = {KeyDerivationParams::CreateForPbkdf2(), kKeystoreKey}; other_cryptographer.AddNonDefaultKey(keystore_key); - EXPECT_TRUE(other_cryptographer.is_ready()); + EXPECT_TRUE(other_cryptographer.CanEncrypt()); EXPECT_TRUE(encryption_handler()->GetKeystoreDecryptor( other_cryptographer, kKeystoreKey, &keystore_decryptor_token)); @@ -1851,7 +1851,7 @@ OnBootstrapTokenUpdated(_, PASSPHRASE_BOOTSTRAP_TOKEN)); EXPECT_CALL(*observer(), OnEncryptionComplete()); encryption_handler()->SetDecryptionPassphrase(kOldKey); - EXPECT_TRUE(GetCryptographer()->is_ready()); + EXPECT_TRUE(GetCryptographer()->CanEncrypt()); EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled()); Mock::VerifyAndClearExpectations(observer()); @@ -1871,7 +1871,7 @@ EXPECT_CALL(*observer(), OnEncryptionComplete()).Times(2); encryption_handler()->SetEncryptionPassphrase(kNewKey); EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); - EXPECT_TRUE(GetCryptographer()->is_ready()); + EXPECT_TRUE(GetCryptographer()->CanEncrypt()); VerifyPassphraseType(PassphraseType::kCustomPassphrase); EXPECT_TRUE(encryption_handler()->IsEncryptEverythingEnabled()); EXPECT_FALSE(encryption_handler()->custom_passphrase_time().is_null()); @@ -1886,7 +1886,7 @@ // Check that the cryptographer can still decrypt keystore key based // encryption (should have been extracted from the encryption keybag). - Cryptographer keystore_cryptographer; + DirectoryCryptographer keystore_cryptographer; keystore_cryptographer.AddKey(keystore_key); sync_pb::EncryptedData keystore_encrypted; keystore_cryptographer.EncryptString("string", &keystore_encrypted); @@ -1895,7 +1895,7 @@ // Check that the cryptographer is encrypting with the new key. KeyParams new_key = {KeyDerivationParams::CreateForScrypt(kScryptSalt), kNewKey}; - Cryptographer new_cryptographer; + DirectoryCryptographer new_cryptographer; new_cryptographer.AddKey(new_key); sync_pb::EncryptedData new_encrypted; new_cryptographer.EncryptString("string", &new_encrypted); @@ -1917,13 +1917,13 @@ MigrateOnEncryptEverythingKeystorePassphrase) { const char kCurKey[] = "cur"; sync_pb::EncryptedData keystore_decryptor_token; - Cryptographer other_cryptographer; + DirectoryCryptographer other_cryptographer; KeyParams cur_key = {KeyDerivationParams::CreateForPbkdf2(), kCurKey}; other_cryptographer.AddKey(cur_key); KeyParams keystore_key = {KeyDerivationParams::CreateForPbkdf2(), kKeystoreKey}; other_cryptographer.AddNonDefaultKey(keystore_key); - EXPECT_TRUE(other_cryptographer.is_ready()); + EXPECT_TRUE(other_cryptographer.CanEncrypt()); EXPECT_TRUE(encryption_handler()->GetKeystoreDecryptor( other_cryptographer, kKeystoreKey, &keystore_decryptor_token)); @@ -1978,7 +1978,7 @@ Mock::VerifyAndClearExpectations(observer()); EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); - EXPECT_TRUE(GetCryptographer()->is_ready()); + EXPECT_TRUE(GetCryptographer()->CanEncrypt()); VerifyPassphraseType(PassphraseType::kFrozenImplicitPassphrase); EXPECT_TRUE(encryption_handler()->IsEncryptEverythingEnabled()); VerifyMigratedNigoriWithTimestamp( @@ -1992,7 +1992,7 @@ // Check that the cryptographer can still decrypt keystore key based // encryption (due to extracting the keystore key from the encryption keybag). - Cryptographer keystore_cryptographer; + DirectoryCryptographer keystore_cryptographer; keystore_cryptographer.AddKey(keystore_key); sync_pb::EncryptedData keystore_encrypted; keystore_cryptographer.EncryptString("string", &keystore_encrypted); @@ -2016,15 +2016,15 @@ GetCryptographer()->AddKey(old_key); GetCryptographer()->AddKey(cur_key); - Cryptographer other_cryptographer; + DirectoryCryptographer other_cryptographer; other_cryptographer.AddKey(old_key); - EXPECT_TRUE(other_cryptographer.is_ready()); + EXPECT_TRUE(other_cryptographer.CanEncrypt()); EXPECT_CALL(*observer(), OnCryptographerStateChanged(_)).Times(AnyNumber()); EXPECT_CALL(*observer(), OnEncryptedTypesChanged(_, false)); EXPECT_CALL(*observer(), OnEncryptionComplete()); encryption_handler()->Init(); - EXPECT_TRUE(GetCryptographer()->is_ready()); + EXPECT_TRUE(GetCryptographer()->CanEncrypt()); EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled()); EXPECT_CALL(*observer(), @@ -2048,7 +2048,7 @@ WriteNode nigori_node(&trans); ASSERT_EQ(nigori_node.InitTypeRoot(NIGORI), BaseNode::INIT_OK); sync_pb::NigoriSpecifics nigori; - Cryptographer other_cryptographer; + DirectoryCryptographer other_cryptographer; other_cryptographer.AddKey(old_key); encryption_handler()->GetKeystoreDecryptor( other_cryptographer, kKeystoreKey, @@ -2065,7 +2065,7 @@ // Verify we're still migrated and have proper encryption state. EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); - EXPECT_TRUE(GetCryptographer()->is_ready()); + EXPECT_TRUE(GetCryptographer()->CanEncrypt()); VerifyPassphraseType(PassphraseType::kKeystorePassphrase); EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled()); VerifyMigratedNigori(PassphraseType::kKeystorePassphrase, kCurKey, @@ -2099,7 +2099,7 @@ // have rotated the keybag so that it's now encrypted with the newest keystore // key (instead of the old gaia key). EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); - EXPECT_TRUE(GetCryptographer()->is_ready()); + EXPECT_TRUE(GetCryptographer()->CanEncrypt()); VerifyPassphraseType(PassphraseType::kKeystorePassphrase); EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled()); VerifyMigratedNigori(PassphraseType::kKeystorePassphrase, kKeystoreKey, @@ -2134,7 +2134,7 @@ // have rotated the keybag so that it's now encrypted with the newest keystore // key (instead of the old gaia key). EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); - EXPECT_TRUE(GetCryptographer()->is_ready()); + EXPECT_TRUE(GetCryptographer()->CanEncrypt()); VerifyPassphraseType(PassphraseType::kKeystorePassphrase); EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled()); VerifyMigratedNigori(PassphraseType::kKeystorePassphrase, kKeystoreKey, @@ -2196,7 +2196,7 @@ // have rotated the keybag so that it's now encrypted with the newest keystore // key (instead of the old gaia key). EXPECT_TRUE(encryption_handler()->MigratedToKeystore()); - EXPECT_TRUE(GetCryptographer()->is_ready()); + EXPECT_TRUE(GetCryptographer()->CanEncrypt()); VerifyPassphraseType(PassphraseType::kKeystorePassphrase); EXPECT_FALSE(encryption_handler()->IsEncryptEverythingEnabled()); VerifyMigratedNigori(PassphraseType::kKeystorePassphrase, kKeystoreKey, @@ -2610,7 +2610,7 @@ EXPECT_EQ(GetSerializedNigoriKeyForCustomPassphrase( KeyDerivationParams::CreateForPbkdf2(), kCustomPassphrase), GetCryptographer()->GetDefaultNigoriKeyData()); - EXPECT_TRUE(GetCryptographer()->is_ready()); + EXPECT_TRUE(GetCryptographer()->CanEncrypt()); } TEST_F(SyncEncryptionHandlerImplTest, @@ -2626,7 +2626,7 @@ EXPECT_EQ(GetSerializedNigoriKeyForCustomPassphrase( KeyDerivationParams::CreateForPbkdf2(), kCustomPassphrase), GetCryptographer()->GetDefaultNigoriKeyData()); - EXPECT_TRUE(GetCryptographer()->is_ready()); + EXPECT_TRUE(GetCryptographer()->CanEncrypt()); } // If we receive data encrypted using a key derivation method that we don't know @@ -2668,7 +2668,7 @@ GetSerializedNigoriKeyForCustomPassphrase( KeyDerivationParams::CreateForScrypt(kScryptSalt), kCustomPassphrase), GetCryptographer()->GetDefaultNigoriKeyData()); - EXPECT_TRUE(GetCryptographer()->is_ready()); + EXPECT_TRUE(GetCryptographer()->CanEncrypt()); } // If scrypt support is explicitly disabled, we should treat it exactly as an @@ -2689,7 +2689,7 @@ _, KeyDerivationParams::CreateWithUnsupportedMethod(), _)); encryption_handler()->SetDecryptionPassphrase(kCustomPassphrase); - EXPECT_FALSE(GetCryptographer()->is_ready()); + EXPECT_FALSE(GetCryptographer()->CanEncrypt()); } TEST_F(SyncEncryptionHandlerImplTest,
diff --git a/components/sync/engine_impl/sync_manager_impl.cc b/components/sync/engine_impl/sync_manager_impl.cc index b173d2e..be4da4d 100644 --- a/components/sync/engine_impl/sync_manager_impl.cc +++ b/components/sync/engine_impl/sync_manager_impl.cc
@@ -448,7 +448,7 @@ void SyncManagerImpl::OnCryptographerStateChanged( Cryptographer* cryptographer) { - allstatus_.SetCryptographerReady(cryptographer->is_ready()); + allstatus_.SetCryptographerReady(cryptographer->CanEncrypt()); allstatus_.SetCryptoHasPendingKeys(cryptographer->has_pending_keys()); allstatus_.SetKeystoreMigrationTime( sync_encryption_handler_->GetKeystoreMigrationTime());
diff --git a/components/sync/engine_impl/sync_manager_impl_unittest.cc b/components/sync/engine_impl/sync_manager_impl_unittest.cc index 4e7efe4e..49b8ec3 100644 --- a/components/sync/engine_impl/sync_manager_impl_unittest.cc +++ b/components/sync/engine_impl/sync_manager_impl_unittest.cc
@@ -250,7 +250,7 @@ syncable::Directory* dir(); SyncEncryptionHandler* encryption_handler(); PassphraseType GetPassphraseType(BaseTransaction* trans); - Cryptographer* GetCryptographer(BaseTransaction* trans); + DirectoryCryptographer* GetCryptographer(BaseTransaction* trans); private: base::test::SingleThreadTaskEnvironment task_environment_; @@ -273,7 +273,7 @@ return dir()->GetNigoriHandler()->GetPassphraseType(trans->GetWrappedTrans()); } -Cryptographer* SyncApiTest::GetCryptographer(BaseTransaction* trans) { +DirectoryCryptographer* SyncApiTest::GetCryptographer(BaseTransaction* trans) { return test_user_share_.GetCryptographer(trans->GetWrappedTrans()); } @@ -1044,7 +1044,7 @@ sync_manager_.GetEncryptionHandler()->EnableEncryptEverything(); WriteTransaction trans(FROM_HERE, share); - Cryptographer* cryptographer = GetCryptographer(&trans); + DirectoryCryptographer* cryptographer = GetCryptographer(&trans); if (!cryptographer) return false; if (encryption_status != UNINITIALIZED) { @@ -1062,7 +1062,7 @@ EXPECT_EQ(BaseNode::INIT_OK, node.InitByIdLookup(nigori_id)); node.SetNigoriSpecifics(nigori); } - return cryptographer->is_ready(); + return cryptographer->CanEncrypt(); } int64_t GetIdForDataType(ModelType type) { @@ -1164,7 +1164,7 @@ return mock_unrecoverable_error_handler_.invocation_count() > 0; } - Cryptographer* GetCryptographer(const BaseTransaction* trans) { + DirectoryCryptographer* GetCryptographer(const BaseTransaction* trans) { DCHECK_EQ(user_share_.directory.get(), trans->GetDirectory()); return encryption_handler_->GetMutableCryptographerForTesting(); } @@ -1214,7 +1214,7 @@ sync_pb::NigoriSpecifics nigori = node.GetNigoriSpecifics(); EXPECT_TRUE(nigori.has_encryption_keybag()); Cryptographer* cryptographer = GetCryptographer(&trans); - EXPECT_TRUE(cryptographer->is_ready()); + EXPECT_TRUE(cryptographer->CanEncrypt()); EXPECT_TRUE(cryptographer->CanDecrypt(nigori.encryption_keybag())); } } @@ -1258,7 +1258,7 @@ sync_pb::NigoriSpecifics nigori = node.GetNigoriSpecifics(); EXPECT_TRUE(nigori.has_encryption_keybag()); Cryptographer* cryptographer = GetCryptographer(&trans); - EXPECT_TRUE(cryptographer->is_ready()); + EXPECT_TRUE(cryptographer->CanEncrypt()); EXPECT_TRUE(cryptographer->CanDecrypt(nigori.encryption_keybag())); } } @@ -1357,12 +1357,12 @@ // and re-encrypt everything. // (case 2 in SyncManager::SyncInternal::SetEncryptionPassphrase) TEST_F(SyncManagerTest, SetPassphraseWithPassword) { - Cryptographer verifier; + DirectoryCryptographer verifier; EXPECT_TRUE(SetUpEncryption(WRITE_TO_NIGORI, DEFAULT_ENCRYPTION)); { WriteTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); // Store the default (soon to be old) key. - Cryptographer* cryptographer = GetCryptographer(&trans); + DirectoryCryptographer* cryptographer = GetCryptographer(&trans); std::string bootstrap_token; cryptographer->GetBootstrapToken(encryptor_, &bootstrap_token); verifier.Bootstrap(encryptor_, bootstrap_token); @@ -1385,8 +1385,8 @@ EXPECT_FALSE(IsEncryptEverythingEnabledForTest()); { ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); - Cryptographer* cryptographer = GetCryptographer(&trans); - EXPECT_TRUE(cryptographer->is_ready()); + DirectoryCryptographer* cryptographer = GetCryptographer(&trans); + EXPECT_TRUE(cryptographer->CanEncrypt()); // Verify the default key has changed. sync_pb::EncryptedData encrypted; cryptographer->GetKeys(&encrypted); @@ -1407,10 +1407,10 @@ // (case 7 in SyncManager::SyncInternal::SetDecryptionPassphrase) TEST_F(SyncManagerTest, SupplyPendingGAIAPass) { EXPECT_TRUE(SetUpEncryption(WRITE_TO_NIGORI, DEFAULT_ENCRYPTION)); - Cryptographer other_cryptographer; + DirectoryCryptographer other_cryptographer; { WriteTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); - Cryptographer* cryptographer = GetCryptographer(&trans); + DirectoryCryptographer* cryptographer = GetCryptographer(&trans); std::string bootstrap_token; cryptographer->GetBootstrapToken(encryptor_, &bootstrap_token); other_cryptographer.Bootstrap(encryptor_, bootstrap_token); @@ -1435,8 +1435,8 @@ EXPECT_FALSE(IsEncryptEverythingEnabledForTest()); { ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); - Cryptographer* cryptographer = GetCryptographer(&trans); - EXPECT_TRUE(cryptographer->is_ready()); + DirectoryCryptographer* cryptographer = GetCryptographer(&trans); + EXPECT_TRUE(cryptographer->CanEncrypt()); // Verify we're encrypting with the new key. sync_pb::EncryptedData encrypted; cryptographer->GetKeys(&encrypted); @@ -1450,10 +1450,10 @@ // (case 9 in SyncManager::SyncInternal::SetDecryptionPassphrase) TEST_F(SyncManagerTest, SupplyPendingExplicitPass) { EXPECT_TRUE(SetUpEncryption(WRITE_TO_NIGORI, DEFAULT_ENCRYPTION)); - Cryptographer other_cryptographer; + DirectoryCryptographer other_cryptographer; { WriteTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); - Cryptographer* cryptographer = GetCryptographer(&trans); + DirectoryCryptographer* cryptographer = GetCryptographer(&trans); std::string bootstrap_token; cryptographer->GetBootstrapToken(encryptor_, &bootstrap_token); other_cryptographer.Bootstrap(encryptor_, bootstrap_token); @@ -1485,8 +1485,8 @@ EXPECT_FALSE(IsEncryptEverythingEnabledForTest()); { ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); - Cryptographer* cryptographer = GetCryptographer(&trans); - EXPECT_TRUE(cryptographer->is_ready()); + DirectoryCryptographer* cryptographer = GetCryptographer(&trans); + EXPECT_TRUE(cryptographer->CanEncrypt()); // Verify we're encrypting with the new key. sync_pb::EncryptedData encrypted; cryptographer->GetKeys(&encrypted); @@ -1699,8 +1699,8 @@ const sync_pb::EntitySpecifics& specifics = node_entry->GetSpecifics(); EXPECT_TRUE(specifics.has_encrypted()); EXPECT_EQ(kEncryptedString, node_entry->GetNonUniqueName()); - Cryptographer* cryptographer = GetCryptographer(&trans); - EXPECT_TRUE(cryptographer->is_ready()); + DirectoryCryptographer* cryptographer = GetCryptographer(&trans); + EXPECT_TRUE(cryptographer->CanEncrypt()); EXPECT_TRUE( cryptographer->CanDecryptUsingDefaultKey(specifics.encrypted())); } @@ -1721,8 +1721,8 @@ const sync_pb::EntitySpecifics& specifics = node_entry->GetSpecifics(); EXPECT_TRUE(specifics.has_encrypted()); EXPECT_EQ(kEncryptedString, node_entry->GetNonUniqueName()); - Cryptographer* cryptographer = GetCryptographer(&trans); - EXPECT_TRUE(cryptographer->is_ready()); + DirectoryCryptographer* cryptographer = GetCryptographer(&trans); + EXPECT_TRUE(cryptographer->CanEncrypt()); EXPECT_TRUE( cryptographer->CanDecryptUsingDefaultKey(specifics.encrypted())); } @@ -1746,7 +1746,7 @@ const sync_pb::EntitySpecifics& specifics = node_entry->GetSpecifics(); EXPECT_TRUE(specifics.has_encrypted()); EXPECT_EQ(kEncryptedString, node_entry->GetNonUniqueName()); - Cryptographer* cryptographer = GetCryptographer(&trans); + DirectoryCryptographer* cryptographer = GetCryptographer(&trans); EXPECT_TRUE( cryptographer->CanDecryptUsingDefaultKey(specifics.encrypted())); } @@ -1764,7 +1764,7 @@ EXPECT_TRUE(specifics.has_encrypted()); EXPECT_FALSE(node_entry->GetIsUnsynced()); EXPECT_EQ(kEncryptedString, node_entry->GetNonUniqueName()); - Cryptographer* cryptographer = GetCryptographer(&trans); + DirectoryCryptographer* cryptographer = GetCryptographer(&trans); EXPECT_TRUE( cryptographer->CanDecryptUsingDefaultKey(specifics.encrypted())); } @@ -1784,7 +1784,7 @@ EXPECT_TRUE(specifics.has_encrypted()); EXPECT_TRUE(node_entry->GetIsUnsynced()); EXPECT_EQ(kEncryptedString, node_entry->GetNonUniqueName()); - Cryptographer* cryptographer = GetCryptographer(&trans); + DirectoryCryptographer* cryptographer = GetCryptographer(&trans); EXPECT_TRUE( cryptographer->CanDecryptUsingDefaultKey(specifics.encrypted())); } @@ -1798,7 +1798,7 @@ sync_pb::EntitySpecifics entity_specifics; { ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); - Cryptographer* cryptographer = GetCryptographer(&trans); + DirectoryCryptographer* cryptographer = GetCryptographer(&trans); sync_pb::PasswordSpecificsData data; data.set_password_value("secret"); cryptographer->Encrypt( @@ -1829,7 +1829,7 @@ sync_pb::EntitySpecifics entity_specifics; { ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); - Cryptographer* cryptographer = GetCryptographer(&trans); + DirectoryCryptographer* cryptographer = GetCryptographer(&trans); sync_pb::PasswordSpecificsData data; data.set_password_value("secret"); cryptographer->Encrypt( @@ -1857,7 +1857,7 @@ WriteNode node(&trans); EXPECT_EQ(BaseNode::INIT_OK, node.InitByClientTagLookup(PASSWORDS, client_tag)); - Cryptographer* cryptographer = GetCryptographer(&trans); + DirectoryCryptographer* cryptographer = GetCryptographer(&trans); sync_pb::PasswordSpecificsData data; data.set_password_value("secret2"); cryptographer->Encrypt( @@ -1875,7 +1875,7 @@ sync_pb::EntitySpecifics entity_specifics; { ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); - Cryptographer* cryptographer = GetCryptographer(&trans); + DirectoryCryptographer* cryptographer = GetCryptographer(&trans); sync_pb::PasswordSpecificsData data; data.set_password_value(kPasswordValue); entity_specifics.mutable_password() @@ -1898,8 +1898,8 @@ SetCustomPassphraseAndCheck("new_passphrase"); { ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); - Cryptographer* cryptographer = GetCryptographer(&trans); - EXPECT_TRUE(cryptographer->is_ready()); + DirectoryCryptographer* cryptographer = GetCryptographer(&trans); + EXPECT_TRUE(cryptographer->CanEncrypt()); ReadNode password_node(&trans); EXPECT_EQ(BaseNode::INIT_OK, password_node.InitByClientTagLookup(PASSWORDS, kClientTag)); @@ -1930,8 +1930,8 @@ } { ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); - Cryptographer* cryptographer = GetCryptographer(&trans); - EXPECT_TRUE(cryptographer->is_ready()); + DirectoryCryptographer* cryptographer = GetCryptographer(&trans); + EXPECT_TRUE(cryptographer->CanEncrypt()); ReadNode password_node(&trans); EXPECT_EQ(BaseNode::INIT_OK, password_node.InitByClientTagLookup(PASSWORDS, tag)); @@ -1951,7 +1951,7 @@ sync_pb::EntitySpecifics entity_specifics; { ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); - Cryptographer* cryptographer = GetCryptographer(&trans); + DirectoryCryptographer* cryptographer = GetCryptographer(&trans); sync_pb::PasswordSpecificsData data; data.set_password_value("secret"); cryptographer->Encrypt( @@ -1982,7 +1982,7 @@ sync_pb::EntitySpecifics entity_specifics; { ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); - Cryptographer* cryptographer = GetCryptographer(&trans); + DirectoryCryptographer* cryptographer = GetCryptographer(&trans); sync_pb::PasswordSpecificsData data; data.set_password_value("secret"); data.set_signon_realm(kUrl); @@ -2004,8 +2004,8 @@ // Check that unencrypted metadata field was set. { ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); - Cryptographer* cryptographer = GetCryptographer(&trans); - EXPECT_TRUE(cryptographer->is_ready()); + DirectoryCryptographer* cryptographer = GetCryptographer(&trans); + EXPECT_TRUE(cryptographer->CanEncrypt()); ReadNode password_node(&trans); EXPECT_EQ(BaseNode::INIT_OK, password_node.InitByClientTagLookup(PASSWORDS, kClientTag)); @@ -2028,7 +2028,7 @@ sync_pb::EntitySpecifics entity_specifics; { ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); - Cryptographer* cryptographer = GetCryptographer(&trans); + DirectoryCryptographer* cryptographer = GetCryptographer(&trans); sync_pb::PasswordSpecificsData data; data.set_password_value("secret"); data.set_signon_realm(kUrl); @@ -2063,7 +2063,7 @@ // Create a synced bookmark with undecryptable data. ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); - Cryptographer other_cryptographer; + DirectoryCryptographer other_cryptographer; KeyParams fake_params = {KeyDerivationParams::CreateForPbkdf2(), "fake_key"}; other_cryptographer.AddKey(fake_params); @@ -2106,7 +2106,7 @@ // Create a synced bookmark with undecryptable data. ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); - Cryptographer other_cryptographer; + DirectoryCryptographer other_cryptographer; KeyParams fake_params = {KeyDerivationParams::CreateForPbkdf2(), "fake_key"}; other_cryptographer.AddKey(fake_params); @@ -2378,7 +2378,7 @@ EXPECT_TRUE(SetUpEncryption(WRITE_TO_NIGORI, DEFAULT_ENCRYPTION)); { ReadTransaction trans(FROM_HERE, sync_manager_.GetUserShare()); - Cryptographer* crypto = GetCryptographer(&trans); + DirectoryCryptographer* crypto = GetCryptographer(&trans); sync_pb::EntitySpecifics bm_specifics; bm_specifics.mutable_bookmark()->set_title("title"); bm_specifics.mutable_bookmark()->set_url("url"); @@ -2487,8 +2487,8 @@ EXPECT_EQ(BaseNode::INIT_OK, node.InitByIdLookup(GetIdForDataType(NIGORI))); sync_pb::NigoriSpecifics nigori = node.GetNigoriSpecifics(); EXPECT_TRUE(nigori.has_encryption_keybag()); - Cryptographer* cryptographer = GetCryptographer(&trans); - EXPECT_TRUE(cryptographer->is_ready()); + DirectoryCryptographer* cryptographer = GetCryptographer(&trans); + EXPECT_TRUE(cryptographer->CanEncrypt()); EXPECT_TRUE(cryptographer->CanDecrypt(nigori.encryption_keybag())); } }
diff --git a/components/sync/engine_impl/syncer_unittest.cc b/components/sync/engine_impl/syncer_unittest.cc index bc688cf..9129af5 100644 --- a/components/sync/engine_impl/syncer_unittest.cc +++ b/components/sync/engine_impl/syncer_unittest.cc
@@ -39,10 +39,10 @@ #include "components/sync/engine_impl/net/server_connection_manager.h" #include "components/sync/engine_impl/sync_scheduler_impl.h" #include "components/sync/engine_impl/syncer_proto_util.h" -#include "components/sync/nigori/cryptographer.h" #include "components/sync/protocol/bookmark_specifics.pb.h" #include "components/sync/protocol/nigori_specifics.pb.h" #include "components/sync/protocol/preference_specifics.pb.h" +#include "components/sync/syncable/directory_cryptographer.h" #include "components/sync/syncable/mutable_entry.h" #include "components/sync/syncable/nigori_util.h" #include "components/sync/syncable/syncable_delete_journal.h" @@ -505,7 +505,7 @@ mock_server_->ExpectGetUpdatesRequestTypes(enabled_datatypes_); } - Cryptographer* GetCryptographer(syncable::BaseTransaction* trans) { + DirectoryCryptographer* GetCryptographer(syncable::BaseTransaction* trans) { return test_user_share_.GetCryptographer(trans); } @@ -659,7 +659,7 @@ // Mark bookmarks as encrypted and set the cryptographer to have pending // keys. syncable::WriteTransaction wtrans(FROM_HERE, UNITTEST, directory()); - Cryptographer other_cryptographer; + DirectoryCryptographer other_cryptographer; other_cryptographer.AddKey(other_params); sync_pb::EntitySpecifics specifics; sync_pb::NigoriSpecifics* nigori = specifics.mutable_nigori(); @@ -1014,7 +1014,7 @@ TEST_F(SyncerTest, EncryptionAwareConflicts) { KeyParams key_params = {KeyDerivationParams::CreateForPbkdf2(), "foobar"}; - Cryptographer other_cryptographer; + DirectoryCryptographer other_cryptographer; other_cryptographer.AddKey(key_params); sync_pb::EntitySpecifics bookmark, encrypted_bookmark, modified_bookmark; bookmark.mutable_bookmark()->set_title("title");
diff --git a/components/sync/nigori/DEPS b/components/sync/nigori/DEPS index c2ee8b4..999730c 100644 --- a/components/sync/nigori/DEPS +++ b/components/sync/nigori/DEPS
@@ -4,5 +4,8 @@ "+components/sync/model", "+components/sync/model_impl", "+components/sync/protocol", + # TODO(crbug.com/967417): Remove once the USS code doesn't use the legacy + # cryptographer. + "+components/sync/syncable", "+crypto", ]
diff --git a/components/sync/nigori/cryptographer.cc b/components/sync/nigori/cryptographer.cc index 15f6a32..af56260 100644 --- a/components/sync/nigori/cryptographer.cc +++ b/components/sync/nigori/cryptographer.cc
@@ -1,367 +1,40 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2019 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "components/sync/nigori/cryptographer.h" -#include <stddef.h> - -#include <algorithm> -#include <utility> - -#include "base/base64.h" #include "base/logging.h" -#include "components/sync/base/encryptor.h" -#include "components/sync/protocol/nigori_specifics.pb.h" namespace syncer { -KeyParams::KeyParams(KeyDerivationParams derivation_params, - const std::string& password) - : derivation_params(derivation_params), password(password) {} +Cryptographer::Cryptographer() = default; -KeyParams::KeyParams(const KeyParams& other) = default; -KeyParams::KeyParams(KeyParams&& other) = default; -KeyParams::~KeyParams() = default; - -CryptographerDataWithPendingKeys::CryptographerDataWithPendingKeys() = default; -CryptographerDataWithPendingKeys::CryptographerDataWithPendingKeys( - CryptographerDataWithPendingKeys&& other) = default; -CryptographerDataWithPendingKeys::~CryptographerDataWithPendingKeys() = default; - -// static -Cryptographer Cryptographer::CreateFromCryptographerDataWithPendingKeys( - const CryptographerDataWithPendingKeys& serialized_state) { - std::unique_ptr<sync_pb::EncryptedData> pending_keys; - if (serialized_state.pending_keys.has_value()) { - pending_keys = std::make_unique<sync_pb::EncryptedData>( - *serialized_state.pending_keys); - } - return Cryptographer(NigoriKeyBag::CreateFromProto( - serialized_state.cryptographer_data.key_bag()), - serialized_state.cryptographer_data.default_key_name(), - std::move(pending_keys)); -} - -Cryptographer::Cryptographer() : key_bag_(NigoriKeyBag::CreateEmpty()) {} - -Cryptographer::Cryptographer(const Cryptographer& other) - : key_bag_(other.key_bag_.Clone()), - default_nigori_name_(other.default_nigori_name_) { - if (other.pending_keys_) { - pending_keys_ = - std::make_unique<sync_pb::EncryptedData>(*(other.pending_keys_)); - } -} - -Cryptographer::~Cryptographer() {} - -void Cryptographer::CopyFrom(const Cryptographer& other) { - key_bag_.CopyFrom(other.key_bag_); - default_nigori_name_ = other.default_nigori_name_; - if (other.pending_keys_) { - pending_keys_ = - std::make_unique<sync_pb::EncryptedData>(*other.pending_keys_); - } -} - -CryptographerDataWithPendingKeys -Cryptographer::ToCryptographerDataWithPendingKeys() const { - CryptographerDataWithPendingKeys output; - *output.cryptographer_data.mutable_key_bag() = key_bag_.ToProto(); - output.cryptographer_data.set_default_key_name(default_nigori_name_); - if (pending_keys_) { - output.pending_keys = *pending_keys_; - } - return output; -} - -void Cryptographer::Bootstrap(const Encryptor& encryptor, - const std::string& restored_bootstrap_token) { - if (is_initialized()) { - NOTREACHED(); - return; - } - - std::string serialized_nigori_key = - UnpackBootstrapToken(encryptor, restored_bootstrap_token); - if (serialized_nigori_key.empty()) - return; - ImportNigoriKey(serialized_nigori_key); -} - -bool Cryptographer::CanDecrypt(const sync_pb::EncryptedData& data) const { - return key_bag_.HasKey(data.key_name()); -} - -bool Cryptographer::CanDecryptUsingDefaultKey( - const sync_pb::EncryptedData& data) const { - return !default_nigori_name_.empty() && - data.key_name() == default_nigori_name_; -} +Cryptographer::~Cryptographer() = default; bool Cryptographer::Encrypt(const ::google::protobuf::MessageLite& message, sync_pb::EncryptedData* encrypted) const { DCHECK(encrypted); - if (default_nigori_name_.empty()) { - LOG(ERROR) << "Cryptographer not ready, failed to encrypt."; - return false; - } std::string serialized; if (!message.SerializeToString(&serialized)) { - LOG(ERROR) << "Message is invalid/missing a required field."; + DLOG(ERROR) << "Message is invalid/missing a required field."; return false; } return EncryptString(serialized, encrypted); } -bool Cryptographer::EncryptString(const std::string& serialized, - sync_pb::EncryptedData* encrypted) const { - if (CanDecryptUsingDefaultKey(*encrypted)) { - std::string original_serialized; - if (DecryptToString(*encrypted, &original_serialized) && - original_serialized == serialized) { - DVLOG(2) << "Re-encryption unnecessary, encrypted data already matches."; - return true; - } - } - - if (!key_bag_.HasKey(default_nigori_name_)) { - LOG(ERROR) << "Corrupt default key."; - return false; - } - - return key_bag_.EncryptWithKey(default_nigori_name_, serialized, encrypted); -} - bool Cryptographer::Decrypt(const sync_pb::EncryptedData& encrypted, ::google::protobuf::MessageLite* message) const { DCHECK(message); + std::string plaintext; if (!DecryptToString(encrypted, &plaintext)) { return false; } + return message->ParseFromString(plaintext); } -bool Cryptographer::DecryptToString(const sync_pb::EncryptedData& encrypted, - std::string* decrypted) const { - return key_bag_.Decrypt(encrypted, decrypted); -} - -bool Cryptographer::GetKeys(sync_pb::EncryptedData* encrypted) const { - DCHECK(encrypted); - DCHECK_NE(size_t(0), key_bag_.size()); - - // Create a bag of all the Nigori parameters we know about. - sync_pb::NigoriKeyBag bag = key_bag_.ToProto(); - - // Encrypt the bag with the default Nigori. - return Encrypt(bag, encrypted); -} - -bool Cryptographer::AddKey(const KeyParams& params) { - return AddKeyImpl( - Nigori::CreateByDerivation(params.derivation_params, params.password), - /*set_as_default=*/true); -} - -bool Cryptographer::AddNonDefaultKey(const KeyParams& params) { - DCHECK(is_initialized()); - return AddKeyImpl( - Nigori::CreateByDerivation(params.derivation_params, params.password), - /*set_as_default=*/false); -} - -bool Cryptographer::AddKeyFromBootstrapToken( - const Encryptor& encryptor, - const std::string& restored_bootstrap_token) { - // Create the new Nigori and make it the default encryptor. - std::string serialized_nigori_key = - UnpackBootstrapToken(encryptor, restored_bootstrap_token); - return ImportNigoriKey(serialized_nigori_key); -} - -bool Cryptographer::AddKeyImpl(std::unique_ptr<Nigori> nigori, - bool set_as_default) { - DCHECK(nigori); - std::string key_name = key_bag_.AddKey(std::move(nigori)); - if (key_name.empty()) { - NOTREACHED(); - return false; - } - - // Check if the key we just added can decrypt the pending keys and add them - // too if so. - if (pending_keys_.get() && CanDecrypt(*pending_keys_)) { - sync_pb::NigoriKeyBag pending_bag; - Decrypt(*pending_keys_, &pending_bag); - InstallKeyBag(pending_bag); - SetDefaultKey(pending_keys_->key_name()); - pending_keys_.reset(); - } - - // The just-added key takes priority over the pending keys as default. - if (set_as_default) - SetDefaultKey(key_name); - return true; -} - -void Cryptographer::InstallKeys(const sync_pb::EncryptedData& encrypted) { - DCHECK(CanDecrypt(encrypted)); - - sync_pb::NigoriKeyBag bag; - if (!Decrypt(encrypted, &bag)) - return; - InstallKeyBag(bag); -} - -void Cryptographer::SetDefaultKey(const std::string& key_name) { - DCHECK(key_bag_.HasKey(key_name)); - default_nigori_name_ = key_name; -} - -bool Cryptographer::is_initialized() const { - return !default_nigori_name_.empty(); -} - -void Cryptographer::SetPendingKeys(const sync_pb::EncryptedData& encrypted) { - DCHECK(!CanDecrypt(encrypted)); - DCHECK(!encrypted.blob().empty()); - pending_keys_ = std::make_unique<sync_pb::EncryptedData>(encrypted); -} - -const sync_pb::EncryptedData& Cryptographer::GetPendingKeys() const { - DCHECK(has_pending_keys()); - return *(pending_keys_.get()); -} - -bool Cryptographer::DecryptPendingKeys(const KeyParams& params) { - DCHECK_NE(KeyDerivationMethod::UNSUPPORTED, - params.derivation_params.method()); - - std::unique_ptr<Nigori> nigori = - Nigori::CreateByDerivation(params.derivation_params, params.password); - - std::string plaintext; - if (!nigori->Decrypt(pending_keys_->blob(), &plaintext)) - return false; - - sync_pb::NigoriKeyBag bag; - if (!bag.ParseFromString(plaintext)) { - NOTREACHED(); - return false; - } - InstallKeyBag(bag); - const std::string& new_default_key_name = pending_keys_->key_name(); - SetDefaultKey(new_default_key_name); - pending_keys_.reset(); - return true; -} - -bool Cryptographer::GetBootstrapToken(const Encryptor& encryptor, - std::string* token) const { - DCHECK(token); - std::string unencrypted_token = GetDefaultNigoriKeyData(); - if (unencrypted_token.empty()) - return false; - - std::string encrypted_token; - if (!encryptor.EncryptString(unencrypted_token, &encrypted_token)) { - return false; - } - - base::Base64Encode(encrypted_token, token); - - return true; -} - -std::string Cryptographer::UnpackBootstrapToken( - const Encryptor& encryptor, - const std::string& token) const { - if (token.empty()) - return std::string(); - - std::string encrypted_data; - if (!base::Base64Decode(token, &encrypted_data)) { - DLOG(WARNING) << "Could not decode token."; - return std::string(); - } - - std::string unencrypted_token; - if (!encryptor.DecryptString(encrypted_data, &unencrypted_token)) { - DLOG(WARNING) << "Decryption of bootstrap token failed."; - return std::string(); - } - return unencrypted_token; -} - -void Cryptographer::InstallKeyBag(const sync_pb::NigoriKeyBag& bag) { - key_bag_.AddAllUnknownKeysFrom(NigoriKeyBag::CreateFromProto(bag)); -} - -bool Cryptographer::KeybagIsStale( - const sync_pb::EncryptedData& encrypted_bag) const { - if (!is_ready()) - return false; - if (encrypted_bag.blob().empty()) - return true; - if (!CanDecrypt(encrypted_bag)) - return false; - if (!CanDecryptUsingDefaultKey(encrypted_bag)) - return true; - sync_pb::NigoriKeyBag bag; - if (!Decrypt(encrypted_bag, &bag)) { - LOG(ERROR) << "Failed to decrypt keybag for stale check. " - << "Assuming keybag is corrupted."; - return true; - } - if (static_cast<size_t>(bag.key_size()) < key_bag_.size()) - return true; - return false; -} - -std::string Cryptographer::GetDefaultNigoriKeyName() const { - return default_nigori_name_; -} - -std::string Cryptographer::GetDefaultNigoriKeyData() const { - if (!is_initialized()) - return std::string(); - sync_pb::NigoriKey key = key_bag_.ExportKey(default_nigori_name_); - key.clear_name(); - return key.SerializeAsString(); -} - -bool Cryptographer::ImportNigoriKey(const std::string& serialized_nigori_key) { - if (serialized_nigori_key.empty()) - return false; - - sync_pb::NigoriKey key; - if (!key.ParseFromString(serialized_nigori_key)) - return false; - - std::unique_ptr<Nigori> nigori = Nigori::CreateByImport( - key.user_key(), key.encryption_key(), key.mac_key()); - - if (!nigori) { - DLOG(ERROR) << "Ignoring invalid Nigori when importing"; - return false; - } - - if (!AddKeyImpl(std::move(nigori), true)) - return false; - return true; -} - -Cryptographer::Cryptographer( - NigoriKeyBag key_bag, - const std::string& default_nigori_name, - std::unique_ptr<sync_pb::EncryptedData> pending_keys) - : key_bag_(std::move(key_bag)), - default_nigori_name_(std::move(default_nigori_name)), - pending_keys_(std::move(pending_keys)) {} - } // namespace syncer
diff --git a/components/sync/nigori/cryptographer.h b/components/sync/nigori/cryptographer.h index 42e3491..7781cb9 100644 --- a/components/sync/nigori/cryptographer.h +++ b/components/sync/nigori/cryptographer.h
@@ -1,244 +1,65 @@ -// Copyright 2012 The Chromium Authors. All rights reserved. +// Copyright 2019 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef COMPONENTS_SYNC_NIGORI_CRYPTOGRAPHER_H_ #define COMPONENTS_SYNC_NIGORI_CRYPTOGRAPHER_H_ -#include <map> #include <memory> #include <string> #include "base/macros.h" -#include "base/optional.h" -#include "components/sync/base/passphrase_enums.h" -#include "components/sync/nigori/nigori.h" -#include "components/sync/nigori/nigori_key_bag.h" #include "components/sync/protocol/encryption.pb.h" -#include "components/sync/protocol/nigori_local_data.pb.h" - -namespace sync_pb { -class NigoriKeyBag; -} // namespace sync_pb namespace syncer { -class Encryptor; - -// The parameters used to initialize a Nigori instance. -// TODO(davidovic): Stop relying on KeyParams and inline it, because it's now -// just a pair of KeyDerivationParams and passphrase. -struct KeyParams { - KeyParams(KeyDerivationParams derivation_params, const std::string& password); - KeyParams(const KeyParams& other); - KeyParams(KeyParams&& other); - ~KeyParams(); - - KeyDerivationParams derivation_params; - std::string password; -}; - -struct CryptographerDataWithPendingKeys { - CryptographerDataWithPendingKeys(); - CryptographerDataWithPendingKeys(CryptographerDataWithPendingKeys&& other); - ~CryptographerDataWithPendingKeys(); - - sync_pb::CryptographerData cryptographer_data; - base::Optional<sync_pb::EncryptedData> pending_keys; - - private: - DISALLOW_COPY_AND_ASSIGN(CryptographerDataWithPendingKeys); -}; - -// This class manages the Nigori objects used to encrypt and decrypt sensitive -// sync data (eg. passwords). Each Nigori object knows how to handle data -// protected with a particular passphrase. -// -// Whenever an update to the Nigori sync node is received from the server, -// SetPendingKeys should be called with the encrypted contents of that node. -// Most likely, an updated Nigori node means that a new passphrase has been set -// and that future node updates won't be decryptable. To remedy this, the user -// should be prompted for the new passphrase and DecryptPendingKeys be called. -// -// Whenever a update to an encrypted node is received from the server, -// CanDecrypt should be used to verify whether the Cryptographer can decrypt -// that node. If it cannot, then the application of that update should be -// delayed until after it can be decrypted. +// Interface used to encrypt and decrypt sensitive sync data (eg. passwords). class Cryptographer { public: - // Deserialization. - static Cryptographer CreateFromCryptographerDataWithPendingKeys( - const CryptographerDataWithPendingKeys& serialized_state); - Cryptographer(); - Cryptographer(const Cryptographer& other); - ~Cryptographer(); + virtual ~Cryptographer(); - void CopyFrom(const Cryptographer& other); + virtual std::unique_ptr<Cryptographer> Clone() const = 0; - // Serialization. - CryptographerDataWithPendingKeys ToCryptographerDataWithPendingKeys() const; + // Returns whether this cryptographer is ready to encrypt data, using + // EncryptString(). This usually means that a default encryption key is + // available and there are no pending keys. + virtual bool CanEncrypt() const = 0; - // |restored_bootstrap_token| can be provided via this method to bootstrap - // Cryptographer instance into the ready state (is_ready will be true). - // It must be a string that was previously built by the - // GetSerializedBootstrapToken function. It is possible that the token is no - // longer valid (due to server key change), in which case the normal - // decryption code paths will fail and the user will need to provide a new - // passphrase. - // It is an error to call this if is_ready() == true, though it is fair to - // never call Bootstrap at all. - void Bootstrap(const Encryptor& encryptor, - const std::string& restored_bootstrap_token); + // Returns whether this cryptographer can decrypt |encrypted| using any of + // the known keys. + virtual bool CanDecrypt(const sync_pb::EncryptedData& encrypted) const = 0; - // Returns whether we can decrypt |encrypted| using the keys we currently know - // about. - bool CanDecrypt(const sync_pb::EncryptedData& encrypted) const; + // Returns a name that uniquely identifies the key used for encryption. + virtual std::string GetDefaultEncryptionKeyName() const = 0; - // Returns whether |encrypted| can be decrypted using the default encryption - // key. - bool CanDecryptUsingDefaultKey(const sync_pb::EncryptedData& encrypted) const; + // Encrypted |decrypted| into |*encrypted|. |encrypted| must not be null. + // Returns false in case of error, which most notably includes the case + // where CanEncrypt() returns false. + virtual bool EncryptString(const std::string& decrypted, + sync_pb::EncryptedData* encrypted) const = 0; - // Encrypts |message| into |encrypted|. Does not overwrite |encrypted| if - // |message| already matches the decrypted data within |encrypted| and - // |encrypted| was encrypted with the current default key. This avoids - // unnecessarily modifying |encrypted| if the change had no practical effect. - // Returns true unless encryption fails or |message| isn't valid (e.g. a - // required field isn't set). + // Decrypts |encrypted| as a plaintext decrypted data into |*decrypted|. + // |decrypted| must not be null. Returns false in case of error, which most + // notably includes the case where CanDecrypt() would have returned false. + virtual bool DecryptToString(const sync_pb::EncryptedData& encrypted, + std::string* decrypted) const = 0; + + // Convenience function to deal with protocol buffers. It uses EncryptString() + // after serialization. bool Encrypt(const ::google::protobuf::MessageLite& message, sync_pb::EncryptedData* encrypted) const; - // Encrypted |serialized| into |encrypted|. Does not overwrite |encrypted| if - // |message| already matches the decrypted data within |encrypted| and - // |encrypted| was encrypted with the current default key. This avoids - // unnecessarily modifying |encrypted| if the change had no practical effect. - // Returns true unless encryption fails or |message| isn't valid (e.g. a - // required field isn't set). - bool EncryptString(const std::string& serialized, - sync_pb::EncryptedData* encrypted) const; - - // Decrypts |encrypted| into |message|. Returns true unless decryption fails, - // or |message| fails to parse the decrypted data. + // Convenience function to deal with protocol buffers. After decryption, it + // parses the decrypted content into a protocol buffer. bool Decrypt(const sync_pb::EncryptedData& encrypted, ::google::protobuf::MessageLite* message) const; - // Decrypts |encrypted| as a plaintext decrypted data in |decrypted|. If - // decryption fails, returns false otherwise returns true. - bool DecryptToString(const sync_pb::EncryptedData& encrypted, - std::string* decrypted) const; - - // Encrypts the set of currently known keys into |encrypted|. Returns true if - // successful. - bool GetKeys(sync_pb::EncryptedData* encrypted) const; - - // Creates a new Nigori instance using |params|. If successful, |params| will - // become the default encryption key and be used for all future calls to - // Encrypt. - // Will decrypt the pending keys and install them if possible (pending key - // will not overwrite default). - bool AddKey(const KeyParams& params); - - // Same as AddKey(..), but builds the new Nigori from a previously persisted - // bootstrap token. This can be useful when consuming a bootstrap token - // with a cryptographer that has already been initialized. - // Updates the default key. - // Will decrypt the pending keys and install them if possible (pending key - // will not overwrite default). - bool AddKeyFromBootstrapToken(const Encryptor& encryptor, - const std::string& restored_bootstrap_token); - - // Creates a new Nigori instance using |params|. If successful, |params| - // will be added to the nigori keybag, but will not be the default encryption - // key (default_nigori_ will remain the same). - // Prereq: is_initialized() must be true. - // Will decrypt the pending keys and install them if possible (pending key - // will become the new default). - bool AddNonDefaultKey(const KeyParams& params); - - // Decrypts |encrypted| and uses its contents to initialize Nigori instances. - // Returns true unless decryption of |encrypted| fails. The caller is - // responsible for checking that CanDecrypt(encrypted) == true. - // Does not modify the default key. - void InstallKeys(const sync_pb::EncryptedData& encrypted); - - // Makes a local copy of |encrypted| to later be decrypted by - // DecryptPendingKeys. This should only be used if CanDecrypt(encrypted) == - // false. - void SetPendingKeys(const sync_pb::EncryptedData& encrypted); - - // Makes |pending_keys_| available to callers that may want to cache its - // value for later use on the UI thread. It is illegal to call this if the - // cryptographer has no pending keys. Like other calls that access the - // cryptographer, this method must be called from within a transaction. - const sync_pb::EncryptedData& GetPendingKeys() const; - - // Attempts to decrypt the set of keys that was copied in the previous call to - // SetPendingKeys using |params|. Returns true if the pending keys were - // successfully decrypted and installed. If successful, the default key - // is updated. - bool DecryptPendingKeys(const KeyParams& params); - - // Sets the default key to the nigori with name |key_name|. |key_name| must - // correspond to a nigori that has already been installed into the keybag. - void SetDefaultKey(const std::string& key_name); - - bool is_initialized() const; - - // Returns whether this Cryptographer is ready to encrypt and decrypt data. - bool is_ready() const { return is_initialized() && !has_pending_keys(); } - // Returns whether there is a pending set of keys that needs to be decrypted. - bool has_pending_keys() const { return nullptr != pending_keys_.get(); } - - // Obtain a token that can be provided on construction to a future - // Cryptographer instance to bootstrap itself. Returns false if such a token - // can't be created (i.e. if this Cryptograhper doesn't have valid keys). - bool GetBootstrapToken(const Encryptor& encryptor, std::string* token) const; - - // Returns true if |keybag| is decryptable and either is a subset of - // |key_bag_| and/or has a different default key. - bool KeybagIsStale(const sync_pb::EncryptedData& keybag) const; - - // Returns the name of the Nigori key currently used for encryption. - std::string GetDefaultNigoriKeyName() const; - - // Returns a serialized sync_pb::NigoriKey version of current default - // encryption key. Returns empty string if Cryptographer is not initialized - // or protobuf serialization error occurs. - std::string GetDefaultNigoriKeyData() const; - - // Generates a new Nigori from |serialized_nigori_key|, and if successful - // installs the new nigori as the default key. - bool ImportNigoriKey(const std::string& serialized_nigori_key); + // TODO(crbug.com/967417): Remove from cryptographer API. + virtual bool has_pending_keys() const = 0; private: - // Initializes cryptographer with completely provided state. - Cryptographer(NigoriKeyBag key_bag, - const std::string& default_nigori_name, - std::unique_ptr<sync_pb::EncryptedData> pending_keys); - - // Helper method to instantiate Nigori instances for each set of key - // parameters in |bag|. - // Does not update the default nigori. - void InstallKeyBag(const sync_pb::NigoriKeyBag& bag); - - // Helper method to add a nigori to the keybag, optionally making it the - // default as well. - bool AddKeyImpl(std::unique_ptr<Nigori> nigori, bool set_as_default); - - // Helper to unencrypt a bootstrap token into a serialized sync_pb::NigoriKey. - std::string UnpackBootstrapToken(const Encryptor& encryptor, - const std::string& token) const; - - // The actual keys we know about. - NigoriKeyBag key_bag_; - - // The key name associated with the default nigori. If non-empty, must - // correspond to a nigori within |key_bag_|. - std::string default_nigori_name_; - - std::unique_ptr<sync_pb::EncryptedData> pending_keys_; - DISALLOW_ASSIGN(Cryptographer); };
diff --git a/components/sync/nigori/nigori_sync_bridge_impl.cc b/components/sync/nigori/nigori_sync_bridge_impl.cc index b55794bc..4ee5f636 100644 --- a/components/sync/nigori/nigori_sync_bridge_impl.cc +++ b/components/sync/nigori/nigori_sync_bridge_impl.cc
@@ -38,7 +38,7 @@ return base::nullopt; } - Cryptographer cryptographer; + DirectoryCryptographer cryptographer; for (const std::string& key : keystore_keys) { KeyParams key_params = {KeyDerivationParams::CreateForPbkdf2(), key}; // TODO(crbug.com/922900): possible behavioral change. Old implementation @@ -75,7 +75,7 @@ const std::vector<std::string>& keystore_keys) { DCHECK(!keystore_keys.empty()); - Cryptographer cryptographer; + DirectoryCryptographer cryptographer; // The last keystore key will become default. for (const std::string& key : keystore_keys) { // This check and checks below theoretically should never fail, but in case @@ -390,8 +390,9 @@ // Packs explicit passphrase key in order to persist it. Should be aligned with // Directory implementation (Cryptographer::GetBootstrapToken()) unless it is // removed. Returns empty string in case of errors. -std::string PackExplicitPassphraseKey(const Encryptor& encryptor, - const Cryptographer& cryptographer) { +std::string PackExplicitPassphraseKey( + const Encryptor& encryptor, + const DirectoryCryptographer& cryptographer) { // Explicit passphrase key should always be default one. std::string serialized_key = cryptographer.GetDefaultNigoriKeyData(); if (serialized_key.empty()) { @@ -440,7 +441,7 @@ if (serialized_key.empty()) { return false; } - Cryptographer cryptographer; + DirectoryCryptographer cryptographer; cryptographer.ImportNigoriKey(serialized_key); return cryptographer.CanDecrypt(encrypted_data); } @@ -533,9 +534,8 @@ if (nigori_model.has_pending_keys()) { serialized_cryptographer.pending_keys = nigori_model.pending_keys(); } - cryptographer_.CopyFrom( - Cryptographer::CreateFromCryptographerDataWithPendingKeys( - serialized_cryptographer)); + cryptographer_.InitFromCryptographerDataWithPendingKeys( + serialized_cryptographer); // Restore rest of the state. passphrase_type_ = nigori_model.passphrase_type(); @@ -606,7 +606,7 @@ } UMA_HISTOGRAM_ENUMERATION("Sync.PassphraseType", enum_passphrase_type); } - UMA_HISTOGRAM_BOOLEAN("Sync.CryptographerReady", cryptographer_.is_ready()); + UMA_HISTOGRAM_BOOLEAN("Sync.CryptographerReady", cryptographer_.CanEncrypt()); UMA_HISTOGRAM_BOOLEAN("Sync.CryptographerPendingKeys", cryptographer_.has_pending_keys()); if (cryptographer_.has_pending_keys() && @@ -643,7 +643,7 @@ case NigoriSpecifics::TRUSTED_VAULT_PASSPHRASE: break; } - DCHECK(cryptographer_.is_ready()); + DCHECK(cryptographer_.CanEncrypt()); passphrase_type_ = NigoriSpecifics::CUSTOM_PASSPHRASE; custom_passphrase_key_derivation_params_ = CreateKeyDerivationParamsForCustomPassphrase(random_salt_generator_); @@ -942,7 +942,7 @@ DecryptKeystoreDecryptor(keystore_keys_, keystore_decryptor_token); if (!serialized_keystore_decryptor || !cryptographer_.ImportNigoriKey(*serialized_keystore_decryptor) || - !cryptographer_.is_ready()) { + !cryptographer_.CanEncrypt()) { return ModelError(FROM_HERE, "Failed to decrypt pending keys using the keystore " "decryptor token."); @@ -982,7 +982,7 @@ std::unique_ptr<EntityData> NigoriSyncBridgeImpl::GetData() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(cryptographer_.is_ready()); + DCHECK(cryptographer_.CanEncrypt()); DCHECK_NE(passphrase_type_, NigoriSpecifics::UNKNOWN); NigoriSpecifics specifics; @@ -1041,7 +1041,7 @@ // solution. storage_->ClearData(); keystore_keys_.clear(); - cryptographer_.CopyFrom(Cryptographer()); + cryptographer_.CopyFrom(DirectoryCryptographer()); passphrase_type_ = NigoriSpecifics::UNKNOWN; encrypt_everything_ = false; custom_passphrase_time_ = base::Time(); @@ -1055,7 +1055,8 @@ } } -const Cryptographer& NigoriSyncBridgeImpl::GetCryptographerForTesting() const { +const DirectoryCryptographer& NigoriSyncBridgeImpl::GetCryptographerForTesting() + const { return cryptographer_; } @@ -1070,7 +1071,7 @@ std::string NigoriSyncBridgeImpl::PackExplicitPassphraseKeyForTesting( const Encryptor& encryptor, - const Cryptographer& cryptographer) { + const DirectoryCryptographer& cryptographer) { return PackExplicitPassphraseKey(encryptor, cryptographer); }
diff --git a/components/sync/nigori/nigori_sync_bridge_impl.h b/components/sync/nigori/nigori_sync_bridge_impl.h index a1a986d..06003023 100644 --- a/components/sync/nigori/nigori_sync_bridge_impl.h +++ b/components/sync/nigori/nigori_sync_bridge_impl.h
@@ -18,10 +18,10 @@ #include "components/sync/engine/sync_encryption_handler.h" #include "components/sync/model/conflict_resolution.h" #include "components/sync/model/model_error.h" -#include "components/sync/nigori/cryptographer.h" #include "components/sync/nigori/keystore_keys_handler.h" #include "components/sync/nigori/nigori_local_change_processor.h" #include "components/sync/nigori/nigori_sync_bridge.h" +#include "components/sync/syncable/directory_cryptographer.h" namespace sync_pb { class NigoriLocalData; @@ -81,13 +81,13 @@ // TODO(crbug.com/922900): investigate whether we need this getter outside of // tests and decide whether this method should be a part of // SyncEncryptionHandler interface. - const Cryptographer& GetCryptographerForTesting() const; + const DirectoryCryptographer& GetCryptographerForTesting() const; sync_pb::NigoriSpecifics::PassphraseType GetPassphraseTypeForTesting() const; ModelTypeSet GetEncryptedTypesForTesting() const; static std::string PackExplicitPassphraseKeyForTesting( const Encryptor& encryptor, - const Cryptographer& cryptographer); + const DirectoryCryptographer& cryptographer); private: base::Optional<ModelError> UpdateLocalState( @@ -134,7 +134,7 @@ // separately. Should be encrypted with OSCrypt before persisting. std::vector<std::string> keystore_keys_; - Cryptographer cryptographer_; + DirectoryCryptographer cryptographer_; // TODO(mmoskvitin): Consider adopting the C++ enum PassphraseType here and // if so remove function ProtoPassphraseInt32ToProtoEnum() from // passphrase_enums.h.
diff --git a/components/sync/nigori/nigori_sync_bridge_impl_unittest.cc b/components/sync/nigori/nigori_sync_bridge_impl_unittest.cc index 1355f403..c502e9d 100644 --- a/components/sync/nigori/nigori_sync_bridge_impl_unittest.cc +++ b/components/sync/nigori/nigori_sync_bridge_impl_unittest.cc
@@ -45,7 +45,8 @@ std::string expected_default_key_name; EXPECT_TRUE(expected_default_nigori->Permute( Nigori::Type::Password, kNigoriKeyName, &expected_default_key_name)); - return cryptographer.GetDefaultNigoriKeyName() == expected_default_key_name; + return cryptographer.GetDefaultEncryptionKeyName() == + expected_default_key_name; } MATCHER(HasKeystoreNigori, "") { @@ -143,7 +144,7 @@ std::string PackKeyAsExplicitPassphrase(const KeyParams& key_params, const Encryptor& encryptor) { - Cryptographer cryptographer; + DirectoryCryptographer cryptographer; cryptographer.AddKey(key_params); return NigoriSyncBridgeImpl::PackExplicitPassphraseKeyForTesting( encryptor, cryptographer); @@ -165,7 +166,7 @@ const KeyParams& keystore_key_params) { sync_pb::NigoriSpecifics specifics; - Cryptographer cryptographer; + DirectoryCryptographer cryptographer; cryptographer.AddKey(keystore_decryptor_params); for (const KeyParams& key_params : keybag_keys_params) { cryptographer.AddNonDefaultKey(key_params); @@ -174,7 +175,7 @@ std::string serialized_keystore_decryptor = cryptographer.GetDefaultNigoriKeyData(); - Cryptographer keystore_cryptographer; + DirectoryCryptographer keystore_cryptographer; keystore_cryptographer.AddKey(keystore_key_params); EXPECT_TRUE(keystore_cryptographer.EncryptString( serialized_keystore_decryptor, @@ -186,7 +187,7 @@ sync_pb::NigoriSpecifics BuildTrustedVaultNigoriSpecifics( const std::vector<KeyParams>& trusted_vault_key_params) { - syncer::Cryptographer cryptographer; + DirectoryCryptographer cryptographer; for (const KeyParams& key_params : trusted_vault_key_params) { cryptographer.AddKey(key_params); } @@ -211,7 +212,7 @@ const base::Optional<KeyParams>& old_key_params = base::nullopt) { sync_pb::NigoriSpecifics specifics; - Cryptographer cryptographer; + DirectoryCryptographer cryptographer; cryptographer.AddKey(passphrase_key_params); if (old_key_params) { cryptographer.AddNonDefaultKey(*old_key_params);
diff --git a/components/sync/protocol/client_debug_info.proto b/components/sync/protocol/client_debug_info.proto index 34852545..62c5063 100644 --- a/components/sync/protocol/client_debug_info.proto +++ b/components/sync/protocol/client_debug_info.proto
@@ -28,24 +28,15 @@ optional bool has_valid_hint = 2; } -// A dummy message definition for deprecated fields. Never add any fields to -// this message. -message DeprecatedMessage {} - // The additional info here is from the StatusController. They get sent when // the event SYNC_CYCLE_COMPLETED is sent. message SyncCycleCompletedEventInfo { - // optional bool syncer_stuck = 1; // Was always false, now obsolete. - - // The client has never set these values correctly. It set - // num_blocking_conflicts to the total number of conflicts detected and set - // num_non_blocking_conflicts to the number of blocking (aka. simple) - // conflicts. - // - // These counters have been deprecated to avoid further confusion. The newer - // counters provide more detail and are less buggy. - optional int32 num_blocking_conflicts = 2 [deprecated = true]; - optional int32 num_non_blocking_conflicts = 3 [deprecated = true]; + reserved 1; + reserved "syncer_stuck"; + reserved 2; + reserved "num_blocking_conflicts"; + reserved 3; + reserved "num_non_blocking_conflicts"; // These new conflict counters replace the ones above. optional int32 num_encryption_conflicts = 4; @@ -61,8 +52,9 @@ // contains the |notifications_enabled| flag. optional GetUpdatesCallerInfo caller_info = 10; - // |source_info| was unused and marked deprecated in M67. - repeated DeprecatedMessage source_info = 11 [deprecated = true]; + // Deprecated in M67. + reserved 11; + reserved "source_info"; optional SyncEnums.GetUpdatesOrigin get_updates_origin = 12; }
diff --git a/components/sync/protocol/sync.proto b/components/sync/protocol/sync.proto index 4868cff..807cc5e7 100644 --- a/components/sync/protocol/sync.proto +++ b/components/sync/protocol/sync.proto
@@ -311,10 +311,8 @@ // include |position_in_parent| instead. optional string insert_after_item_id = 16; - // Arbitrary key/value pairs associated with this item. - // Present in both GetUpdatesResponse and CommitMessage. - // Deprecated. - // optional ExtendedAttributes extended_attributes = 17; + reserved 17; + reserved "extended_attributes"; // If true, indicates that this item has been (or should be) deleted. // Present in both GetUpdatesResponse and CommitMessage. @@ -401,7 +399,8 @@ // This used to be a list of sync attachment IDs, but it was never launched // and the code has been removed as of M66. - repeated DeprecatedMessage attachment_id = 26 [deprecated = true]; + reserved 26; + reserved "attachment_id"; }; // This message contains diagnostic information used to correlate @@ -565,11 +564,8 @@ // based on last modified time. optional int32 age_watermark_in_days = 3; - // This field specifies the max number of items that the client should keep - // for a specific datatype. If the number of items exceeds this limit, the - // client should purge the extra sync entities based on the LRU rule. - // Deprecated in M76. - optional int32 deprecated_max_number_of_items = 4 [deprecated = true]; + reserved 4; + reserved "max_number_of_items"; } message DataTypeProgressMarker { @@ -700,15 +696,7 @@ reserved "requested_types"; }; -message AuthenticateMessage { - required string auth_token = 1; -}; - // Message from a client asking the server to clear its data. -// -// A client makes a ClearServerData request when it transitions to passphrase -// encryption to ensure the server deletes any plaintext data that may have been -// synced previously. message ClearServerDataMessage { // No arguments needed as the store birthday and user identifier are part of // an enclosing message. @@ -775,7 +763,7 @@ enum Contents { COMMIT = 1; GET_UPDATES = 2; - AUTHENTICATE = 3; + DEPRECATED_3 = 3; DEPRECATED_4 = 4; CLEAR_SERVER_DATA = 5; } @@ -787,9 +775,10 @@ required Contents message_contents = 3; optional CommitMessage commit = 4; optional GetUpdatesMessage get_updates = 5; - optional AuthenticateMessage authenticate = 6; + reserved 6; + reserved "authenticate"; - optional DeprecatedMessage deprecated_field_9 = 9 [deprecated = true]; + reserved 9; optional string store_birthday = 7; // Opaque store ID; if it changes, duck! // The client sets this if it detects a sync issue. The server will tell it @@ -865,9 +854,8 @@ // should be filled if our parent was assigned a new ID. optional string parent_id_string = 4; - // This used to be set to the same as the position_in_parent value in - // the SyncEntity message in GetUpdatesResponse, but it's not set anymore. - optional int64 deprecated_position_in_parent = 5 [deprecated = true]; + reserved 5; + reserved "position_in_parent"; // The item's current version. optional int64 version = 6; @@ -903,8 +891,8 @@ // instead. optional int64 new_timestamp = 2; - // DEPRECATED FIELD - server does not set this anymore. - optional int64 deprecated_newest_timestamp = 3; + reserved 3; + reserved "newest_timestamp"; // Approximate count of changes remaining - use this for UI feedback. // If present and zero, this estimate is firm: the server has no changes @@ -965,25 +953,11 @@ repeated SyncEntity entries = 1; }; -// A user-identifying struct. For a given Google account the email and display -// name can change, but obfuscated_id should be constant. -// The obfuscated id is optional because at least one planned use of the proto -// (sharing) does not require it. -message UserIdentification { - required string email = 1; // the user's full primary email address. - optional string display_name = 2; // the user's display name. - optional string obfuscated_id = 3; // an obfuscated, opaque user id. -}; - -message AuthenticateResponse { - // Optional only for backward compatibility. - optional UserIdentification user = 1; -}; - message ClientToServerResponse { optional CommitResponse commit = 1; optional GetUpdatesResponse get_updates = 2; - optional AuthenticateResponse authenticate = 3; + reserved 3; + reserved "authenticate"; // Up until protocol_version 24, the default was SUCCESS which made it // impossible to add new enum values since older clients would parse any @@ -1003,7 +977,7 @@ optional ClientCommand client_command = 7; optional ProfilingData profiling_data = 8; - optional DeprecatedMessage deprecated_field_9 = 9 [deprecated = true]; + reserved 9; optional GetUpdatesMetadataResponse stream_metadata = 10; // If GetUpdatesStreamingResponse is contained in the ClientToServerResponse, // none of the other fields (error_code and etc) will be set.
diff --git a/components/sync/protocol/web_app_specifics.proto b/components/sync/protocol/web_app_specifics.proto index 7358e68..3fbd803 100644 --- a/components/sync/protocol/web_app_specifics.proto +++ b/components/sync/protocol/web_app_specifics.proto
@@ -11,10 +11,9 @@ package sync_pb; -// WebApp data. This should be a subset of WebAppProto in -// chrome/browser/web_applications/proto/web_app.proto +// WebApp data. This is a synced part of +// chrome/browser/web_applications/proto/web_app.proto data. message WebAppSpecifics { - // Keep in sync with WebAppProto::LaunchContainer. enum LaunchContainer { TAB = 1; WINDOW = 2;
diff --git a/components/sync/syncable/directory_cryptographer.cc b/components/sync/syncable/directory_cryptographer.cc new file mode 100644 index 0000000..61982e0 --- /dev/null +++ b/components/sync/syncable/directory_cryptographer.cc
@@ -0,0 +1,359 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/sync/syncable/directory_cryptographer.h" + +#include <stddef.h> + +#include <algorithm> +#include <utility> + +#include "base/base64.h" +#include "base/logging.h" +#include "base/memory/ptr_util.h" +#include "components/sync/base/encryptor.h" +#include "components/sync/protocol/nigori_specifics.pb.h" + +namespace syncer { + +KeyParams::KeyParams(KeyDerivationParams derivation_params, + const std::string& password) + : derivation_params(derivation_params), password(password) {} + +KeyParams::KeyParams(const KeyParams& other) = default; +KeyParams::KeyParams(KeyParams&& other) = default; +KeyParams::~KeyParams() = default; + +CryptographerDataWithPendingKeys::CryptographerDataWithPendingKeys() = default; +CryptographerDataWithPendingKeys::CryptographerDataWithPendingKeys( + CryptographerDataWithPendingKeys&& other) = default; +CryptographerDataWithPendingKeys::~CryptographerDataWithPendingKeys() = default; + +DirectoryCryptographer::DirectoryCryptographer() + : key_bag_(NigoriKeyBag::CreateEmpty()) {} + +DirectoryCryptographer::~DirectoryCryptographer() {} + +void DirectoryCryptographer::CopyFrom(const DirectoryCryptographer& other) { + key_bag_.CopyFrom(other.key_bag_); + default_nigori_name_ = other.default_nigori_name_; + if (other.pending_keys_) { + pending_keys_ = + std::make_unique<sync_pb::EncryptedData>(*other.pending_keys_); + } +} + +void DirectoryCryptographer::InitFromCryptographerDataWithPendingKeys( + const CryptographerDataWithPendingKeys& serialized_state) { + std::unique_ptr<sync_pb::EncryptedData> pending_keys; + if (serialized_state.pending_keys.has_value()) { + pending_keys = std::make_unique<sync_pb::EncryptedData>( + *serialized_state.pending_keys); + } + CopyFrom(DirectoryCryptographer( + NigoriKeyBag::CreateFromProto( + serialized_state.cryptographer_data.key_bag()), + serialized_state.cryptographer_data.default_key_name(), + std::move(pending_keys))); +} + +CryptographerDataWithPendingKeys +DirectoryCryptographer::ToCryptographerDataWithPendingKeys() const { + CryptographerDataWithPendingKeys output; + *output.cryptographer_data.mutable_key_bag() = key_bag_.ToProto(); + output.cryptographer_data.set_default_key_name(default_nigori_name_); + if (pending_keys_) { + output.pending_keys = *pending_keys_; + } + return output; +} + +void DirectoryCryptographer::Bootstrap( + const Encryptor& encryptor, + const std::string& restored_bootstrap_token) { + if (is_initialized()) { + NOTREACHED(); + return; + } + + std::string serialized_nigori_key = + UnpackBootstrapToken(encryptor, restored_bootstrap_token); + if (serialized_nigori_key.empty()) + return; + ImportNigoriKey(serialized_nigori_key); +} + +std::unique_ptr<Cryptographer> DirectoryCryptographer::Clone() const { + auto cryptographer = base::WrapUnique(new DirectoryCryptographer()); + cryptographer->CopyFrom(*this); + return cryptographer; +} + +bool DirectoryCryptographer::CanEncrypt() const { + return is_initialized() && !has_pending_keys(); +} + +bool DirectoryCryptographer::CanDecrypt( + const sync_pb::EncryptedData& data) const { + return key_bag_.HasKey(data.key_name()); +} + +bool DirectoryCryptographer::CanDecryptUsingDefaultKey( + const sync_pb::EncryptedData& data) const { + return !default_nigori_name_.empty() && + data.key_name() == default_nigori_name_; +} + +bool DirectoryCryptographer::EncryptString( + const std::string& serialized, + sync_pb::EncryptedData* encrypted) const { + if (default_nigori_name_.empty()) { + LOG(ERROR) << "Cryptographer not ready, failed to encrypt."; + return false; + } + + if (CanDecryptUsingDefaultKey(*encrypted)) { + std::string original_serialized; + if (DecryptToString(*encrypted, &original_serialized) && + original_serialized == serialized) { + DVLOG(2) << "Re-encryption unnecessary, encrypted data already matches."; + return true; + } + } + + if (!key_bag_.HasKey(default_nigori_name_)) { + LOG(ERROR) << "Corrupt default key."; + return false; + } + + return key_bag_.EncryptWithKey(default_nigori_name_, serialized, encrypted); +} + +bool DirectoryCryptographer::DecryptToString( + const sync_pb::EncryptedData& encrypted, + std::string* decrypted) const { + return key_bag_.Decrypt(encrypted, decrypted); +} + +bool DirectoryCryptographer::has_pending_keys() const { + return nullptr != pending_keys_.get(); +} + +bool DirectoryCryptographer::GetKeys(sync_pb::EncryptedData* encrypted) const { + DCHECK(encrypted); + DCHECK_NE(size_t(0), key_bag_.size()); + + // Create a bag of all the Nigori parameters we know about. + sync_pb::NigoriKeyBag bag = key_bag_.ToProto(); + + // Encrypt the bag with the default Nigori. + return Encrypt(bag, encrypted); +} + +bool DirectoryCryptographer::AddKey(const KeyParams& params) { + return AddKeyImpl( + Nigori::CreateByDerivation(params.derivation_params, params.password), + /*set_as_default=*/true); +} + +bool DirectoryCryptographer::AddNonDefaultKey(const KeyParams& params) { + DCHECK(is_initialized()); + return AddKeyImpl( + Nigori::CreateByDerivation(params.derivation_params, params.password), + /*set_as_default=*/false); +} + +bool DirectoryCryptographer::AddKeyFromBootstrapToken( + const Encryptor& encryptor, + const std::string& restored_bootstrap_token) { + // Create the new Nigori and make it the default encryptor. + std::string serialized_nigori_key = + UnpackBootstrapToken(encryptor, restored_bootstrap_token); + return ImportNigoriKey(serialized_nigori_key); +} + +bool DirectoryCryptographer::AddKeyImpl(std::unique_ptr<Nigori> nigori, + bool set_as_default) { + DCHECK(nigori); + std::string key_name = key_bag_.AddKey(std::move(nigori)); + if (key_name.empty()) { + NOTREACHED(); + return false; + } + + // Check if the key we just added can decrypt the pending keys and add them + // too if so. + if (pending_keys_.get() && CanDecrypt(*pending_keys_)) { + sync_pb::NigoriKeyBag pending_bag; + Decrypt(*pending_keys_, &pending_bag); + InstallKeyBag(pending_bag); + SetDefaultKey(pending_keys_->key_name()); + pending_keys_.reset(); + } + + // The just-added key takes priority over the pending keys as default. + if (set_as_default) + SetDefaultKey(key_name); + return true; +} + +void DirectoryCryptographer::InstallKeys( + const sync_pb::EncryptedData& encrypted) { + DCHECK(CanDecrypt(encrypted)); + + sync_pb::NigoriKeyBag bag; + if (!Decrypt(encrypted, &bag)) + return; + InstallKeyBag(bag); +} + +void DirectoryCryptographer::SetDefaultKey(const std::string& key_name) { + DCHECK(key_bag_.HasKey(key_name)); + default_nigori_name_ = key_name; +} + +bool DirectoryCryptographer::is_initialized() const { + return !default_nigori_name_.empty(); +} + +void DirectoryCryptographer::SetPendingKeys( + const sync_pb::EncryptedData& encrypted) { + DCHECK(!CanDecrypt(encrypted)); + DCHECK(!encrypted.blob().empty()); + pending_keys_ = std::make_unique<sync_pb::EncryptedData>(encrypted); +} + +const sync_pb::EncryptedData& DirectoryCryptographer::GetPendingKeys() const { + DCHECK(has_pending_keys()); + return *(pending_keys_.get()); +} + +bool DirectoryCryptographer::DecryptPendingKeys(const KeyParams& params) { + DCHECK_NE(KeyDerivationMethod::UNSUPPORTED, + params.derivation_params.method()); + + std::unique_ptr<Nigori> nigori = + Nigori::CreateByDerivation(params.derivation_params, params.password); + + std::string plaintext; + if (!nigori->Decrypt(pending_keys_->blob(), &plaintext)) + return false; + + sync_pb::NigoriKeyBag bag; + if (!bag.ParseFromString(plaintext)) { + NOTREACHED(); + return false; + } + InstallKeyBag(bag); + const std::string& new_default_key_name = pending_keys_->key_name(); + SetDefaultKey(new_default_key_name); + pending_keys_.reset(); + return true; +} + +bool DirectoryCryptographer::GetBootstrapToken(const Encryptor& encryptor, + std::string* token) const { + DCHECK(token); + std::string unencrypted_token = GetDefaultNigoriKeyData(); + if (unencrypted_token.empty()) + return false; + + std::string encrypted_token; + if (!encryptor.EncryptString(unencrypted_token, &encrypted_token)) { + return false; + } + + base::Base64Encode(encrypted_token, token); + + return true; +} + +std::string DirectoryCryptographer::UnpackBootstrapToken( + const Encryptor& encryptor, + const std::string& token) const { + if (token.empty()) + return std::string(); + + std::string encrypted_data; + if (!base::Base64Decode(token, &encrypted_data)) { + DLOG(WARNING) << "Could not decode token."; + return std::string(); + } + + std::string unencrypted_token; + if (!encryptor.DecryptString(encrypted_data, &unencrypted_token)) { + DLOG(WARNING) << "Decryption of bootstrap token failed."; + return std::string(); + } + return unencrypted_token; +} + +void DirectoryCryptographer::InstallKeyBag(const sync_pb::NigoriKeyBag& bag) { + key_bag_.AddAllUnknownKeysFrom(NigoriKeyBag::CreateFromProto(bag)); +} + +bool DirectoryCryptographer::KeybagIsStale( + const sync_pb::EncryptedData& encrypted_bag) const { + if (!CanEncrypt()) + return false; + if (encrypted_bag.blob().empty()) + return true; + if (!CanDecrypt(encrypted_bag)) + return false; + if (!CanDecryptUsingDefaultKey(encrypted_bag)) + return true; + sync_pb::NigoriKeyBag bag; + if (!Decrypt(encrypted_bag, &bag)) { + LOG(ERROR) << "Failed to decrypt keybag for stale check. " + << "Assuming keybag is corrupted."; + return true; + } + if (static_cast<size_t>(bag.key_size()) < key_bag_.size()) + return true; + return false; +} + +std::string DirectoryCryptographer::GetDefaultEncryptionKeyName() const { + return default_nigori_name_; +} + +std::string DirectoryCryptographer::GetDefaultNigoriKeyData() const { + if (!is_initialized()) + return std::string(); + sync_pb::NigoriKey key = key_bag_.ExportKey(default_nigori_name_); + key.clear_name(); + return key.SerializeAsString(); +} + +bool DirectoryCryptographer::ImportNigoriKey( + const std::string& serialized_nigori_key) { + if (serialized_nigori_key.empty()) + return false; + + sync_pb::NigoriKey key; + if (!key.ParseFromString(serialized_nigori_key)) + return false; + + std::unique_ptr<Nigori> nigori = Nigori::CreateByImport( + key.user_key(), key.encryption_key(), key.mac_key()); + + if (!nigori) { + DLOG(ERROR) << "Ignoring invalid Nigori when importing"; + return false; + } + + if (!AddKeyImpl(std::move(nigori), true)) + return false; + return true; +} + +DirectoryCryptographer::DirectoryCryptographer( + NigoriKeyBag key_bag, + const std::string& default_nigori_name, + std::unique_ptr<sync_pb::EncryptedData> pending_keys) + : key_bag_(std::move(key_bag)), + default_nigori_name_(std::move(default_nigori_name)), + pending_keys_(std::move(pending_keys)) {} + +} // namespace syncer
diff --git a/components/sync/syncable/directory_cryptographer.h b/components/sync/syncable/directory_cryptographer.h new file mode 100644 index 0000000..9f9c058b --- /dev/null +++ b/components/sync/syncable/directory_cryptographer.h
@@ -0,0 +1,219 @@ +// Copyright 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_SYNC_SYNCABLE_DIRECTORY_CRYPTOGRAPHER_H_ +#define COMPONENTS_SYNC_SYNCABLE_DIRECTORY_CRYPTOGRAPHER_H_ + +#include <map> +#include <memory> +#include <string> + +#include "base/macros.h" +#include "base/optional.h" +#include "components/sync/base/passphrase_enums.h" +#include "components/sync/nigori/cryptographer.h" +#include "components/sync/nigori/nigori.h" +#include "components/sync/nigori/nigori_key_bag.h" +#include "components/sync/protocol/encryption.pb.h" +#include "components/sync/protocol/nigori_local_data.pb.h" + +namespace sync_pb { +class NigoriKeyBag; +} // namespace sync_pb + +namespace syncer { + +class Encryptor; + +// The parameters used to initialize a Nigori instance. +// TODO(davidovic): Stop relying on KeyParams and inline it, because it's now +// just a pair of KeyDerivationParams and passphrase. +struct KeyParams { + KeyParams(KeyDerivationParams derivation_params, const std::string& password); + KeyParams(const KeyParams& other); + KeyParams(KeyParams&& other); + ~KeyParams(); + + KeyDerivationParams derivation_params; + std::string password; +}; + +struct CryptographerDataWithPendingKeys { + CryptographerDataWithPendingKeys(); + CryptographerDataWithPendingKeys(CryptographerDataWithPendingKeys&& other); + ~CryptographerDataWithPendingKeys(); + + sync_pb::CryptographerData cryptographer_data; + base::Optional<sync_pb::EncryptedData> pending_keys; + + private: + DISALLOW_COPY_AND_ASSIGN(CryptographerDataWithPendingKeys); +}; + +// This class manages the Nigori objects used to encrypt and decrypt sensitive +// sync data (eg. passwords). Each Nigori object knows how to handle data +// protected with a particular passphrase. +// +// Whenever an update to the Nigori sync node is received from the server, +// SetPendingKeys should be called with the encrypted contents of that node. +// Most likely, an updated Nigori node means that a new passphrase has been set +// and that future node updates won't be decryptable. To remedy this, the user +// should be prompted for the new passphrase and DecryptPendingKeys be called. +// +// Whenever a update to an encrypted node is received from the server, +// CanDecrypt should be used to verify whether the Cryptographer can decrypt +// that node. If it cannot, then the application of that update should be +// delayed until after it can be decrypted. +class DirectoryCryptographer : public Cryptographer { + public: + DirectoryCryptographer(); + ~DirectoryCryptographer() override; + + void CopyFrom(const DirectoryCryptographer& other); + + // Deserialization. + void InitFromCryptographerDataWithPendingKeys( + const CryptographerDataWithPendingKeys& serialized_state); + + // Serialization. + CryptographerDataWithPendingKeys ToCryptographerDataWithPendingKeys() const; + + // |restored_bootstrap_token| can be provided via this method to bootstrap + // Cryptographer instance into the ready state (is_ready will be true). + // It must be a string that was previously built by the + // GetSerializedBootstrapToken function. It is possible that the token is no + // longer valid (due to server key change), in which case the normal + // decryption code paths will fail and the user will need to provide a new + // passphrase. + // It is an error to call this if is_ready() == true, though it is fair to + // never call Bootstrap at all. + void Bootstrap(const Encryptor& encryptor, + const std::string& restored_bootstrap_token); + + // Returns whether |encrypted| can be decrypted using the default encryption + // key. + bool CanDecryptUsingDefaultKey(const sync_pb::EncryptedData& encrypted) const; + + // Encrypts the set of currently known keys into |encrypted|. Returns true if + // successful. + bool GetKeys(sync_pb::EncryptedData* encrypted) const; + + // Creates a new Nigori instance using |params|. If successful, |params| will + // become the default encryption key and be used for all future calls to + // Encrypt. + // Will decrypt the pending keys and install them if possible (pending key + // will not overwrite default). + bool AddKey(const KeyParams& params); + + // Same as AddKey(..), but builds the new Nigori from a previously persisted + // bootstrap token. This can be useful when consuming a bootstrap token + // with a cryptographer that has already been initialized. + // Updates the default key. + // Will decrypt the pending keys and install them if possible (pending key + // will not overwrite default). + bool AddKeyFromBootstrapToken(const Encryptor& encryptor, + const std::string& restored_bootstrap_token); + + // Creates a new Nigori instance using |params|. If successful, |params| + // will be added to the nigori keybag, but will not be the default encryption + // key (default_nigori_ will remain the same). + // Prereq: is_initialized() must be true. + // Will decrypt the pending keys and install them if possible (pending key + // will become the new default). + bool AddNonDefaultKey(const KeyParams& params); + + // Decrypts |encrypted| and uses its contents to initialize Nigori instances. + // Returns true unless decryption of |encrypted| fails. The caller is + // responsible for checking that CanDecrypt(encrypted) == true. + // Does not modify the default key. + void InstallKeys(const sync_pb::EncryptedData& encrypted); + + // Makes a local copy of |encrypted| to later be decrypted by + // DecryptPendingKeys. This should only be used if CanDecrypt(encrypted) == + // false. + void SetPendingKeys(const sync_pb::EncryptedData& encrypted); + + // Makes |pending_keys_| available to callers that may want to cache its + // value for later use on the UI thread. It is illegal to call this if the + // cryptographer has no pending keys. Like other calls that access the + // cryptographer, this method must be called from within a transaction. + const sync_pb::EncryptedData& GetPendingKeys() const; + + // Attempts to decrypt the set of keys that was copied in the previous call to + // SetPendingKeys using |params|. Returns true if the pending keys were + // successfully decrypted and installed. If successful, the default key + // is updated. + bool DecryptPendingKeys(const KeyParams& params); + + // Sets the default key to the nigori with name |key_name|. |key_name| must + // correspond to a nigori that has already been installed into the keybag. + void SetDefaultKey(const std::string& key_name); + + bool is_initialized() const; + + // Obtain a token that can be provided on construction to a future + // Cryptographer instance to bootstrap itself. Returns false if such a token + // can't be created (i.e. if this Cryptograhper doesn't have valid keys). + bool GetBootstrapToken(const Encryptor& encryptor, std::string* token) const; + + // Returns true if |keybag| is decryptable and either is a subset of + // |key_bag_| and/or has a different default key. + bool KeybagIsStale(const sync_pb::EncryptedData& keybag) const; + + // Returns the name of the Nigori key currently used for encryption. + std::string GetDefaultEncryptionKeyName() const override; + + // Returns a serialized sync_pb::NigoriKey version of current default + // encryption key. Returns empty string if Cryptographer is not initialized + // or protobuf serialization error occurs. + std::string GetDefaultNigoriKeyData() const; + + // Generates a new Nigori from |serialized_nigori_key|, and if successful + // installs the new nigori as the default key. + bool ImportNigoriKey(const std::string& serialized_nigori_key); + + // Cryptographer overrides. + std::unique_ptr<Cryptographer> Clone() const override; + bool CanEncrypt() const override; + bool CanDecrypt(const sync_pb::EncryptedData& encrypted) const override; + bool EncryptString(const std::string& serialized, + sync_pb::EncryptedData* encrypted) const override; + bool DecryptToString(const sync_pb::EncryptedData& encrypted, + std::string* decrypted) const override; + bool has_pending_keys() const override; + + private: + // Initializes cryptographer with completely provided state. + DirectoryCryptographer(NigoriKeyBag key_bag, + const std::string& default_nigori_name, + std::unique_ptr<sync_pb::EncryptedData> pending_keys); + + // Helper method to instantiate Nigori instances for each set of key + // parameters in |bag|. + // Does not update the default nigori. + void InstallKeyBag(const sync_pb::NigoriKeyBag& bag); + + // Helper method to add a nigori to the keybag, optionally making it the + // default as well. + bool AddKeyImpl(std::unique_ptr<Nigori> nigori, bool set_as_default); + + // Helper to unencrypt a bootstrap token into a serialized sync_pb::NigoriKey. + std::string UnpackBootstrapToken(const Encryptor& encryptor, + const std::string& token) const; + + // The actual keys we know about. + NigoriKeyBag key_bag_; + + // The key name associated with the default nigori. If non-empty, must + // correspond to a nigori within |key_bag_|. + std::string default_nigori_name_; + + std::unique_ptr<sync_pb::EncryptedData> pending_keys_; + + DISALLOW_ASSIGN(DirectoryCryptographer); +}; + +} // namespace syncer + +#endif // COMPONENTS_SYNC_SYNCABLE_DIRECTORY_CRYPTOGRAPHER_H_
diff --git a/components/sync/nigori/cryptographer_unittest.cc b/components/sync/syncable/directory_cryptographer_unittest.cc similarity index 83% rename from components/sync/nigori/cryptographer_unittest.cc rename to components/sync/syncable/directory_cryptographer_unittest.cc index 9e0224ac..737d1a3 100644 --- a/components/sync/nigori/cryptographer_unittest.cc +++ b/components/sync/syncable/directory_cryptographer_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/sync/nigori/cryptographer.h" +#include "components/sync/syncable/directory_cryptographer.h" #include "base/strings/string_util.h" #include "components/sync/base/fake_encryptor.h" @@ -22,16 +22,16 @@ } // namespace -class CryptographerTest : public ::testing::Test { +class DirectoryCryptographerTest : public ::testing::Test { protected: - CryptographerTest() = default; + DirectoryCryptographerTest() = default; FakeEncryptor encryptor_; - Cryptographer cryptographer_; + DirectoryCryptographer cryptographer_; }; -TEST_F(CryptographerTest, EmptyCantDecrypt) { - EXPECT_FALSE(cryptographer_.is_ready()); +TEST_F(DirectoryCryptographerTest, EmptyCantDecrypt) { + EXPECT_FALSE(cryptographer_.CanEncrypt()); sync_pb::EncryptedData encrypted; encrypted.set_key_name("foo"); @@ -40,18 +40,18 @@ EXPECT_FALSE(cryptographer_.CanDecrypt(encrypted)); } -TEST_F(CryptographerTest, EmptyCantEncrypt) { - EXPECT_FALSE(cryptographer_.is_ready()); +TEST_F(DirectoryCryptographerTest, EmptyCantEncrypt) { + EXPECT_FALSE(cryptographer_.CanEncrypt()); sync_pb::EncryptedData encrypted; sync_pb::PasswordSpecificsData original; EXPECT_FALSE(cryptographer_.Encrypt(original, &encrypted)); } -TEST_F(CryptographerTest, MissingCantDecrypt) { +TEST_F(DirectoryCryptographerTest, MissingCantDecrypt) { KeyParams params = {KeyDerivationParams::CreateForPbkdf2(), "dummy"}; cryptographer_.AddKey(params); - EXPECT_TRUE(cryptographer_.is_ready()); + EXPECT_TRUE(cryptographer_.CanEncrypt()); sync_pb::EncryptedData encrypted; encrypted.set_key_name("foo"); @@ -60,10 +60,10 @@ EXPECT_FALSE(cryptographer_.CanDecrypt(encrypted)); } -TEST_F(CryptographerTest, CanEncryptAndDecrypt) { +TEST_F(DirectoryCryptographerTest, CanEncryptAndDecrypt) { KeyParams params = {KeyDerivationParams::CreateForPbkdf2(), "dummy"}; EXPECT_TRUE(cryptographer_.AddKey(params)); - EXPECT_TRUE(cryptographer_.is_ready()); + EXPECT_TRUE(cryptographer_.CanEncrypt()); sync_pb::PasswordSpecificsData original; original.set_origin("http://example.com"); @@ -79,10 +79,10 @@ EXPECT_EQ(original.SerializeAsString(), decrypted.SerializeAsString()); } -TEST_F(CryptographerTest, EncryptOnlyIfDifferent) { +TEST_F(DirectoryCryptographerTest, EncryptOnlyIfDifferent) { KeyParams params = {KeyDerivationParams::CreateForPbkdf2(), "dummy"}; EXPECT_TRUE(cryptographer_.AddKey(params)); - EXPECT_TRUE(cryptographer_.is_ready()); + EXPECT_TRUE(cryptographer_.CanEncrypt()); sync_pb::PasswordSpecificsData original; original.set_origin("http://example.com"); @@ -110,10 +110,10 @@ EXPECT_EQ(original.SerializeAsString(), decrypted.SerializeAsString()); } -TEST_F(CryptographerTest, AddKeySetsDefault) { +TEST_F(DirectoryCryptographerTest, AddKeySetsDefault) { KeyParams params1 = {KeyDerivationParams::CreateForPbkdf2(), "dummy1"}; EXPECT_TRUE(cryptographer_.AddKey(params1)); - EXPECT_TRUE(cryptographer_.is_ready()); + EXPECT_TRUE(cryptographer_.CanEncrypt()); sync_pb::PasswordSpecificsData original; original.set_origin("http://example.com"); @@ -127,7 +127,7 @@ KeyParams params2 = {KeyDerivationParams::CreateForPbkdf2(), "dummy2"}; EXPECT_TRUE(cryptographer_.AddKey(params2)); - EXPECT_TRUE(cryptographer_.is_ready()); + EXPECT_TRUE(cryptographer_.CanEncrypt()); sync_pb::EncryptedData encrypted3; EXPECT_TRUE(cryptographer_.Encrypt(original, &encrypted3)); @@ -139,7 +139,7 @@ EXPECT_EQ(encrypted3.key_name(), encrypted4.key_name()); } -TEST_F(CryptographerTest, EncryptExportDecrypt) { +TEST_F(DirectoryCryptographerTest, EncryptExportDecrypt) { sync_pb::EncryptedData nigori; sync_pb::EncryptedData encrypted; @@ -149,27 +149,27 @@ original.set_password_value("hunter2"); { - Cryptographer cryptographer; + DirectoryCryptographer cryptographer; KeyParams params = {KeyDerivationParams::CreateForPbkdf2(), "dummy"}; cryptographer.AddKey(params); - EXPECT_TRUE(cryptographer.is_ready()); + EXPECT_TRUE(cryptographer.CanEncrypt()); EXPECT_TRUE(cryptographer.Encrypt(original, &encrypted)); EXPECT_TRUE(cryptographer.GetKeys(&nigori)); } { - Cryptographer cryptographer; + DirectoryCryptographer cryptographer; EXPECT_FALSE(cryptographer.CanDecrypt(nigori)); cryptographer.SetPendingKeys(nigori); - EXPECT_FALSE(cryptographer.is_ready()); + EXPECT_FALSE(cryptographer.CanEncrypt()); EXPECT_TRUE(cryptographer.has_pending_keys()); KeyParams params = {KeyDerivationParams::CreateForPbkdf2(), "dummy"}; EXPECT_TRUE(cryptographer.DecryptPendingKeys(params)); - EXPECT_TRUE(cryptographer.is_ready()); + EXPECT_TRUE(cryptographer.CanEncrypt()); EXPECT_FALSE(cryptographer.has_pending_keys()); sync_pb::PasswordSpecificsData decrypted; @@ -178,7 +178,7 @@ } } -TEST_F(CryptographerTest, Bootstrap) { +TEST_F(DirectoryCryptographerTest, Bootstrap) { KeyParams params = {KeyDerivationParams::CreateForPbkdf2(), "dummy"}; cryptographer_.AddKey(params); @@ -186,9 +186,9 @@ EXPECT_TRUE(cryptographer_.GetBootstrapToken(encryptor_, &token)); EXPECT_TRUE(base::IsStringUTF8(token)); - Cryptographer other_cryptographer; + DirectoryCryptographer other_cryptographer; other_cryptographer.Bootstrap(encryptor_, token); - EXPECT_TRUE(other_cryptographer.is_ready()); + EXPECT_TRUE(other_cryptographer.CanEncrypt()); const char secret[] = "secret"; sync_pb::EncryptedData encrypted; @@ -203,7 +203,7 @@ // // Then copy the original cryptographer and ensure it can also decrypt these // items and encrypt them with the most recent key. -TEST_F(CryptographerTest, CopyConstructor) { +TEST_F(DirectoryCryptographerTest, CopyConstructor) { sync_pb::PasswordSpecificsData original; original.set_origin("http://example.com"); original.set_username_value("luser"); @@ -212,14 +212,14 @@ // Start by testing the original cryptogprapher. KeyParams params1 = {KeyDerivationParams::CreateForPbkdf2(), "dummy"}; EXPECT_TRUE(cryptographer_.AddKey(params1)); - EXPECT_TRUE(cryptographer_.is_ready()); + EXPECT_TRUE(cryptographer_.CanEncrypt()); sync_pb::EncryptedData encrypted_k1; EXPECT_TRUE(cryptographer_.Encrypt(original, &encrypted_k1)); KeyParams params2 = {KeyDerivationParams::CreateForPbkdf2(), "fatuous"}; EXPECT_TRUE(cryptographer_.AddKey(params2)); - EXPECT_TRUE(cryptographer_.is_ready()); + EXPECT_TRUE(cryptographer_.CanEncrypt()); sync_pb::EncryptedData encrypted_k2; EXPECT_TRUE(cryptographer_.Encrypt(original, &encrypted_k2)); @@ -233,13 +233,13 @@ EXPECT_EQ(original.SerializeAsString(), decrypted_k2.SerializeAsString()); // Clone the cryptographer and test that it behaves the same. - Cryptographer cryptographer_clone(cryptographer_); + std::unique_ptr<Cryptographer> cryptographer_clone = cryptographer_.Clone(); // The clone should be able to decrypt with old and new keys. sync_pb::PasswordSpecificsData decrypted_k1_clone; sync_pb::PasswordSpecificsData decrypted_k2_clone; - EXPECT_TRUE(cryptographer_clone.Decrypt(encrypted_k1, &decrypted_k1_clone)); - EXPECT_TRUE(cryptographer_clone.Decrypt(encrypted_k2, &decrypted_k2_clone)); + EXPECT_TRUE(cryptographer_clone->Decrypt(encrypted_k1, &decrypted_k1_clone)); + EXPECT_TRUE(cryptographer_clone->Decrypt(encrypted_k2, &decrypted_k2_clone)); EXPECT_EQ(original.SerializeAsString(), decrypted_k1_clone.SerializeAsString()); @@ -249,7 +249,7 @@ // The old cryptographer should be able to decrypt things encrypted by the // new. sync_pb::EncryptedData encrypted_c; - EXPECT_TRUE(cryptographer_clone.Encrypt(original, &encrypted_c)); + EXPECT_TRUE(cryptographer_clone->Encrypt(original, &encrypted_c)); sync_pb::PasswordSpecificsData decrypted_c; EXPECT_TRUE(cryptographer_.Decrypt(encrypted_c, &decrypted_c)); @@ -262,7 +262,7 @@ // Test verifies that GetBootstrapToken/Bootstrap only transfers default // key. Additional call to GetKeys/InstallKeys is needed to transfer keybag // to decrypt messages encrypted with old keys. -TEST_F(CryptographerTest, GetKeysThenInstall) { +TEST_F(DirectoryCryptographerTest, GetKeysThenInstall) { sync_pb::PasswordSpecificsData original; original.set_origin("http://example.com"); original.set_username_value("luser"); @@ -271,20 +271,20 @@ // First, encrypt the same value using two different keys. KeyParams params1 = {KeyDerivationParams::CreateForPbkdf2(), "dummy"}; EXPECT_TRUE(cryptographer_.AddKey(params1)); - EXPECT_TRUE(cryptographer_.is_ready()); + EXPECT_TRUE(cryptographer_.CanEncrypt()); sync_pb::EncryptedData encrypted_k1; EXPECT_TRUE(cryptographer_.Encrypt(original, &encrypted_k1)); KeyParams params2 = {KeyDerivationParams::CreateForPbkdf2(), "dummy2"}; EXPECT_TRUE(cryptographer_.AddKey(params2)); - EXPECT_TRUE(cryptographer_.is_ready()); + EXPECT_TRUE(cryptographer_.CanEncrypt()); sync_pb::EncryptedData encrypted_k2; EXPECT_TRUE(cryptographer_.Encrypt(original, &encrypted_k2)); // Then construct second cryptographer and bootstrap it from the first one. - Cryptographer another_cryptographer; + DirectoryCryptographer another_cryptographer; std::string bootstrap_token; EXPECT_TRUE(cryptographer_.GetBootstrapToken(encryptor_, &bootstrap_token)); another_cryptographer.Bootstrap(encryptor_, bootstrap_token); @@ -305,7 +305,8 @@ EXPECT_TRUE(another_cryptographer.CanDecrypt(encrypted_k2)); } -TEST_F(CryptographerTest, ShouldConvertToCryptographerDataWithPendingKeys) { +TEST_F(DirectoryCryptographerTest, + ShouldConvertToCryptographerDataWithPendingKeys) { const KeyParams kKeyParams = {KeyDerivationParams::CreateForPbkdf2(), "password1"}; ASSERT_TRUE(cryptographer_.AddKey(kKeyParams));
diff --git a/components/sync/syncable/nigori_handler.h b/components/sync/syncable/nigori_handler.h index a437273..7241b15 100644 --- a/components/sync/syncable/nigori_handler.h +++ b/components/sync/syncable/nigori_handler.h
@@ -16,6 +16,7 @@ namespace syncer { class Cryptographer; +class DirectoryCryptographer; enum class PassphraseType; namespace syncable { @@ -45,6 +46,11 @@ virtual const Cryptographer* GetCryptographer( const syncable::BaseTransaction* const trans) const = 0; + // Returns the full-blown DirectoryCryptographer API, available only if the + // legacy directory-based implementation of NIGORI is active. + virtual const DirectoryCryptographer* GetDirectoryCryptographerForNigori( + const syncable::BaseTransaction* const trans) const = 0; + // Returns the set of currently encrypted types. virtual ModelTypeSet GetEncryptedTypes( const syncable::BaseTransaction* const trans) const = 0;
diff --git a/components/sync/syncable/nigori_handler_proxy.cc b/components/sync/syncable/nigori_handler_proxy.cc index 86ad6a50..88c5213d 100644 --- a/components/sync/syncable/nigori_handler_proxy.cc +++ b/components/sync/syncable/nigori_handler_proxy.cc
@@ -4,6 +4,7 @@ #include "components/sync/syncable/nigori_handler_proxy.h" +#include "components/sync/syncable/directory_cryptographer.h" #include "components/sync/syncable/syncable_base_transaction.h" #include "components/sync/syncable/user_share.h" #include "components/sync/syncable/write_transaction.h" @@ -14,6 +15,7 @@ NigoriHandlerProxy::NigoriHandlerProxy(UserShare* user_share) : user_share_(user_share), + cryptographer_(std::make_unique<DirectoryCryptographer>()), encrypted_types_(SyncEncryptionHandler::SensitiveTypes()), passphrase_type_(SyncEncryptionHandler::kInitialPassphraseType) { DCHECK(user_share); @@ -55,7 +57,7 @@ Cryptographer* cryptographer) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); syncer::WriteTransaction trans(FROM_HERE, user_share_); - cryptographer_.CopyFrom(*cryptographer); + cryptographer_ = cryptographer->Clone(); } void NigoriHandlerProxy::OnPassphraseTypeChanged(PassphraseType type, @@ -81,7 +83,14 @@ const Cryptographer* NigoriHandlerProxy::GetCryptographer( const syncable::BaseTransaction* const trans) const { DCHECK_EQ(user_share_->directory.get(), trans->directory()); - return &cryptographer_; + DCHECK(cryptographer_); + return cryptographer_.get(); +} + +const DirectoryCryptographer* +NigoriHandlerProxy::GetDirectoryCryptographerForNigori( + const syncable::BaseTransaction* const trans) const { + return nullptr; } ModelTypeSet NigoriHandlerProxy::GetEncryptedTypes(
diff --git a/components/sync/syncable/nigori_handler_proxy.h b/components/sync/syncable/nigori_handler_proxy.h index b4b397c4..d9df74a 100644 --- a/components/sync/syncable/nigori_handler_proxy.h +++ b/components/sync/syncable/nigori_handler_proxy.h
@@ -5,6 +5,7 @@ #ifndef COMPONENTS_SYNC_SYNCABLE_NIGORI_HANDLER_PROXY_H_ #define COMPONENTS_SYNC_SYNCABLE_NIGORI_HANDLER_PROXY_H_ +#include <memory> #include <string> #include "base/macros.h" @@ -59,6 +60,8 @@ const syncable::BaseTransaction* const trans) const override; const Cryptographer* GetCryptographer( const syncable::BaseTransaction* const trans) const override; + const DirectoryCryptographer* GetDirectoryCryptographerForNigori( + const syncable::BaseTransaction* const trans) const override; ModelTypeSet GetEncryptedTypes( const syncable::BaseTransaction* const trans) const override; PassphraseType GetPassphraseType( @@ -67,7 +70,7 @@ private: UserShare* user_share_; - Cryptographer cryptographer_; + std::unique_ptr<Cryptographer> cryptographer_; ModelTypeSet encrypted_types_; PassphraseType passphrase_type_;
diff --git a/components/sync/syncable/nigori_util.cc b/components/sync/syncable/nigori_util.cc index 5f4477c..4d2fb24 100644 --- a/components/sync/syncable/nigori_util.cc +++ b/components/sync/syncable/nigori_util.cc
@@ -25,13 +25,22 @@ namespace syncer { namespace syncable { +namespace { + +bool CanDecryptUsingDefaultKey(const Cryptographer& cryptographer, + const sync_pb::EncryptedData& encrypted) { + return !encrypted.key_name().empty() && + encrypted.key_name() == cryptographer.GetDefaultEncryptionKeyName(); +} + +} // namespace bool ProcessUnsyncedChangesForEncryption(WriteTransaction* const trans) { NigoriHandler* nigori_handler = trans->directory()->GetNigoriHandler(); ModelTypeSet encrypted_types = nigori_handler->GetEncryptedTypes(trans); const Cryptographer* cryptographer = trans->directory()->GetCryptographer(trans); - DCHECK(cryptographer->is_ready()); + DCHECK(cryptographer->CanEncrypt()); // Get list of all datatypes with unsynced changes. It's possible that our // local changes need to be encrypted if encryption for that datatype was @@ -139,7 +148,7 @@ if (specifics.has_encrypted()) { if (child.GetNonUniqueName() != kEncryptedString) return false; - if (!cryptographer->CanDecryptUsingDefaultKey(specifics.encrypted())) + if (!CanDecryptUsingDefaultKey(*cryptographer, specifics.encrypted())) return false; } } @@ -169,10 +178,14 @@ NOTREACHED() << "New specifics already has an encrypted blob."; return false; } - if ((!SpecificsNeedsEncryption(encrypted_types, new_specifics) && - !was_encrypted) || - !cryptographer || !cryptographer->is_initialized()) { - // No encryption required or we are unable to encrypt. + if (!SpecificsNeedsEncryption(encrypted_types, new_specifics) && + !was_encrypted) { + // No encryption required. + generated_specifics.CopyFrom(new_specifics); + } else if (!cryptographer || !cryptographer->CanEncrypt()) { + // We are currently unable to encrypt, so store unencrypted. The data will + // be reencrypted when the encryption key becomes available, via + // SyncEncryptionHandlerImpl::ReEncryptEverything(). generated_specifics.CopyFrom(new_specifics); } else { // Encrypt new_specifics into generated_specifics.
diff --git a/components/sync/syncable/test_user_share.cc b/components/sync/syncable/test_user_share.cc index 8c2140c..78cc401 100644 --- a/components/sync/syncable/test_user_share.cc +++ b/components/sync/syncable/test_user_share.cc
@@ -58,7 +58,7 @@ return true; } -Cryptographer* TestUserShare::GetCryptographer( +DirectoryCryptographer* TestUserShare::GetCryptographer( const syncable::BaseTransaction* trans) { return dir_maker_->GetCryptographer(trans); }
diff --git a/components/sync/syncable/test_user_share.h b/components/sync/syncable/test_user_share.h index b60da8c6..dc5654d 100644 --- a/components/sync/syncable/test_user_share.h +++ b/components/sync/syncable/test_user_share.h
@@ -15,7 +15,7 @@ namespace syncer { -class Cryptographer; +class DirectoryCryptographer; class KeystoreKeysHandler; class SyncEncryptionHandler; class TestDirectorySetterUpper; @@ -67,7 +67,8 @@ // Save and reload Directory to clear out temporary data in memory. bool Reload(); - Cryptographer* GetCryptographer(const syncable::BaseTransaction* trans); + DirectoryCryptographer* GetCryptographer( + const syncable::BaseTransaction* trans); // Non-null iff called between a call to SetUp() and TearDown(). UserShare* user_share();
diff --git a/components/sync/test/engine/mock_connection_manager.cc b/components/sync/test/engine/mock_connection_manager.cc index cec1ac5..fc954be 100644 --- a/components/sync/test/engine/mock_connection_manager.cc +++ b/components/sync/test/engine/mock_connection_manager.cc
@@ -146,7 +146,6 @@ } bool result = true; EXPECT_TRUE(!store_birthday_sent_ || post.has_store_birthday() || - post.message_contents() == ClientToServerMessage::AUTHENTICATE || post.message_contents() == ClientToServerMessage::CLEAR_SERVER_DATA); store_birthday_sent_ = true;
diff --git a/components/sync/test/engine/mock_connection_manager.h b/components/sync/test/engine/mock_connection_manager.h index 4640e9f..011dadb 100644 --- a/components/sync/test/engine/mock_connection_manager.h +++ b/components/sync/test/engine/mock_connection_manager.h
@@ -371,11 +371,6 @@ // The keystore key we return for a GetUpdates with need_encryption_key set. std::string keystore_key_; - // The AUTHENTICATE response we'll return for auth requests. - sync_pb::AuthenticateResponse auth_response_; - // What we use to determine if we should return SUCCESS or BAD_AUTH_TOKEN. - std::string valid_access_token_; - // Whether we are faking a server mandating clients to throttle requests. // Protected by |response_code_override_lock_|. bool throttling_;
diff --git a/components/sync/test/engine/test_directory_setter_upper.cc b/components/sync/test/engine/test_directory_setter_upper.cc index 8d6ecc7..7e15897 100644 --- a/components/sync/test/engine/test_directory_setter_upper.cc +++ b/components/sync/test/engine/test_directory_setter_upper.cc
@@ -78,7 +78,7 @@ directory()->FullyCheckTreeInvariants(&trans); } -Cryptographer* TestDirectorySetterUpper::GetCryptographer( +DirectoryCryptographer* TestDirectorySetterUpper::GetCryptographer( const syncable::BaseTransaction* trans) { DCHECK_EQ(directory_.get(), trans->directory()); return encryption_handler_.GetMutableCryptographer();
diff --git a/components/sync/test/engine/test_directory_setter_upper.h b/components/sync/test/engine/test_directory_setter_upper.h index a7cf5b7b1..9d7a8b8 100644 --- a/components/sync/test/engine/test_directory_setter_upper.h +++ b/components/sync/test/engine/test_directory_setter_upper.h
@@ -65,7 +65,8 @@ virtual void TearDown(); // Returns mutable version of Cryptographer owned by |encryption_handler_|. - Cryptographer* GetCryptographer(const syncable::BaseTransaction* trans); + DirectoryCryptographer* GetCryptographer( + const syncable::BaseTransaction* trans); syncable::Directory* directory() { return directory_.get(); }
diff --git a/components/sync/test/fake_sync_encryption_handler.cc b/components/sync/test/fake_sync_encryption_handler.cc index ab37d9f..31afc99 100644 --- a/components/sync/test/fake_sync_encryption_handler.cc +++ b/components/sync/test/fake_sync_encryption_handler.cc
@@ -45,7 +45,7 @@ observer.OnPassphraseRequired(REASON_DECRYPTION, KeyDerivationParams::CreateForPbkdf2(), pending_keys); - } else if (!cryptographer_.is_ready()) { + } else if (!cryptographer_.CanEncrypt()) { DVLOG(1) << "OnPassphraseRequired sent because cryptographer is not " << "ready"; for (auto& observer : observers_) { @@ -90,6 +90,12 @@ return &cryptographer_; } +const DirectoryCryptographer* +FakeSyncEncryptionHandler::GetDirectoryCryptographerForNigori( + const syncable::BaseTransaction* const trans) const { + return &cryptographer_; +} + ModelTypeSet FakeSyncEncryptionHandler::GetEncryptedTypes( const syncable::BaseTransaction* const trans) const { return encrypted_types_; @@ -139,7 +145,7 @@ return this; } -Cryptographer* FakeSyncEncryptionHandler::GetMutableCryptographer() { +DirectoryCryptographer* FakeSyncEncryptionHandler::GetMutableCryptographer() { return &cryptographer_; }
diff --git a/components/sync/test/fake_sync_encryption_handler.h b/components/sync/test/fake_sync_encryption_handler.h index da420dc1..4a341b1 100644 --- a/components/sync/test/fake_sync_encryption_handler.h +++ b/components/sync/test/fake_sync_encryption_handler.h
@@ -12,8 +12,8 @@ #include "base/observer_list.h" #include "base/time/time.h" #include "components/sync/engine/sync_encryption_handler.h" -#include "components/sync/nigori/cryptographer.h" #include "components/sync/nigori/keystore_keys_handler.h" +#include "components/sync/syncable/directory_cryptographer.h" #include "components/sync/syncable/nigori_handler.h" namespace syncer { @@ -50,6 +50,8 @@ const syncable::BaseTransaction* const trans) const override; const Cryptographer* GetCryptographer( const syncable::BaseTransaction* const trans) const override; + const DirectoryCryptographer* GetDirectoryCryptographerForNigori( + const syncable::BaseTransaction* const trans) const override; ModelTypeSet GetEncryptedTypes( const syncable::BaseTransaction* const trans) const override; PassphraseType GetPassphraseType( @@ -60,7 +62,7 @@ bool SetKeystoreKeys(const std::vector<std::string>& keys) override; // Own method, used in some tests to manipulate cryptographer directly. - Cryptographer* GetMutableCryptographer(); + DirectoryCryptographer* GetMutableCryptographer(); private: base::ObserverList<SyncEncryptionHandler::Observer>::Unchecked observers_; @@ -68,7 +70,7 @@ bool encrypt_everything_; PassphraseType passphrase_type_; - Cryptographer cryptographer_; + DirectoryCryptographer cryptographer_; std::string keystore_key_; };
diff --git a/components/sync_bookmarks/bookmark_model_associator.cc b/components/sync_bookmarks/bookmark_model_associator.cc index 649e3ec..1a5fefc8 100644 --- a/components/sync_bookmarks/bookmark_model_associator.cc +++ b/components/sync_bookmarks/bookmark_model_associator.cc
@@ -940,7 +940,7 @@ syncer::ReadTransaction trans(FROM_HERE, user_share_); const syncer::ModelTypeSet encrypted_types = trans.GetEncryptedTypes(); return !encrypted_types.Has(syncer::BOOKMARKS) || - trans.GetCryptographer()->is_ready(); + trans.GetCryptographer()->CanEncrypt(); } syncer::SyncError BookmarkModelAssociator::CheckModelSyncState(
diff --git a/components/test/data/payments/render_tests/MicrotransactionRenderTest.button_error_resource.Nexus_5-19.png.sha1 b/components/test/data/payments/render_tests/MicrotransactionRenderTest.button_error_resource.Nexus_5-19.png.sha1 new file mode 100644 index 0000000..2fc1d59 --- /dev/null +++ b/components/test/data/payments/render_tests/MicrotransactionRenderTest.button_error_resource.Nexus_5-19.png.sha1
@@ -0,0 +1 @@ +2ffcb95d98413c66e0a3effc40e7209795b0e83a \ No newline at end of file
diff --git a/components/test/data/payments/render_tests/MicrotransactionRenderTest.button_error_resource_expanded.Nexus_5-19.png.sha1 b/components/test/data/payments/render_tests/MicrotransactionRenderTest.button_error_resource_expanded.Nexus_5-19.png.sha1 new file mode 100644 index 0000000..4a76a1b --- /dev/null +++ b/components/test/data/payments/render_tests/MicrotransactionRenderTest.button_error_resource_expanded.Nexus_5-19.png.sha1
@@ -0,0 +1 @@ +e1ddf2d0bc4b70ec45ae1eaa47191af60d2b9588 \ No newline at end of file
diff --git a/components/test/data/payments/render_tests/MicrotransactionRenderTest.button_error_string.Nexus_5-19.png.sha1 b/components/test/data/payments/render_tests/MicrotransactionRenderTest.button_error_string.Nexus_5-19.png.sha1 new file mode 100644 index 0000000..56f22eb --- /dev/null +++ b/components/test/data/payments/render_tests/MicrotransactionRenderTest.button_error_string.Nexus_5-19.png.sha1
@@ -0,0 +1 @@ +a0799e2686eab6cd19fb3bed34c62e1e25a137a8 \ No newline at end of file
diff --git a/components/test/data/payments/render_tests/MicrotransactionRenderTest.button_error_string_expanded.Nexus_5-19.png.sha1 b/components/test/data/payments/render_tests/MicrotransactionRenderTest.button_error_string_expanded.Nexus_5-19.png.sha1 new file mode 100644 index 0000000..a4524ef --- /dev/null +++ b/components/test/data/payments/render_tests/MicrotransactionRenderTest.button_error_string_expanded.Nexus_5-19.png.sha1
@@ -0,0 +1 @@ +362b6166f2477a40d0237ecc170ef3f7f37ace64 \ No newline at end of file
diff --git a/components/test/data/payments/render_tests/MicrotransactionRenderTest.button_initial.Nexus_5-19.png.sha1 b/components/test/data/payments/render_tests/MicrotransactionRenderTest.button_initial.Nexus_5-19.png.sha1 new file mode 100644 index 0000000..7822493 --- /dev/null +++ b/components/test/data/payments/render_tests/MicrotransactionRenderTest.button_initial.Nexus_5-19.png.sha1
@@ -0,0 +1 @@ +f71440a596cf9b0b089402573e0125e2372a170a \ No newline at end of file
diff --git a/components/test/data/payments/render_tests/MicrotransactionRenderTest.button_initial_expanded.Nexus_5-19.png.sha1 b/components/test/data/payments/render_tests/MicrotransactionRenderTest.button_initial_expanded.Nexus_5-19.png.sha1 new file mode 100644 index 0000000..75bf03d --- /dev/null +++ b/components/test/data/payments/render_tests/MicrotransactionRenderTest.button_initial_expanded.Nexus_5-19.png.sha1
@@ -0,0 +1 @@ +ce49a8a3419025d7ea50a07d8b70731873ada4b4 \ No newline at end of file
diff --git a/components/test/data/payments/render_tests/MicrotransactionRenderTest.button_processing.Nexus_5-19.png.sha1 b/components/test/data/payments/render_tests/MicrotransactionRenderTest.button_processing.Nexus_5-19.png.sha1 new file mode 100644 index 0000000..b6024ac --- /dev/null +++ b/components/test/data/payments/render_tests/MicrotransactionRenderTest.button_processing.Nexus_5-19.png.sha1
@@ -0,0 +1 @@ +050b33e82d278745080ec9fe87272fb485148a35 \ No newline at end of file
diff --git a/components/test/data/payments/render_tests/MicrotransactionRenderTest.button_processing_expanded.Nexus_5-19.png.sha1 b/components/test/data/payments/render_tests/MicrotransactionRenderTest.button_processing_expanded.Nexus_5-19.png.sha1 new file mode 100644 index 0000000..ef200e4 --- /dev/null +++ b/components/test/data/payments/render_tests/MicrotransactionRenderTest.button_processing_expanded.Nexus_5-19.png.sha1
@@ -0,0 +1 @@ +4f97844b18a4bb5de49e9905a483f782855a0512 \ No newline at end of file
diff --git a/components/test/data/payments/render_tests/MicrotransactionRenderTest.button_success.Nexus_5-19.png.sha1 b/components/test/data/payments/render_tests/MicrotransactionRenderTest.button_success.Nexus_5-19.png.sha1 new file mode 100644 index 0000000..8d21e27a --- /dev/null +++ b/components/test/data/payments/render_tests/MicrotransactionRenderTest.button_success.Nexus_5-19.png.sha1
@@ -0,0 +1 @@ +4ee5d58a05ea1df7e21428d3c071f3533dcb4320 \ No newline at end of file
diff --git a/components/test/data/payments/render_tests/MicrotransactionRenderTest.button_success_expanded.Nexus_5-19.png.sha1 b/components/test/data/payments/render_tests/MicrotransactionRenderTest.button_success_expanded.Nexus_5-19.png.sha1 new file mode 100644 index 0000000..44807813 --- /dev/null +++ b/components/test/data/payments/render_tests/MicrotransactionRenderTest.button_success_expanded.Nexus_5-19.png.sha1
@@ -0,0 +1 @@ +e07f3ca6aec1bc7a48ac62df908eb1bbc2f9967e \ No newline at end of file
diff --git a/components/test/data/payments/render_tests/MicrotransactionRenderTest.fingerprint_error_resource.Nexus_5-19.png.sha1 b/components/test/data/payments/render_tests/MicrotransactionRenderTest.fingerprint_error_resource.Nexus_5-19.png.sha1 new file mode 100644 index 0000000..eaf0958b --- /dev/null +++ b/components/test/data/payments/render_tests/MicrotransactionRenderTest.fingerprint_error_resource.Nexus_5-19.png.sha1
@@ -0,0 +1 @@ +01f5b5212714fea6108aa75cd1a763a5c5d2c5fa \ No newline at end of file
diff --git a/components/test/data/payments/render_tests/MicrotransactionRenderTest.fingerprint_error_resource_expanded.Nexus_5-19.png.sha1 b/components/test/data/payments/render_tests/MicrotransactionRenderTest.fingerprint_error_resource_expanded.Nexus_5-19.png.sha1 new file mode 100644 index 0000000..169cc70 --- /dev/null +++ b/components/test/data/payments/render_tests/MicrotransactionRenderTest.fingerprint_error_resource_expanded.Nexus_5-19.png.sha1
@@ -0,0 +1 @@ +059a58733a525f89492e1d06541dd595b64e2674 \ No newline at end of file
diff --git a/components/test/data/payments/render_tests/MicrotransactionRenderTest.fingerprint_error_string.Nexus_5-19.png.sha1 b/components/test/data/payments/render_tests/MicrotransactionRenderTest.fingerprint_error_string.Nexus_5-19.png.sha1 new file mode 100644 index 0000000..70e1d181 --- /dev/null +++ b/components/test/data/payments/render_tests/MicrotransactionRenderTest.fingerprint_error_string.Nexus_5-19.png.sha1
@@ -0,0 +1 @@ +597dedb5aa98d1c7985fd815632477848c435412 \ No newline at end of file
diff --git a/components/test/data/payments/render_tests/MicrotransactionRenderTest.fingerprint_error_string_expanded.Nexus_5-19.png.sha1 b/components/test/data/payments/render_tests/MicrotransactionRenderTest.fingerprint_error_string_expanded.Nexus_5-19.png.sha1 new file mode 100644 index 0000000..2da2fba0 --- /dev/null +++ b/components/test/data/payments/render_tests/MicrotransactionRenderTest.fingerprint_error_string_expanded.Nexus_5-19.png.sha1
@@ -0,0 +1 @@ +56d31b38e22da4c2399c5491cccd397c27945196 \ No newline at end of file
diff --git a/components/test/data/payments/render_tests/MicrotransactionRenderTest.fingerprint_initial.Nexus_5-19.png.sha1 b/components/test/data/payments/render_tests/MicrotransactionRenderTest.fingerprint_initial.Nexus_5-19.png.sha1 new file mode 100644 index 0000000..3369e0b1 --- /dev/null +++ b/components/test/data/payments/render_tests/MicrotransactionRenderTest.fingerprint_initial.Nexus_5-19.png.sha1
@@ -0,0 +1 @@ +12c6daa5fbfea11eb7a7c239440b2585eae3d777 \ No newline at end of file
diff --git a/components/test/data/payments/render_tests/MicrotransactionRenderTest.fingerprint_initial_expanded.Nexus_5-19.png.sha1 b/components/test/data/payments/render_tests/MicrotransactionRenderTest.fingerprint_initial_expanded.Nexus_5-19.png.sha1 new file mode 100644 index 0000000..37e9d8f --- /dev/null +++ b/components/test/data/payments/render_tests/MicrotransactionRenderTest.fingerprint_initial_expanded.Nexus_5-19.png.sha1
@@ -0,0 +1 @@ +cbcc9055beee80114ba66035ba34f473ae168467 \ No newline at end of file
diff --git a/components/test/data/payments/render_tests/MicrotransactionRenderTest.fingerprint_processing.Nexus_5-19.png.sha1 b/components/test/data/payments/render_tests/MicrotransactionRenderTest.fingerprint_processing.Nexus_5-19.png.sha1 new file mode 100644 index 0000000..e3a6605 --- /dev/null +++ b/components/test/data/payments/render_tests/MicrotransactionRenderTest.fingerprint_processing.Nexus_5-19.png.sha1
@@ -0,0 +1 @@ +792edcbad644e560aab2e309daf3ea9fe3166ada \ No newline at end of file
diff --git a/components/test/data/payments/render_tests/MicrotransactionRenderTest.fingerprint_processing_expanded.Nexus_5-19.png.sha1 b/components/test/data/payments/render_tests/MicrotransactionRenderTest.fingerprint_processing_expanded.Nexus_5-19.png.sha1 new file mode 100644 index 0000000..aee05d4 --- /dev/null +++ b/components/test/data/payments/render_tests/MicrotransactionRenderTest.fingerprint_processing_expanded.Nexus_5-19.png.sha1
@@ -0,0 +1 @@ +fdd6f1becf73f7f50bd8eec9c530ccb65c95414c \ No newline at end of file
diff --git a/components/test/data/payments/render_tests/MicrotransactionRenderTest.fingerprint_success.Nexus_5-19.png.sha1 b/components/test/data/payments/render_tests/MicrotransactionRenderTest.fingerprint_success.Nexus_5-19.png.sha1 new file mode 100644 index 0000000..342cde3 --- /dev/null +++ b/components/test/data/payments/render_tests/MicrotransactionRenderTest.fingerprint_success.Nexus_5-19.png.sha1
@@ -0,0 +1 @@ +7b74244d173e0b7540671faab1f8047812b8a8d6 \ No newline at end of file
diff --git a/components/test/data/payments/render_tests/MicrotransactionRenderTest.fingerprint_success_expanded.Nexus_5-19.png.sha1 b/components/test/data/payments/render_tests/MicrotransactionRenderTest.fingerprint_success_expanded.Nexus_5-19.png.sha1 new file mode 100644 index 0000000..d1200af --- /dev/null +++ b/components/test/data/payments/render_tests/MicrotransactionRenderTest.fingerprint_success_expanded.Nexus_5-19.png.sha1
@@ -0,0 +1 @@ +c513c5a353ac108a5499454a404f23d491b0a434 \ No newline at end of file
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc index 5af4454..e114ed06 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
@@ -784,26 +784,8 @@ void SkiaOutputSurfaceImplOnGpu::ScheduleOutputSurfaceAsOverlay( const OverlayProcessor::OutputSurfaceOverlayPlane& output_surface_plane) { - DCHECK(!is_using_vulkan()); - - if (!MakeCurrent(!dependency_->IsOffscreen() /* need_fbo0 */)) - return; - - gl::GLImage* image = output_device_->GetOverlayImage(); - std::unique_ptr<gfx::GpuFence> gpu_fence = - output_device_->SubmitOverlayGpuFence(); - - if (image) { - // Output surface is also z-order 0. - int plane_z_order = 0; - // Output surface always uses the full texture. - gfx::RectF uv_rect(0.f, 0.f, 1.f, 1.f); - - gl_surface_->ScheduleOverlayPlane( - plane_z_order, output_surface_plane.transform, image, - ToNearestRect(output_surface_plane.display_rect), uv_rect, - output_surface_plane.enable_blending, std::move(gpu_fence)); - } + DCHECK(!output_surface_plane_); + output_surface_plane_ = output_surface_plane; } void SkiaOutputSurfaceImplOnGpu::SwapBuffers( @@ -824,6 +806,25 @@ scoped_output_device_paint_.reset(); + if (output_surface_plane_) { + DCHECK(!is_using_vulkan()); + if (gl::GLImage* image = output_device_->GetOverlayImage()) { + std::unique_ptr<gfx::GpuFence> gpu_fence = + output_device_->SubmitOverlayGpuFence(); + + // Output surface is also z-order 0. + int plane_z_order = 0; + // Output surface always uses the full texture. + gfx::RectF uv_rect(0.f, 0.f, 1.f, 1.f); + + gl_surface_->ScheduleOverlayPlane( + plane_z_order, output_surface_plane_->transform, image, + ToNearestRect(output_surface_plane_->display_rect), uv_rect, + output_surface_plane_->enable_blending, std::move(gpu_fence)); + } + output_surface_plane_.reset(); + } + if (frame.sub_buffer_rect && frame.sub_buffer_rect->IsEmpty()) { // Call SwapBuffers() to present overlays. output_device_->SwapBuffers(buffer_presented_callback_,
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h index ac48dab8..d229302 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h +++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
@@ -241,6 +241,9 @@ std::unique_ptr<SkiaOutputDevice> output_device_; base::Optional<SkiaOutputDevice::ScopedPaint> scoped_output_device_paint_; + base::Optional<OverlayProcessor::OutputSurfaceOverlayPlane> + output_surface_plane_; + // Offscreen surfaces for render passes. It can only be accessed on GPU // thread. class OffscreenSurface {
diff --git a/content/browser/accessibility/browser_accessibility_cocoa.mm b/content/browser/accessibility/browser_accessibility_cocoa.mm index ae504a5..ca88cdf6 100644 --- a/content/browser/accessibility/browser_accessibility_cocoa.mm +++ b/content/browser/accessibility/browser_accessibility_cocoa.mm
@@ -9,6 +9,8 @@ #include <stdint.h> #include <string.h> +#include <algorithm> +#include <iterator> #include <map> #include <memory> #include <utility> @@ -370,6 +372,38 @@ return AXPlatformRange(std::move(anchor), std::move(focus)); } +AXPlatformRange GetSelectedRange(BrowserAccessibility& owner) { + const BrowserAccessibilityManager* manager = owner.manager(); + if (!manager) + return {}; + + const ui::AXTree::Selection unignored_selection = + manager->ax_tree()->GetUnignoredSelection(); + int32_t anchor_id = unignored_selection.anchor_object_id; + const BrowserAccessibility* anchor_object = manager->GetFromID(anchor_id); + if (!anchor_object) + return {}; + + int32_t focus_id = unignored_selection.focus_object_id; + const BrowserAccessibility* focus_object = manager->GetFromID(focus_id); + if (!focus_object) + return {}; + + // |anchor_offset| and / or |focus_offset| refer to a character offset if + // |anchor_object| / |focus_object| are text-only objects or native text + // fields. Otherwise, they should be treated as child indices. + int anchor_offset = unignored_selection.anchor_offset; + int focus_offset = unignored_selection.focus_offset; + DCHECK_GE(anchor_offset, 0); + DCHECK_GE(focus_offset, 0); + + ax::mojom::TextAffinity anchor_affinity = unignored_selection.anchor_affinity; + ax::mojom::TextAffinity focus_affinity = unignored_selection.focus_affinity; + + return CreateAXPlatformRange(*anchor_object, anchor_offset, anchor_affinity, + *focus_object, focus_offset, focus_affinity); +} + void AddMisspelledTextAttributes(const AXPlatformRange& ax_range, NSMutableAttributedString* attributed_string) { int anchor_start_offset = 0; @@ -826,11 +860,10 @@ - (NSNumber*)ariaColumnIndex { if (![self instanceActive]) return nil; - base::Optional<int> aria_col_index = - owner_->node()->GetTableCellAriaColIndex(); - if (!aria_col_index) + base::Optional<int> ariaColIndex = owner_->node()->GetTableCellAriaColIndex(); + if (!ariaColIndex) return nil; - return [NSNumber numberWithInt:*aria_col_index]; + return [NSNumber numberWithInt:*ariaColIndex]; } - (NSString*)ariaLive { @@ -843,10 +876,10 @@ - (NSNumber*)ariaPosInSet { if (![self instanceActive]) return nil; - base::Optional<int> pos_in_set = owner_->node()->GetPosInSet(); - if (!pos_in_set) + base::Optional<int> posInSet = owner_->node()->GetPosInSet(); + if (!posInSet) return nil; - return [NSNumber numberWithInt:*pos_in_set]; + return [NSNumber numberWithInt:*posInSet]; } - (NSString*)ariaRelevant { @@ -859,29 +892,28 @@ - (NSNumber*)ariaRowCount { if (![self instanceActive]) return nil; - base::Optional<int> aria_row_count = owner_->node()->GetTableAriaRowCount(); - if (!aria_row_count) + base::Optional<int> ariaRowCount = owner_->node()->GetTableAriaRowCount(); + if (!ariaRowCount) return nil; - return [NSNumber numberWithInt:*aria_row_count]; + return [NSNumber numberWithInt:*ariaRowCount]; } - (NSNumber*)ariaRowIndex { if (![self instanceActive]) return nil; - base::Optional<int> aria_row_index = - owner_->node()->GetTableCellAriaRowIndex(); - if (!aria_row_index) + base::Optional<int> ariaRowIndex = owner_->node()->GetTableCellAriaRowIndex(); + if (!ariaRowIndex) return nil; - return [NSNumber numberWithInt:*aria_row_index]; + return [NSNumber numberWithInt:*ariaRowIndex]; } - (NSNumber*)ariaSetSize { if (![self instanceActive]) return nil; - base::Optional<int> set_size = owner_->node()->GetSetSize(); - if (!set_size) + base::Optional<int> setSize = owner_->node()->GetSetSize(); + if (!setSize) return nil; - return [NSNumber numberWithInt:*set_size]; + return [NSNumber numberWithInt:*setSize]; } - (NSString*)autocompleteValue { @@ -1396,25 +1428,24 @@ - (NSNumber*)insertionPointLineNumber { if (![self instanceActive]) return nil; - - // TODO(nektar): Deprecate sel_start and sel_end attributes. - int selStart, selEnd; - if (!owner_->GetIntAttribute(ax::mojom::IntAttribute::kTextSelStart, - &selStart) || - !owner_->GetIntAttribute(ax::mojom::IntAttribute::kTextSelEnd, &selEnd)) { + if (!owner_->HasVisibleCaretOrSelection()) return nil; - } - if (selStart > selEnd) - std::swap(selStart, selEnd); + const AXPlatformRange range = GetSelectedRange(*owner_); + // If the selection is not collapsed, then there is no visible caret. + if (!range.IsCollapsed()) + return nil; - const std::vector<int> line_breaks = owner_->GetLineStartOffsets(); - for (int i = 0; i < static_cast<int>(line_breaks.size()); ++i) { - if (line_breaks[i] > selStart) - return [NSNumber numberWithInt:i]; - } - - return [NSNumber numberWithInt:static_cast<int>(line_breaks.size())]; + const BrowserAccessibilityPositionInstance caretPosition = + range.focus()->LowestCommonAncestor(*owner_->CreatePositionAt(0)); + DCHECK(!caretPosition->IsNullPosition()) + << "Calling HasVisibleCaretOrSelection() should have ensured that there " + "is a valid selection focus inside the current object."; + const std::vector<int> lineBreaks = owner_->GetLineStartOffsets(); + auto iterator = + std::upper_bound(lineBreaks.begin(), lineBreaks.end(), + caretPosition->AsTextPosition()->text_offset()); + return @(std::distance(lineBreaks.begin(), iterator)); } // Returns whether or not this node should be ignored in the @@ -2083,79 +2114,44 @@ - (NSString*)selectedText { if (![self instanceActive]) return nil; - - // TODO(nektar): Deprecate sel_start and sel_end attributes. - int selStart, selEnd; - if (!owner_->GetIntAttribute(ax::mojom::IntAttribute::kTextSelStart, - &selStart) || - !owner_->GetIntAttribute(ax::mojom::IntAttribute::kTextSelEnd, &selEnd)) { + if (!owner_->HasVisibleCaretOrSelection()) return nil; - } - if (selStart > selEnd) - std::swap(selStart, selEnd); - - int selLength = selEnd - selStart; - base::string16 value = owner_->GetValue(); - return base::SysUTF16ToNSString(value.substr(selStart, selLength)); + const AXPlatformRange range = GetSelectedRange(*owner_); + if (range.IsNull()) + return nil; + return base::SysUTF16ToNSString(range.GetText()); } +// Returns range of text under the current object that is selected. +// // Example, caret at offset 5: -// AXSelectedTextRange: “pos=5 len=0” +// NSRange: “pos=5 len=0” - (NSValue*)selectedTextRange { if (![self instanceActive]) return nil; - - // TODO(nektar): Deprecate sel_start and sel_end attributes. - int selStart, selEnd; - if (!owner_->GetIntAttribute(ax::mojom::IntAttribute::kTextSelStart, - &selStart) || - !owner_->GetIntAttribute(ax::mojom::IntAttribute::kTextSelEnd, &selEnd)) { - // TODO(accessibility) Incorrectly reaches this line in a rich text area. + if (!owner_->HasVisibleCaretOrSelection()) return nil; - } - if (selStart > selEnd) - std::swap(selStart, selEnd); + const AXPlatformRange range = GetSelectedRange(*owner_).AsForwardRange(); + if (range.IsNull()) + return nil; - int selLength = selEnd - selStart; + const BrowserAccessibilityPositionInstance startPosition = + range.anchor()->LowestCommonAncestor(*owner_->CreatePositionAt(0)); + DCHECK(!startPosition->IsNullPosition()) + << "Calling HasVisibleCaretOrSelection() should have ensured that there " + "is a valid selection anchor inside the current object."; + int selStart = startPosition->AsTextPosition()->text_offset(); + DCHECK_GE(selStart, 0); + int selLength = range.GetText().length(); return [NSValue valueWithRange:NSMakeRange(selStart, selLength)]; } - (id)selectedTextMarkerRange { if (![self instanceActive]) return nil; - - BrowserAccessibilityManager* manager = owner_->manager(); - if (!manager) - return nil; - - ui::AXTree::Selection unignored_selection = - manager->ax_tree()->GetUnignoredSelection(); - int32_t anchorId = unignored_selection.anchor_object_id; - const BrowserAccessibility* anchorObject = manager->GetFromID(anchorId); - if (!anchorObject) - return nil; - - int32_t focusId = unignored_selection.focus_object_id; - const BrowserAccessibility* focusObject = manager->GetFromID(focusId); - if (!focusObject) - return nil; - - // |anchorOffset| and / or |focusOffset| refer to a character offset if - // |anchorObject| / |focusObject| are text-only objects. Otherwise, they - // should be treated as child indices. - int anchorOffset = unignored_selection.anchor_offset; - int focusOffset = unignored_selection.focus_offset; - if (anchorOffset < 0 || focusOffset < 0) - return nil; - - ax::mojom::TextAffinity anchorAffinity = unignored_selection.anchor_affinity; - ax::mojom::TextAffinity focusAffinity = unignored_selection.focus_affinity; - - return CreateTextMarkerRange( - CreateAXPlatformRange(*anchorObject, anchorOffset, anchorAffinity, - *focusObject, focusOffset, focusAffinity)); + return CreateTextMarkerRange(GetSelectedRange(*owner_)); } - (NSValue*)size { @@ -2519,9 +2515,11 @@ if (![self instanceActive]) return nil; - const std::vector<int> line_breaks = owner_->GetLineStartOffsets(); + const std::vector<int> lineBreaks = owner_->GetLineStartOffsets(); base::string16 value = owner_->GetValue(); - int len = static_cast<int>(value.size()); + if (owner_->IsTextOnlyObject() && value.empty()) + value = owner_->GetText(); + int valueLength = static_cast<int>(value.size()); if ([attribute isEqualToString: NSAccessibilityStringForRangeParameterizedAttribute]) { @@ -2536,22 +2534,21 @@ if ([attribute isEqualToString:NSAccessibilityLineForIndexParameterizedAttribute]) { - int index = [(NSNumber*)parameter intValue]; - for (int i = 0; i < static_cast<int>(line_breaks.size()); ++i) { - if (line_breaks[i] > index) - return [NSNumber numberWithInt:i]; - } - return [NSNumber numberWithInt:static_cast<int>(line_breaks.size())]; + int lineIndex = [(NSNumber*)parameter intValue]; + auto iterator = + std::upper_bound(lineBreaks.begin(), lineBreaks.end(), lineIndex); + return @(std::distance(lineBreaks.begin(), iterator)); } if ([attribute isEqualToString:NSAccessibilityRangeForLineParameterizedAttribute]) { - int line_index = [(NSNumber*)parameter intValue]; - int line_count = static_cast<int>(line_breaks.size()) + 1; - if (line_index < 0 || line_index >= line_count) + int lineIndex = [(NSNumber*)parameter intValue]; + int lineCount = static_cast<int>(lineBreaks.size()) + 1; + if (lineIndex < 0 || lineIndex >= lineCount) return nil; - int start = line_index > 0 ? line_breaks[line_index - 1] : 0; - int end = line_index < line_count - 1 ? line_breaks[line_index] : len; + int start = (lineIndex > 0) ? lineBreaks[lineIndex - 1] : 0; + int end = + (lineIndex < (lineCount - 1)) ? lineBreaks[lineIndex] : valueLength; return [NSValue valueWithRange:NSMakeRange(start, end - start)]; } @@ -2568,11 +2565,11 @@ int column = [[array objectAtIndex:0] intValue]; int row = [[array objectAtIndex:1] intValue]; - ui::AXNode* cell_node = owner_->node()->GetTableCellFromCoords(row, column); - if (!cell_node) + ui::AXNode* cellNode = owner_->node()->GetTableCellFromCoords(row, column); + if (!cellNode) return nil; - BrowserAccessibility* cell = owner_->manager()->GetFromID(cell_node->id()); + BrowserAccessibility* cell = owner_->manager()->GetFromID(cellNode->id()); if (cell) return ToBrowserAccessibilityCocoa(cell); } @@ -2696,21 +2693,42 @@ ui::AXBoundaryBehavior::CrossBoundary)); } - if ([attribute - isEqualToString: - NSAccessibilityTextMarkerRangeForLineParameterizedAttribute]) { + if ([attribute isEqualToString: + NSAccessibilityLineForTextMarkerParameterizedAttribute]) { BrowserAccessibilityPositionInstance position = CreatePositionFromTextMarker(parameter); if (position->IsNullPosition()) return nil; - BrowserAccessibilityPositionInstance startPosition = - position->CreatePreviousLineStartPosition( - ui::AXBoundaryBehavior::StopIfAlreadyAtBoundary); - BrowserAccessibilityPositionInstance endPosition = - position->CreateNextLineEndPosition( - ui::AXBoundaryBehavior::StopIfAlreadyAtBoundary); - AXPlatformRange range(std::move(startPosition), std::move(endPosition)); + int textOffset = position->AsTextPosition()->text_offset(); + const auto iterator = + std::upper_bound(lineBreaks.begin(), lineBreaks.end(), textOffset); + return @(std::distance(lineBreaks.begin(), iterator)); + } + + if ([attribute + isEqualToString: + NSAccessibilityTextMarkerRangeForLineParameterizedAttribute]) { + int lineIndex = [(NSNumber*)parameter intValue]; + int lineCount = static_cast<int>(lineBreaks.size()) + 1; + if (lineIndex < 0 || lineIndex >= lineCount) + return nil; + + int lineStartOffset = (lineIndex > 0) ? lineBreaks[lineIndex - 1] : 0; + BrowserAccessibilityPositionInstance lineStartPosition = CreateTextPosition( + *owner_, lineStartOffset, ax::mojom::TextAffinity::kDownstream); + if (lineStartPosition->IsNullPosition()) + return nil; + + // Make sure that the line start position is really at the start of the + // current line. + lineStartPosition = lineStartPosition->CreatePreviousLineStartPosition( + ui::AXBoundaryBehavior::StopIfAlreadyAtBoundary); + BrowserAccessibilityPositionInstance lineEndPosition = + lineStartPosition->CreateNextLineEndPosition( + ui::AXBoundaryBehavior::StopAtAnchorBoundary); + AXPlatformRange range(std::move(lineStartPosition), + std::move(lineEndPosition)); return CreateTextMarkerRange(std::move(range)); } @@ -2948,14 +2966,14 @@ if (![parameter isKindOfClass:[NSArray class]]) return nil; - NSArray* text_marker_array = parameter; - if ([text_marker_array count] != 2) + NSArray* textMarkerArray = parameter; + if ([textMarkerArray count] != 2) return nil; BrowserAccessibilityPositionInstance startPosition = - CreatePositionFromTextMarker([text_marker_array objectAtIndex:0]); + CreatePositionFromTextMarker([textMarkerArray objectAtIndex:0]); BrowserAccessibilityPositionInstance endPosition = - CreatePositionFromTextMarker([text_marker_array objectAtIndex:1]); + CreatePositionFromTextMarker([textMarkerArray objectAtIndex:1]); if (*startPosition <= *endPosition) { return CreateTextMarkerRange( AXPlatformRange(std::move(startPosition), std::move(endPosition)));
diff --git a/content/browser/background_sync/background_sync_manager.cc b/content/browser/background_sync/background_sync_manager.cc index a93f4dd..3566b94 100644 --- a/content/browser/background_sync/background_sync_manager.cc +++ b/content/browser/background_sync/background_sync_manager.cc
@@ -2331,6 +2331,9 @@ void BackgroundSyncManager::OnNetworkChanged() { DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId()); + if (!AreOptionConditionsMet()) + return; + FireReadyEvents(BackgroundSyncType::ONE_SHOT, /* reschedule= */ true, base::DoNothing::Once()); FireReadyEvents(BackgroundSyncType::PERIODIC, /* reschedule= */ true,
diff --git a/content/browser/browser_interface_binders.cc b/content/browser/browser_interface_binders.cc index 858ce3ba..b1d73727 100644 --- a/content/browser/browser_interface_binders.cc +++ b/content/browser/browser_interface_binders.cc
@@ -4,7 +4,9 @@ #include "content/browser/browser_interface_binders.h" +#include "build/build_config.h" #include "content/browser/background_fetch/background_fetch_service_impl.h" +#include "content/browser/content_index/content_index_service_impl.h" #include "content/browser/frame_host/render_frame_host_impl.h" #include "content/browser/image_capture/image_capture_impl.h" #include "content/browser/renderer_host/render_process_host_impl.h" @@ -17,6 +19,8 @@ #include "media/capture/mojom/image_capture.mojom.h" #include "third_party/blink/public/mojom/appcache/appcache.mojom.h" #include "third_party/blink/public/mojom/background_fetch/background_fetch.mojom.h" +#include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom.h" +#include "third_party/blink/public/mojom/content_index/content_index.mojom.h" #include "third_party/blink/public/mojom/filesystem/file_system.mojom.h" #include "third_party/blink/public/mojom/idle/idle_manager.mojom.h" #include "third_party/blink/public/mojom/locks/lock_manager.mojom.h" @@ -24,6 +28,10 @@ #include "third_party/blink/public/mojom/speech/speech_synthesis.mojom.h" #include "third_party/blink/public/mojom/webaudio/audio_context_manager.mojom.h" +#if !defined(OS_ANDROID) +#include "third_party/blink/public/mojom/hid/hid.mojom.h" +#endif + namespace content { namespace internal { @@ -36,9 +44,17 @@ map->Add<blink::mojom::AudioContextManager>(base::BindRepeating( &RenderFrameHostImpl::GetAudioContextManager, base::Unretained(host))); + map->Add<blink::mojom::ContactsManager>(base::BindRepeating( + &RenderFrameHostImpl::GetContactsManager, base::Unretained(host))); + map->Add<blink::mojom::FileSystemManager>(base::BindRepeating( &RenderFrameHostImpl::GetFileSystemManager, base::Unretained(host))); +#if !defined(OS_ANDROID) + map->Add<blink::mojom::HidService>(base::BindRepeating( + &RenderFrameHostImpl::GetHidService, base::Unretained(host))); +#endif + map->Add<blink::mojom::IdleManager>(base::BindRepeating( &RenderFrameHostImpl::GetIdleManager, base::Unretained(host))); @@ -59,6 +75,9 @@ map->Add<media::mojom::ImageCapture>( base::BindRepeating(&ImageCaptureImpl::Create)); + + map->Add<blink::mojom::WebBluetoothService>(base::BindRepeating( + &RenderFrameHostImpl::CreateWebBluetoothService, base::Unretained(host))); } void PopulateBinderMapWithContext( @@ -66,6 +85,8 @@ service_manager::BinderMapWithContext<RenderFrameHost*>* map) { map->Add<blink::mojom::BackgroundFetchService>( base::BindRepeating(&BackgroundFetchServiceImpl::CreateForFrame)); + map->Add<blink::mojom::ContentIndexService>( + base::BindRepeating(&ContentIndexServiceImpl::CreateForFrame)); GetContentClient()->browser()->RegisterBrowserInterfaceBindersForFrame(map); } @@ -168,10 +189,15 @@ if (ServiceWorkerContext::IsServiceWorkerOnUIEnabled()) { map->Add<blink::mojom::BackgroundFetchService>( base::BindRepeating(&BackgroundFetchServiceImpl::CreateForWorker)); + map->Add<blink::mojom::ContentIndexService>( + base::BindRepeating(&ContentIndexServiceImpl::CreateForWorker)); } else { map->Add<blink::mojom::BackgroundFetchService>( base::BindRepeating(&BackgroundFetchServiceImpl::CreateForWorker), base::CreateSingleThreadTaskRunner(BrowserThread::UI)); + map->Add<blink::mojom::ContentIndexService>( + base::BindRepeating(&ContentIndexServiceImpl::CreateForWorker), + base::CreateSingleThreadTaskRunner(BrowserThread::UI)); } }
diff --git a/content/browser/content_index/content_index_service_impl.cc b/content/browser/content_index/content_index_service_impl.cc index feab6d2..314dc6a 100644 --- a/content/browser/content_index/content_index_service_impl.cc +++ b/content/browser/content_index/content_index_service_impl.cc
@@ -19,18 +19,40 @@ namespace content { // static -void ContentIndexServiceImpl::Create( - mojo::PendingReceiver<blink::mojom::ContentIndexService> receiver, - RenderProcessHost* render_process_host, - const url::Origin& origin) { +void ContentIndexServiceImpl::CreateForFrame( + RenderFrameHost* render_frame_host, + mojo::PendingReceiver<blink::mojom::ContentIndexService> receiver) { DCHECK_CURRENTLY_ON(BrowserThread::UI); + RenderProcessHost* render_process_host = render_frame_host->GetProcess(); + DCHECK(render_process_host); + auto* storage_partition = static_cast<StoragePartitionImpl*>( + render_process_host->GetStoragePartition()); + + mojo::MakeSelfOwnedReceiver(std::make_unique<ContentIndexServiceImpl>( + render_frame_host->GetLastCommittedOrigin(), + storage_partition->GetContentIndexContext()), + std::move(receiver)); +} + +// static +void ContentIndexServiceImpl::CreateForWorker( + const ServiceWorkerVersionInfo& info, + mojo::PendingReceiver<blink::mojom::ContentIndexService> receiver) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + RenderProcessHost* render_process_host = + RenderProcessHost::FromID(info.process_id); + + if (!render_process_host) + return; + auto* storage_partition = static_cast<StoragePartitionImpl*>( render_process_host->GetStoragePartition()); mojo::MakeSelfOwnedReceiver( std::make_unique<ContentIndexServiceImpl>( - origin, storage_partition->GetContentIndexContext()), + info.script_origin, storage_partition->GetContentIndexContext()), std::move(receiver)); }
diff --git a/content/browser/content_index/content_index_service_impl.h b/content/browser/content_index/content_index_service_impl.h index 172936a..863bbe6 100644 --- a/content/browser/content_index/content_index_service_impl.h +++ b/content/browser/content_index/content_index_service_impl.h
@@ -15,17 +15,21 @@ namespace content { -class RenderProcessHost; +class RenderFrameHost; +struct ServiceWorkerVersionInfo; // Lazily constructed by the corresponding renderer when the Content Index API // is triggered. class CONTENT_EXPORT ContentIndexServiceImpl : public blink::mojom::ContentIndexService { public: - static void Create( - mojo::PendingReceiver<blink::mojom::ContentIndexService> receiver, - RenderProcessHost* render_process_host, - const url::Origin& origin); + static void CreateForFrame( + RenderFrameHost* render_frame_host, + mojo::PendingReceiver<blink::mojom::ContentIndexService> receiver); + + static void CreateForWorker( + const ServiceWorkerVersionInfo& info, + mojo::PendingReceiver<blink::mojom::ContentIndexService> receiver); ContentIndexServiceImpl( const url::Origin& origin,
diff --git a/content/browser/devtools/protocol/tracing_handler.cc b/content/browser/devtools/protocol/tracing_handler.cc index 51069f5..7730d55d 100644 --- a/content/browser/devtools/protocol/tracing_handler.cc +++ b/content/browser/devtools/protocol/tracing_handler.cc
@@ -985,6 +985,7 @@ ->RequestGlobalDumpAndAppendToTrace( base::trace_event::MemoryDumpType::EXPLICITLY_TRIGGERED, base::trace_event::MemoryDumpLevelOfDetail::DETAILED, + base::trace_event::MemoryDumpDeterminism::NONE, std::move(on_memory_dump_finished)); }
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc index 441f632..61336b0 100644 --- a/content/browser/frame_host/navigation_request.cc +++ b/content/browser/frame_host/navigation_request.cc
@@ -451,74 +451,103 @@ RenderFrameHostImpl* new_rfh, const mojom::CommonNavigationParams& common_params, base::TimeTicks ready_to_commit_time) { + bool is_main_frame = !new_rfh->GetParent(); bool is_same_process = old_rfh->GetProcess()->GetID() == new_rfh->GetProcess()->GetID(); - bool is_same_browsing_instance = - old_rfh->GetSiteInstance()->IsRelatedSiteInstance( - new_rfh->GetSiteInstance()); + // Navigation.IsSameBrowsingInstance + if (is_main_frame) { + bool is_same_browsing_instance = + old_rfh->GetSiteInstance()->IsRelatedSiteInstance( + new_rfh->GetSiteInstance()); - bool is_same_site_instance = - old_rfh->GetSiteInstance() == new_rfh->GetSiteInstance(); - - // Log overall value, then log specific value per type of navigation. - UMA_HISTOGRAM_BOOLEAN("Navigation.IsSameProcess", is_same_process); - UMA_HISTOGRAM_BOOLEAN("Navigation.IsSameSiteInstance", is_same_site_instance); - UMA_HISTOGRAM_BOOLEAN("Navigation.IsSameBrowsingInstance", - is_same_browsing_instance); - - UMA_HISTOGRAM_BOOLEAN("Navigation.RequiresDedicatedProcess", - new_rfh->GetSiteInstance()->RequiresDedicatedProcess()); - if (common_params.url.SchemeIsHTTPOrHTTPS()) { - UMA_HISTOGRAM_BOOLEAN( - "Navigation.RequiresDedicatedProcess.HTTPOrHTTPS", - new_rfh->GetSiteInstance()->RequiresDedicatedProcess()); + UMA_HISTOGRAM_BOOLEAN("Navigation.IsSameBrowsingInstance", + is_same_browsing_instance); } - ChildProcessSecurityPolicyImpl* policy = - ChildProcessSecurityPolicyImpl::GetInstance(); - GURL process_lock = policy->GetOriginLock(new_rfh->GetProcess()->GetID()); - UMA_HISTOGRAM_BOOLEAN("Navigation.IsLockedProcess", !process_lock.is_empty()); - if (common_params.url.SchemeIsHTTPOrHTTPS()) { - UMA_HISTOGRAM_BOOLEAN("Navigation.IsLockedProcess.HTTPOrHTTPS", + // Navigation.IsSameSiteInstance + { + bool is_same_site_instance = + old_rfh->GetSiteInstance() == new_rfh->GetSiteInstance(); + UMA_HISTOGRAM_BOOLEAN("Navigation.IsSameSiteInstance", + is_same_site_instance); + if (is_main_frame) { + UMA_HISTOGRAM_BOOLEAN("Navigation.IsSameSiteInstance.MainFrame", + is_same_site_instance); + } else { + UMA_HISTOGRAM_BOOLEAN("Navigation.IsSameSiteInstance.Subframe", + is_same_site_instance); + } + } + + // Navigation.IsLockedProcess + { + ChildProcessSecurityPolicyImpl* policy = + ChildProcessSecurityPolicyImpl::GetInstance(); + GURL process_lock = policy->GetOriginLock(new_rfh->GetProcess()->GetID()); + UMA_HISTOGRAM_BOOLEAN("Navigation.IsLockedProcess", !process_lock.is_empty()); + if (common_params.url.SchemeIsHTTPOrHTTPS()) { + UMA_HISTOGRAM_BOOLEAN("Navigation.IsLockedProcess.HTTPOrHTTPS", + !process_lock.is_empty()); + } } - if (common_params.transition & ui::PAGE_TRANSITION_FORWARD_BACK) { - UMA_HISTOGRAM_BOOLEAN("Navigation.IsSameProcess.BackForward", - is_same_process); - } else if (ui::PageTransitionCoreTypeIs(common_params.transition, - ui::PAGE_TRANSITION_RELOAD)) { - UMA_HISTOGRAM_BOOLEAN("Navigation.IsSameProcess.Reload", is_same_process); - } else if (ui::PageTransitionIsNewNavigation(common_params.transition)) { - UMA_HISTOGRAM_BOOLEAN("Navigation.IsSameProcess.NewNavigation", - is_same_process); - } else { - NOTREACHED() << "Invalid page transition: " << common_params.transition; + // Navigation.RequiresDedicatedProcess + { + UMA_HISTOGRAM_BOOLEAN( + "Navigation.RequiresDedicatedProcess", + new_rfh->GetSiteInstance()->RequiresDedicatedProcess()); + if (common_params.url.SchemeIsHTTPOrHTTPS()) { + UMA_HISTOGRAM_BOOLEAN( + "Navigation.RequiresDedicatedProcess.HTTPOrHTTPS", + new_rfh->GetSiteInstance()->RequiresDedicatedProcess()); + } } - constexpr base::Optional<bool> kIsBackground = base::nullopt; - base::TimeDelta delta = ready_to_commit_time - common_params.navigation_start; - - LOG_NAVIGATION_TIMING_HISTOGRAM( - "TimeToReadyToCommit2", common_params.transition, kIsBackground, delta); - if (!old_rfh->GetParent()) { - LOG_NAVIGATION_TIMING_HISTOGRAM("TimeToReadyToCommit2.MainFrame", - common_params.transition, kIsBackground, - delta); - } else { - LOG_NAVIGATION_TIMING_HISTOGRAM("TimeToReadyToCommit2.Subframe", - common_params.transition, kIsBackground, - delta); + // Navigation.IsSameProcess + { + UMA_HISTOGRAM_BOOLEAN("Navigation.IsSameProcess", is_same_process); + if (common_params.transition & ui::PAGE_TRANSITION_FORWARD_BACK) { + UMA_HISTOGRAM_BOOLEAN("Navigation.IsSameProcess.BackForward", + is_same_process); + } else if (ui::PageTransitionCoreTypeIs(common_params.transition, + ui::PAGE_TRANSITION_RELOAD)) { + UMA_HISTOGRAM_BOOLEAN("Navigation.IsSameProcess.Reload", is_same_process); + } else if (ui::PageTransitionIsNewNavigation(common_params.transition)) { + UMA_HISTOGRAM_BOOLEAN("Navigation.IsSameProcess.NewNavigation", + is_same_process); + } else { + NOTREACHED() << "Invalid page transition: " << common_params.transition; + } } - if (is_same_process) { - LOG_NAVIGATION_TIMING_HISTOGRAM("TimeToReadyToCommit2.SameProcess", - common_params.transition, kIsBackground, - delta); - } else { - LOG_NAVIGATION_TIMING_HISTOGRAM("TimeToReadyToCommit2.CrossProcess", - common_params.transition, kIsBackground, - delta); + + // TimeToReadyToCommit2 + { + constexpr base::Optional<bool> kIsBackground = base::nullopt; + base::TimeDelta delta = + ready_to_commit_time - common_params.navigation_start; + + LOG_NAVIGATION_TIMING_HISTOGRAM( + "TimeToReadyToCommit2", common_params.transition, kIsBackground, delta); + if (is_main_frame) { + LOG_NAVIGATION_TIMING_HISTOGRAM("TimeToReadyToCommit2.MainFrame", + common_params.transition, kIsBackground, + delta); + } else { + LOG_NAVIGATION_TIMING_HISTOGRAM("TimeToReadyToCommit2.Subframe", + common_params.transition, kIsBackground, + delta); + } + if (is_same_process) { + LOG_NAVIGATION_TIMING_HISTOGRAM("TimeToReadyToCommit2.SameProcess", + common_params.transition, kIsBackground, + delta); + } else { + LOG_NAVIGATION_TIMING_HISTOGRAM("TimeToReadyToCommit2.CrossProcess", + common_params.transition, kIsBackground, + delta); + } } }
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index d8c9d8c..92e5d7cb 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -4338,10 +4338,6 @@ registry_->AddInterface( base::Bind(&MediaSessionServiceImpl::Create, base::Unretained(this))); - registry_->AddInterface(base::Bind( - base::IgnoreResult(&RenderFrameHostImpl::CreateWebBluetoothService), - base::Unretained(this))); - registry_->AddInterface(base::BindRepeating( &RenderFrameHostImpl::CreateWebUsbService, base::Unretained(this))); @@ -4413,8 +4409,6 @@ registry_->AddInterface( base::BindRepeating(&RenderFrameHostImpl::BindSerialServiceReceiver, base::Unretained(this))); - registry_->AddInterface( - base::BindRepeating(&HidService::Create, base::Unretained(this))); } #endif // !defined(OS_ANDROID) @@ -4482,9 +4476,6 @@ GetProcess()->GetStoragePartition()->GetFileSystemContext(), ChromeBlobStorageContext::GetFor(GetProcess()->GetBrowserContext()))); - registry_->AddInterface(base::BindRepeating(&ContactsManagerImpl::Create, - base::Unretained(this))); - registry_->AddInterface(base::BindRepeating(&WakeLockServiceImpl::Create, base::Unretained(this))); @@ -6186,7 +6177,7 @@ dst->focused_tree_id = focused_frame->GetAXTreeID(); } -WebBluetoothServiceImpl* RenderFrameHostImpl::CreateWebBluetoothService( +void RenderFrameHostImpl::CreateWebBluetoothService( mojo::PendingReceiver<blink::mojom::WebBluetoothService> receiver) { // RFHI owns |web_bluetooth_services_| and |web_bluetooth_service| owns the // |receiver_| which may run the error handler. |receiver_| can't run the @@ -6198,6 +6189,11 @@ base::BindOnce(&RenderFrameHostImpl::DeleteWebBluetoothService, base::Unretained(this), web_bluetooth_service.get())); web_bluetooth_services_.push_back(std::move(web_bluetooth_service)); +} + +WebBluetoothServiceImpl* +RenderFrameHostImpl::GetWebBluetoothServiceForTesting() { + DCHECK(web_bluetooth_services_.back()); return web_bluetooth_services_.back().get(); } @@ -6342,6 +6338,11 @@ authenticator_impl_->Bind(std::move(receiver)); } + +void RenderFrameHostImpl::GetHidService( + mojo::PendingReceiver<blink::mojom::HidService> receiver) { + HidService::Create(this, std::move(receiver)); +} #endif void RenderFrameHostImpl::GetIdleManager( @@ -6443,6 +6444,11 @@ AudioContextManagerImpl::Create(this, std::move(receiver)); } +void RenderFrameHostImpl::GetContactsManager( + mojo::PendingReceiver<blink::mojom::ContactsManager> receiver) { + ContactsManagerImpl::Create(this, std::move(receiver)); +} + void RenderFrameHostImpl::GetFileSystemManager( mojo::PendingReceiver<blink::mojom::FileSystemManager> receiver) { // This is safe because file_system_manager_ is deleted on the IO thread
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h index 6cb54e0..bfb8fa8 100644 --- a/content/browser/frame_host/render_frame_host_impl.h +++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -77,6 +77,7 @@ #include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom.h" #include "third_party/blink/public/mojom/choosers/file_chooser.mojom.h" #include "third_party/blink/public/mojom/commit_result/commit_result.mojom.h" +#include "third_party/blink/public/mojom/contacts/contacts_manager.mojom.h" #include "third_party/blink/public/mojom/devtools/devtools_agent.mojom.h" #include "third_party/blink/public/mojom/frame/document_interface_broker.mojom.h" #include "third_party/blink/public/mojom/frame/find_in_page.mojom.h" @@ -108,6 +109,7 @@ #if defined(OS_ANDROID) #include "services/device/public/mojom/nfc.mojom.h" #else +#include "third_party/blink/public/mojom/hid/hid.mojom.h" #include "third_party/blink/public/mojom/serial/serial.mojom.h" #endif @@ -1047,9 +1049,16 @@ void GetAudioContextManager( mojo::PendingReceiver<blink::mojom::AudioContextManager> receiver); + void GetContactsManager( + mojo::PendingReceiver<blink::mojom::ContactsManager> receiver); + void GetFileSystemManager( mojo::PendingReceiver<blink::mojom::FileSystemManager> receiver); +#if !defined(OS_ANDROID) + void GetHidService(mojo::PendingReceiver<blink::mojom::HidService> receiver); +#endif + void GetIdleManager( mojo::PendingReceiver<blink::mojom::IdleManager> receiver); @@ -1064,6 +1073,9 @@ void GetFileChooser( mojo::PendingReceiver<blink::mojom::FileChooser> receiver); + void CreateWebBluetoothService( + mojo::PendingReceiver<blink::mojom::WebBluetoothService> receiver); + // https://mikewest.github.io/corpp/#initialize-embedder-policy-for-global network::mojom::CrossOriginEmbedderPolicy cross_origin_embedder_policy() const { @@ -1522,10 +1534,9 @@ FrameTreeNode* FindAndVerifyChild(int32_t child_frame_routing_id, bad_message::BadMessageReason reason); - // Creates Web Bluetooth Service owned by the frame. Returns a raw pointer - // to it. - WebBluetoothServiceImpl* CreateWebBluetoothService( - mojo::PendingReceiver<blink::mojom::WebBluetoothService> receiver); + // Returns a raw pointer to the Web Bluetooth Service owned by the frame. Used + // for testing purposes only (see |TestRenderFrameHost|). + WebBluetoothServiceImpl* GetWebBluetoothServiceForTesting(); // Deletes the Web Bluetooth Service owned by the frame. void DeleteWebBluetoothService(
diff --git a/content/browser/hid/hid_service.cc b/content/browser/hid/hid_service.cc index 7810d13..3655454 100644 --- a/content/browser/hid/hid_service.cc +++ b/content/browser/hid/hid_service.cc
@@ -12,21 +12,21 @@ #include "content/public/browser/hid_chooser.h" #include "content/public/browser/hid_delegate.h" #include "content/public/browser/render_frame_host.h" -#include "mojo/public/cpp/bindings/interface_request.h" #include "mojo/public/cpp/bindings/message.h" #include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom.h" namespace content { HidService::HidService(RenderFrameHost* render_frame_host, - blink::mojom::HidServiceRequest request) - : FrameServiceBase(render_frame_host, std::move(request)) {} + mojo::PendingReceiver<blink::mojom::HidService> receiver) + : FrameServiceBase(render_frame_host, std::move(receiver)) {} HidService::~HidService() = default; // static -void HidService::Create(RenderFrameHost* render_frame_host, - blink::mojom::HidServiceRequest request) { +void HidService::Create( + RenderFrameHost* render_frame_host, + mojo::PendingReceiver<blink::mojom::HidService> receiver) { DCHECK(render_frame_host); if (!render_frame_host->IsFeatureEnabled( @@ -43,7 +43,7 @@ // HidService owns itself. It will self-destruct when a mojo interface error // occurs, the render frame host is deleted, or the render frame host // navigates to a new document. - new HidService(render_frame_host, std::move(request)); + new HidService(render_frame_host, std::move(receiver)); } void HidService::GetDevices(GetDevicesCallback callback) {
diff --git a/content/browser/hid/hid_service.h b/content/browser/hid/hid_service.h index 8792d8db..471eb53 100644 --- a/content/browser/hid/hid_service.h +++ b/content/browser/hid/hid_service.h
@@ -12,7 +12,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "content/public/browser/frame_service_base.h" -#include "mojo/public/cpp/bindings/binding_set.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "services/device/public/mojom/hid.mojom.h" #include "third_party/blink/public/mojom/hid/hid.mojom.h" @@ -26,7 +26,8 @@ // interface is used by Blink to implement the WebHID API. class HidService : public content::FrameServiceBase<blink::mojom::HidService> { public: - static void Create(RenderFrameHost*, blink::mojom::HidServiceRequest); + static void Create(RenderFrameHost*, + mojo::PendingReceiver<blink::mojom::HidService>); // blink::mojom::HidService: void GetDevices(GetDevicesCallback callback) override; @@ -37,7 +38,7 @@ ConnectCallback callback) override; private: - HidService(RenderFrameHost*, blink::mojom::HidServiceRequest); + HidService(RenderFrameHost*, mojo::PendingReceiver<blink::mojom::HidService>); ~HidService() override; void FinishGetDevices(GetDevicesCallback callback,
diff --git a/content/browser/hid/hid_service_unittest.cc b/content/browser/hid/hid_service_unittest.cc index e8a3c24..7a87119 100644 --- a/content/browser/hid/hid_service_unittest.cc +++ b/content/browser/hid/hid_service_unittest.cc
@@ -86,10 +86,9 @@ TEST_F(HidServiceTest, GetDevicesWithPermission) { NavigateAndCommit(GURL(kTestUrl)); - blink::mojom::HidServicePtr service; - contents()->GetMainFrame()->BinderRegistryForTesting().BindInterface( - blink::mojom::HidService::Name_, - mojo::MakeRequest(&service).PassMessagePipe()); + mojo::Remote<blink::mojom::HidService> service; + contents()->GetMainFrame()->GetHidService( + service.BindNewPipeAndPassReceiver()); auto device_info = device::mojom::HidDeviceInfo::New(); device_info->guid = kTestGuid; @@ -112,10 +111,9 @@ TEST_F(HidServiceTest, GetDevicesWithoutPermission) { NavigateAndCommit(GURL(kTestUrl)); - blink::mojom::HidServicePtr service; - contents()->GetMainFrame()->BinderRegistryForTesting().BindInterface( - blink::mojom::HidService::Name_, - mojo::MakeRequest(&service).PassMessagePipe()); + mojo::Remote<blink::mojom::HidService> service; + contents()->GetMainFrame()->GetHidService( + service.BindNewPipeAndPassReceiver()); auto device_info = device::mojom::HidDeviceInfo::New(); device_info->guid = kTestGuid; @@ -138,10 +136,9 @@ TEST_F(HidServiceTest, RequestDevice) { NavigateAndCommit(GURL(kTestUrl)); - blink::mojom::HidServicePtr service; - contents()->GetMainFrame()->BinderRegistryForTesting().BindInterface( - blink::mojom::HidService::Name_, - mojo::MakeRequest(&service).PassMessagePipe()); + mojo::Remote<blink::mojom::HidService> service; + contents()->GetMainFrame()->GetHidService( + service.BindNewPipeAndPassReceiver()); auto device_info = device::mojom::HidDeviceInfo::New(); device_info->guid = kTestGuid; @@ -168,10 +165,9 @@ TEST_F(HidServiceTest, OpenAndCloseHidConnection) { NavigateAndCommit(GURL(kTestUrl)); - blink::mojom::HidServicePtr service; - contents()->GetMainFrame()->BinderRegistryForTesting().BindInterface( - blink::mojom::HidService::Name_, - mojo::MakeRequest(&service).PassMessagePipe()); + mojo::Remote<blink::mojom::HidService> service; + contents()->GetMainFrame()->GetHidService( + service.BindNewPipeAndPassReceiver()); auto device_info = device::mojom::HidDeviceInfo::New(); device_info->guid = kTestGuid;
diff --git a/content/browser/navigation_browsertest.cc b/content/browser/navigation_browsertest.cc index 163fc3f..5f9b3be 100644 --- a/content/browser/navigation_browsertest.cc +++ b/content/browser/navigation_browsertest.cc
@@ -2514,8 +2514,6 @@ // 5. Start history cross-document navigation, cancelling 4. EXPECT_TRUE(ExecJs(shell()->web_contents(), "history.back()")); - // TODO(arthursonzogni): The embedder_url_tracker should update the visible - // URL here. { EXPECT_EQ(url_b, shell()->web_contents()->GetVisibleURL()); EXPECT_EQ(url_b, embedder_url_tracker.url()); @@ -2537,9 +2535,6 @@ EXPECT_EQ(url_b, shell()->web_contents()->GetVisibleURL()); EXPECT_EQ(url_b, embedder_url_tracker.url()); } - - // TODO(https://crbug.com/998284): The URL tracked by the embedder should have - // been invalidated. At some point, |url_b| should be displayed, not |url_c|. } // Regression test for https://crbug.com/1001283
diff --git a/content/browser/renderer_interface_binders.cc b/content/browser/renderer_interface_binders.cc index cf4be3849..7a834a2 100644 --- a/content/browser/renderer_interface_binders.cc +++ b/content/browser/renderer_interface_binders.cc
@@ -12,7 +12,6 @@ #include "base/no_destructor.h" #include "base/task/post_task.h" #include "content/browser/child_process_security_policy_impl.h" -#include "content/browser/content_index/content_index_service_impl.h" #include "content/browser/cookie_store/cookie_store_context.h" #include "content/browser/gpu/gpu_process_host.h" #include "content/browser/native_file_system/native_file_system_manager_impl.h" @@ -248,8 +247,6 @@ host->GetBrowserContext()->GetVideoDecodePerfHistory()->BindRequest( std::move(request)); })); - parameterized_binder_registry_.AddInterface( - base::BindRepeating(&ContentIndexServiceImpl::Create)); } RendererInterfaceBinders& GetRendererInterfaceBinders() {
diff --git a/content/browser/scheduler/browser_io_thread_delegate.cc b/content/browser/scheduler/browser_io_thread_delegate.cc index ec65f10a..cb4233c 100644 --- a/content/browser/scheduler/browser_io_thread_delegate.cc +++ b/content/browser/scheduler/browser_io_thread_delegate.cc
@@ -4,6 +4,7 @@ #include "content/browser/scheduler/browser_io_thread_delegate.h" +#include "base/message_loop/message_pump.h" #include "base/message_loop/message_pump_type.h" #include "base/task/sequence_manager/sequence_manager.h" #include "base/task/sequence_manager/task_queue.h"
diff --git a/content/browser/service_worker/service_worker_context_wrapper.cc b/content/browser/service_worker/service_worker_context_wrapper.cc index 0b458608..2278bb9 100644 --- a/content/browser/service_worker/service_worker_context_wrapper.cc +++ b/content/browser/service_worker/service_worker_context_wrapper.cc
@@ -18,6 +18,7 @@ #include "base/lazy_instance.h" #include "base/location.h" #include "base/logging.h" +#include "base/run_loop.h" #include "base/single_thread_task_runner.h" #include "base/task/post_task.h" #include "base/threading/thread_task_runner_handle.h"
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc index 1ede4ab..bf608031 100644 --- a/content/browser/storage_partition_impl.cc +++ b/content/browser/storage_partition_impl.cc
@@ -18,6 +18,7 @@ #include "base/command_line.h" #include "base/location.h" #include "base/optional.h" +#include "base/run_loop.h" #include "base/sequenced_task_runner.h" #include "base/single_thread_task_runner.h" #include "base/strings/utf_string_conversions.h"
diff --git a/content/browser/tracing/background_memory_tracing_observer.cc b/content/browser/tracing/background_memory_tracing_observer.cc index cf1f294..29c7996 100644 --- a/content/browser/tracing/background_memory_tracing_observer.cc +++ b/content/browser/tracing/background_memory_tracing_observer.cc
@@ -34,6 +34,7 @@ ->RequestGlobalDumpAndAppendToTrace( base::trace_event::MemoryDumpType::EXPLICITLY_TRIGGERED, base::trace_event::MemoryDumpLevelOfDetail::BACKGROUND, + base::trace_event::MemoryDumpDeterminism::NONE, memory_instrumentation::MemoryInstrumentation:: RequestGlobalMemoryDumpAndAppendToTraceCallback()); }
diff --git a/content/browser/tracing/memory_tracing_browsertest.cc b/content/browser/tracing/memory_tracing_browsertest.cc index a5041492..8409d63f 100644 --- a/content/browser/tracing/memory_tracing_browsertest.cc +++ b/content/browser/tracing/memory_tracing_browsertest.cc
@@ -27,6 +27,7 @@ #include "testing/gmock/include/gmock/gmock.h" using base::trace_event::MemoryDumpArgs; +using base::trace_event::MemoryDumpDeterminism; using base::trace_event::MemoryDumpLevelOfDetail; using base::trace_event::MemoryDumpManager; using base::trace_event::MemoryDumpType; @@ -85,10 +86,12 @@ RequestGlobalDumpAndAppendToTrace, base::Unretained( memory_instrumentation::MemoryInstrumentation::GetInstance()), - dump_type, level_of_detail, std::move(callback))); + dump_type, level_of_detail, MemoryDumpDeterminism::NONE, + std::move(callback))); } else { memory_instrumentation::MemoryInstrumentation::GetInstance() ->RequestGlobalDumpAndAppendToTrace(dump_type, level_of_detail, + MemoryDumpDeterminism::NONE, std::move(callback)); } }
diff --git a/content/browser/tracing/tracing_controller_impl.cc b/content/browser/tracing/tracing_controller_impl.cc index a0226541..0123f12 100644 --- a/content/browser/tracing/tracing_controller_impl.cc +++ b/content/browser/tracing/tracing_controller_impl.cc
@@ -14,6 +14,7 @@ #include "base/cpu.h" #include "base/files/file_tracing.h" #include "base/logging.h" +#include "base/run_loop.h" #include "base/strings/string_split.h" #include "base/strings/stringprintf.h" #include "base/system/sys_info.h"
diff --git a/content/browser/url_loader_factory_getter.cc b/content/browser/url_loader_factory_getter.cc index 377ac68..9f06bfc 100644 --- a/content/browser/url_loader_factory_getter.cc +++ b/content/browser/url_loader_factory_getter.cc
@@ -12,6 +12,7 @@ #include "base/command_line.h" #include "base/feature_list.h" #include "base/lazy_instance.h" +#include "base/run_loop.h" #include "base/task/post_task.h" #include "content/browser/storage_partition_impl.h" #include "content/common/service_worker/service_worker_utils.h"
diff --git a/content/browser/web_contents/web_contents_impl_browsertest.cc b/content/browser/web_contents/web_contents_impl_browsertest.cc index 62b55d15..ba9df57 100644 --- a/content/browser/web_contents/web_contents_impl_browsertest.cc +++ b/content/browser/web_contents/web_contents_impl_browsertest.cc
@@ -3430,15 +3430,8 @@ EXPECT_TRUE(delete_rfh_c.deleted()); } -// http://crbug.com/990854 -#if defined(OS_ANDROID) -#define MAYBE_PopupWindowBrowserNavResumeLoad \ - DISABLED_PopupWindowBrowserNavResumeLoad -#else -#define MAYBE_PopupWindowBrowserNavResumeLoad PopupWindowBrowserNavResumeLoad -#endif IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, - MAYBE_PopupWindowBrowserNavResumeLoad) { + PopupWindowBrowserNavResumeLoad) { // This test verifies a pop up that requires navigation from browser side // works with a delegate that delays navigations of pop ups. // Create a file: scheme pop up from a file: scheme page, which requires @@ -3460,8 +3453,7 @@ ShellAddedObserver new_shell_observer; bool success = false; EXPECT_TRUE(ExecuteScriptAndExtractBool( - shell(), - "window.domAutomationController.send(clickDeadFileNewWindowLink());", + shell(), "window.domAutomationController.send(clickLinkToSelf());", &success)); new_shell = new_shell_observer.GetShell(); new_contents = new_shell->web_contents(); @@ -3472,10 +3464,8 @@ EXPECT_FALSE(new_contents->GetDelegate()); new_contents->SetDelegate(new_shell); new_contents->ResumeLoadingCreatedWebContents(); - // Dead file link may or may not load depending on OS. The result is not - // relevant for this test, so not checking the the result. WaitForLoadStop(new_contents); - EXPECT_TRUE(new_contents->GetLastCommittedURL().SchemeIs("file")); + EXPECT_EQ(url, new_contents->GetLastCommittedURL()); } namespace {
diff --git a/content/child/blink_platform_impl.cc b/content/child/blink_platform_impl.cc index ba8cff1..8616e38 100644 --- a/content/child/blink_platform_impl.cc +++ b/content/child/blink_platform_impl.cc
@@ -160,10 +160,6 @@ return IDS_AX_MEDIA_TOUCHLESS_SEEK_ACTION; case WebLocalizedString::kAXMediaTouchLessVolumeAction: return IDS_AX_MEDIA_TOUCHLESS_VOLUME_ACTION; - case WebLocalizedString::kCalendarClear: - return IDS_FORM_CALENDAR_CLEAR; - case WebLocalizedString::kCalendarToday: - return IDS_FORM_CALENDAR_TODAY; case WebLocalizedString::kDetailsLabel: return IDS_DETAILS_WITHOUT_SUMMARY_LABEL; case WebLocalizedString::kFileButtonNoFileSelectedLabel:
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc index eb46ac8d..f77550f 100644 --- a/content/child/runtime_features.cc +++ b/content/child/runtime_features.cc
@@ -515,9 +515,6 @@ WebRuntimeFeatures::EnableSkipTouchEventFilter( base::FeatureList::IsEnabled(features::kSkipTouchEventFilter)); - WebRuntimeFeatures::EnableStaleWhileRevalidate( - base::FeatureList::IsEnabled(features::kStaleWhileRevalidate)); - if (!base::FeatureList::IsEnabled(features::kSmsReceiver)) WebRuntimeFeatures::EnableSmsReceiver(false);
diff --git a/content/public/app/content_browser_manifest.cc b/content/public/app/content_browser_manifest.cc index fbd3e3d..d3e7bf7 100644 --- a/content/public/app/content_browser_manifest.cc +++ b/content/public/app/content_browser_manifest.cc
@@ -199,7 +199,7 @@ "navigation:service_worker", "renderer", std::set<const char*>{ "blink.mojom.CacheStorage", "blink.mojom.CookieStore", - "blink.mojom.ContentIndexService", "blink.mojom.IDBFactory", + "blink.mojom.IDBFactory", "blink.mojom.NativeFileSystemManager", "blink.mojom.NotificationService", "blink.mojom.PermissionService", @@ -219,13 +219,10 @@ "blink.mojom.AnchorElementMetricsHost", "blink.mojom.CacheStorage", "blink.mojom.ColorChooserFactory", - "blink.mojom.ContactsManager", - "blink.mojom.ContentIndexService", "blink.mojom.DateTimeChooser", "blink.mojom.DisplayCutoutHost", "blink.mojom.DedicatedWorkerHostFactory", "blink.mojom.GeolocationService", - "blink.mojom.HidService", "blink.mojom.IDBFactory", "blink.mojom.InsecureInputService", "blink.mojom.KeyboardLockService", @@ -246,7 +243,6 @@ "blink.mojom.TextSuggestionHost", "blink.mojom.UnhandledTapNotifier", "blink.mojom.WakeLockService", - "blink.mojom.WebBluetoothService", "blink.mojom.WebUsbService", "content.mojom.BrowserTarget", "content.mojom.InputInjector",
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index ee197275..5bb008c71 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc
@@ -525,11 +525,6 @@ const base::Feature kSpareRendererForSitePerProcess{ "SpareRendererForSitePerProcess", base::FEATURE_ENABLED_BY_DEFAULT}; -// Enables StaleWhileRevalidate support. -// https://www.chromestatus.com/features/5050913014153216 -const base::Feature kStaleWhileRevalidate{"StaleWhileRevalidate", - base::FEATURE_ENABLED_BY_DEFAULT}; - // Enables Storage Pressure notifications and settings pages. const base::Feature kStoragePressureUI{"StoragePressureUI", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h index a63f89e1..b8aaa14 100644 --- a/content/public/common/content_features.h +++ b/content/public/common/content_features.h
@@ -118,7 +118,6 @@ CONTENT_EXPORT extern const base::Feature kSignedHTTPExchangePingValidity; CONTENT_EXPORT extern const base::Feature kSmsReceiver; CONTENT_EXPORT extern const base::Feature kSpareRendererForSitePerProcess; -CONTENT_EXPORT extern const base::Feature kStaleWhileRevalidate; CONTENT_EXPORT extern const base::Feature kStoragePressureUI; CONTENT_EXPORT extern const base::Feature kStrictOriginIsolation; CONTENT_EXPORT extern const base::Feature kSyntheticPointerActions;
diff --git a/content/public/test/content_browser_test.cc b/content/public/test/content_browser_test.cc index 834fc446..d912fc4 100644 --- a/content/public/test/content_browser_test.cc +++ b/content/public/test/content_browser_test.cc
@@ -6,7 +6,7 @@ #include "base/command_line.h" #include "base/logging.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_loop_current.h" #include "base/path_service.h" #include "base/run_loop.h" #include "build/build_config.h"
diff --git a/content/public/test/test_download_http_response.cc b/content/public/test/test_download_http_response.cc index 5235b06..02cffd5 100644 --- a/content/public/test/test_download_http_response.cc +++ b/content/public/test/test_download_http_response.cc
@@ -11,6 +11,7 @@ #include "base/lazy_instance.h" #include "base/logging.h" #include "base/numerics/ranges.h" +#include "base/run_loop.h" #include "base/single_thread_task_runner.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h"
diff --git a/content/public/test/url_loader_interceptor.cc b/content/public/test/url_loader_interceptor.cc index 848b0de..a548ec10 100644 --- a/content/public/test/url_loader_interceptor.cc +++ b/content/public/test/url_loader_interceptor.cc
@@ -12,6 +12,7 @@ #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/path_service.h" +#include "base/run_loop.h" #include "base/synchronization/lock.h" #include "base/task/post_task.h" #include "base/test/bind_test_util.h"
diff --git a/content/renderer/service_worker/service_worker_context_client.cc b/content/renderer/service_worker/service_worker_context_client.cc index cd93266..fd1a5da 100644 --- a/content/renderer/service_worker/service_worker_context_client.cc +++ b/content/renderer/service_worker/service_worker_context_client.cc
@@ -199,19 +199,6 @@ std::move(receiver)); } -void ServiceWorkerContextClient::WorkerContextFailedToStartOnInitiatorThread() { - DCHECK(initiator_thread_task_runner_->RunsTasksInCurrentSequence()); - DCHECK(!proxy_); - - instance_host_->OnStopped(); - - TRACE_EVENT_NESTABLE_ASYNC_END1( - "ServiceWorker", "ServiceWorkerContextClient", this, "Status", - "WorkerContextFailedToStartOnInitiatorThread"); - - owner_->WorkerContextDestroyed(); -} - void ServiceWorkerContextClient::FailedToLoadClassicScript() { DCHECK(worker_task_runner_->RunsTasksInCurrentSequence()); TRACE_EVENT_NESTABLE_ASYNC_END1("ServiceWorker", "LOAD_SCRIPT", this,
diff --git a/content/renderer/service_worker/service_worker_context_client.h b/content/renderer/service_worker/service_worker_context_client.h index 645c59f..2e0336e9 100644 --- a/content/renderer/service_worker/service_worker_context_client.h +++ b/content/renderer/service_worker/service_worker_context_client.h
@@ -125,7 +125,6 @@ void WorkerReadyForInspectionOnInitiatorThread( mojo::ScopedMessagePipeHandle devtools_agent_ptr_info, mojo::ScopedMessagePipeHandle devtools_agent_host_request) override; - void WorkerContextFailedToStartOnInitiatorThread() override; void FailedToLoadClassicScript() override; void FailedToFetchModuleScript() override; void WorkerScriptLoadedOnWorkerThread() override;
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 379681f..58862874 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -414,6 +414,7 @@ "//storage/common", "//testing/gmock", "//testing/gtest", + "//third_party/blink/public/strings:strings_grit", "//third_party/webrtc/api:libjingle_peerconnection_api", "//third_party/webrtc/api:media_stream_interface", "//third_party/webrtc/api:rtc_stats_api",
diff --git a/content/test/data/simple_links.html b/content/test/data/simple_links.html index 44c7db3..7703605 100644 --- a/content/test/data/simple_links.html +++ b/content/test/data/simple_links.html
@@ -40,8 +40,8 @@ return simulateClick(document.getElementById("view_source_link")); } - function clickDeadFileNewWindowLink() { - return simulateClick(document.getElementById("dead_file_new_window_link")); + function clickLinkToSelf() { + return simulateClick(document.getElementById("linkToSelf")); } function clickGoogleChromeLink() { @@ -55,6 +55,9 @@ <a href="view-source:about:blank" id="view_source_link">view-source:</a><br> <a href="title2.html" id="same_site_new_window_link" target="_blank">same-site new window</a> <a href="http://foo.com/title2.html" id="cross_site_new_window_link" target="_blank">cross-site new window</a> -<a href="file://" id="dead_file_new_window_link" target="_blank">dead-file new window</a> +<a href="" id="linkToSelf" target="_blank">self new window</a> +<script> + document.getElementById("linkToSelf").href = window.location.toString(); +</script> <a href="googlechrome://" id="google_chrome_link">googlechrome:</a></br> </html>
diff --git a/content/test/test_blink_web_unit_test_support.cc b/content/test/test_blink_web_unit_test_support.cc index d0785d60..97ffa0d5 100644 --- a/content/test/test_blink_web_unit_test_support.cc +++ b/content/test/test_blink_web_unit_test_support.cc
@@ -40,6 +40,7 @@ #include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/public/platform/web_url.h" #include "third_party/blink/public/platform/web_url_loader_factory.h" +#include "third_party/blink/public/strings/grit/blink_strings.h" #include "third_party/blink/public/web/blink.h" #include "v8/include/v8.h" @@ -230,9 +231,9 @@ return WebString::FromASCII("<<OtherMonthLabel>>"); case blink::WebLocalizedString::kOtherWeekLabel: return WebString::FromASCII("<<OtherWeekLabel>>"); - case blink::WebLocalizedString::kCalendarClear: + case IDS_FORM_CALENDAR_CLEAR: return WebString::FromASCII("<<CalendarClear>>"); - case blink::WebLocalizedString::kCalendarToday: + case IDS_FORM_CALENDAR_TODAY: return WebString::FromASCII("<<CalendarToday>>"); case blink::WebLocalizedString::kThisMonthButtonLabel: return WebString::FromASCII("<<ThisMonthLabel>>");
diff --git a/content/test/test_render_frame_host.cc b/content/test/test_render_frame_host.cc index bd02bab..a0e07f7 100644 --- a/content/test/test_render_frame_host.cc +++ b/content/test/test_render_frame_host.cc
@@ -527,10 +527,9 @@ WebBluetoothServiceImpl* TestRenderFrameHost::CreateWebBluetoothServiceForTesting() { - WebBluetoothServiceImpl* service = - RenderFrameHostImpl::CreateWebBluetoothService( - dummy_web_bluetooth_service_remote_.InitWithNewPipeAndPassReceiver()); - return service; + RenderFrameHostImpl::CreateWebBluetoothService( + dummy_web_bluetooth_service_remote_.InitWithNewPipeAndPassReceiver()); + return RenderFrameHostImpl::GetWebBluetoothServiceForTesting(); } void TestRenderFrameHost::SendFramePolicy(
diff --git a/extensions/browser/api/networking_private/networking_private_linux.h b/extensions/browser/api/networking_private/networking_private_linux.h index 4950a14..e5f9939 100644 --- a/extensions/browser/api/networking_private/networking_private_linux.h +++ b/extensions/browser/api/networking_private/networking_private_linux.h
@@ -11,6 +11,7 @@ #include <vector> #include "base/macros.h" +#include "base/observer_list.h" #include "base/threading/thread.h" #include "components/keyed_service/core/keyed_service.h" #include "extensions/browser/api/networking_private/networking_private_delegate.h"
diff --git a/extensions/shell/test/shell_test.cc b/extensions/shell/test/shell_test.cc index c7e70435..0498606 100644 --- a/extensions/shell/test/shell_test.cc +++ b/extensions/shell/test/shell_test.cc
@@ -7,7 +7,7 @@ #include "base/command_line.h" #include "base/files/file_path.h" #include "base/logging.h" -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_loop_current.h" #include "base/run_loop.h" #include "content/public/common/content_switches.h" #include "extensions/browser/extension_system.h"
diff --git a/fuchsia/http/http_service_unittest.cc b/fuchsia/http/http_service_unittest.cc index 628e2ef..3d024ea5 100644 --- a/fuchsia/http/http_service_unittest.cc +++ b/fuchsia/http/http_service_unittest.cc
@@ -7,6 +7,7 @@ #include "base/fuchsia/scoped_service_binding.h" #include "base/fuchsia/service_directory.h" +#include "base/message_loop/message_loop_current.h" #include "base/run_loop.h" #include "base/test/task_environment.h" #include "fuchsia/http/http_service_impl.h"
diff --git a/gin/test/v8_test.h b/gin/test/v8_test.h index 62796a8..73fdb3a3 100644 --- a/gin/test/v8_test.h +++ b/gin/test/v8_test.h
@@ -30,7 +30,7 @@ protected: // This is used during SetUp() to initialize instance_. virtual std::unique_ptr<IsolateHolder> CreateIsolateHolder() const; - base::test::SingleThreadTaskEnvironment task_environment_; + base::test::TaskEnvironment task_environment_; std::unique_ptr<IsolateHolder> instance_; v8::Persistent<v8::Context> context_;
diff --git a/gin/v8_isolate_memory_dump_provider.cc b/gin/v8_isolate_memory_dump_provider.cc index fe14263..4e328f1 100644 --- a/gin/v8_isolate_memory_dump_provider.cc +++ b/gin/v8_isolate_memory_dump_provider.cc
@@ -156,6 +156,10 @@ void V8IsolateMemoryDumpProvider::DumpHeapStatistics( const base::trace_event::MemoryDumpArgs& args, base::trace_event::ProcessMemoryDump* process_memory_dump) { + if (args.determinism == base::trace_event::MemoryDumpDeterminism::FORCE_GC) { + // Force GC in V8 using the same API as DevTools uses in "collectGarbage". + isolate_holder_->isolate()->LowMemoryNotification(); + } std::string isolate_name = base::StringPrintf( "isolate_0x%" PRIXPTR, reinterpret_cast<uintptr_t>(isolate_holder_->isolate()));
diff --git a/gin/v8_isolate_memory_dump_provider_unittest.cc b/gin/v8_isolate_memory_dump_provider_unittest.cc index 26962ee..b003a234 100644 --- a/gin/v8_isolate_memory_dump_provider_unittest.cc +++ b/gin/v8_isolate_memory_dump_provider_unittest.cc
@@ -6,6 +6,7 @@ #include <memory> +#include "base/task/thread_pool/thread_pool_instance.h" #include "base/threading/thread_task_runner_handle.h" #include "base/trace_event/process_memory_dump.h" #include "base/trace_event/trace_event.h" @@ -159,4 +160,29 @@ ASSERT_TRUE(did_dump_external_scripts_size); } +// Tests that a deterministic memory dump request performs a GC. +TEST_F(V8MemoryDumpProviderTest, Deterministic) { + base::trace_event::MemoryDumpArgs dump_args = { + base::trace_event::MemoryDumpLevelOfDetail::LIGHT, + base::trace_event::MemoryDumpDeterminism::FORCE_GC}; + std::unique_ptr<base::trace_event::ProcessMemoryDump> process_memory_dump( + new base::trace_event::ProcessMemoryDump(dump_args)); + + // Allocate an object that has only a weak reference. + v8::Global<v8::Object> weak_ref; + { + v8::HandleScope scope(instance_->isolate()); + v8::Local<v8::Object> object = v8::Object::New(instance_->isolate()); + weak_ref.Reset(instance_->isolate(), object); + weak_ref.SetWeak(); + } + + // Deterministic memory dump should trigger GC. + instance_->isolate_memory_dump_provider_for_testing()->OnMemoryDump( + dump_args, process_memory_dump.get()); + + // GC reclaimed the object. + ASSERT_TRUE(weak_ref.IsEmpty()); +} + } // namespace gin
diff --git a/gpu/ipc/service/gpu_watchdog_thread_unittest.cc b/gpu/ipc/service/gpu_watchdog_thread_unittest.cc index 407c9b5..6beb6aa 100644 --- a/gpu/ipc/service/gpu_watchdog_thread_unittest.cc +++ b/gpu/ipc/service/gpu_watchdog_thread_unittest.cc
@@ -4,6 +4,8 @@ #include "gpu/ipc/service/gpu_watchdog_thread_v2.h" +#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_loop_current.h" #include "base/power_monitor/power_monitor.h" #include "base/power_monitor/power_monitor_source.h" #include "base/test/power_monitor_test_base.h"
diff --git a/ios/chrome/app/application_delegate/BUILD.gn b/ios/chrome/app/application_delegate/BUILD.gn index 7027368..3cb6f0c 100644 --- a/ios/chrome/app/application_delegate/BUILD.gn +++ b/ios/chrome/app/application_delegate/BUILD.gn
@@ -102,6 +102,7 @@ deps = [ ":application_delegate", "//base", + "//build:branding_buildflags", "//components/crash/core/common", "//components/feature_engagement", "//components/handoff",
diff --git a/ios/chrome/app/application_delegate/app_state.mm b/ios/chrome/app/application_delegate/app_state.mm index a97ba2a2..1f6ab47 100644 --- a/ios/chrome/app/application_delegate/app_state.mm +++ b/ios/chrome/app/application_delegate/app_state.mm
@@ -30,8 +30,8 @@ #include "ios/chrome/browser/application_context.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/chrome_constants.h" -#include "ios/chrome/browser/crash_loop_detection_util.h" #include "ios/chrome/browser/crash_report/breakpad_helper.h" +#include "ios/chrome/browser/crash_report/crash_loop_detection_util.h" #import "ios/chrome/browser/device_sharing/device_sharing_manager.h" #include "ios/chrome/browser/feature_engagement/tracker_factory.h" #import "ios/chrome/browser/geolocation/omnibox_geolocation_config.h"
diff --git a/ios/chrome/app/application_delegate/metrics_mediator.mm b/ios/chrome/app/application_delegate/metrics_mediator.mm index 1d2506c9b..98a1a74 100644 --- a/ios/chrome/app/application_delegate/metrics_mediator.mm +++ b/ios/chrome/app/application_delegate/metrics_mediator.mm
@@ -9,6 +9,7 @@ #include "base/metrics/user_metrics_action.h" #include "base/strings/sys_string_conversions.h" #include "base/task/post_task.h" +#include "build/branding_buildflags.h" #include "components/crash/core/common/crash_keys.h" #include "components/metrics/metrics_pref_names.h" #include "components/metrics/metrics_service.h" @@ -191,7 +192,7 @@ - (BOOL)areMetricsEnabled { // If this if-def changes, it needs to be changed in // IOSChromeMainParts::IsMetricsReportingEnabled and settings_egtest.mm. -#if defined(GOOGLE_CHROME_BUILD) +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) BOOL optIn = GetApplicationContext()->GetLocalState()->GetBoolean( metrics::prefs::kMetricsReportingEnabled); #else
diff --git a/ios/chrome/app/main_controller.mm b/ios/chrome/app/main_controller.mm index 026f93f..f1640ff6 100644 --- a/ios/chrome/app/main_controller.mm +++ b/ios/chrome/app/main_controller.mm
@@ -72,8 +72,8 @@ #include "ios/chrome/browser/chrome_url_constants.h" #import "ios/chrome/browser/chrome_url_util.h" #include "ios/chrome/browser/content_settings/host_content_settings_map_factory.h" -#include "ios/chrome/browser/crash_loop_detection_util.h" #include "ios/chrome/browser/crash_report/breakpad_helper.h" +#include "ios/chrome/browser/crash_report/crash_loop_detection_util.h" #import "ios/chrome/browser/crash_report/crash_restore_helper.h" #include "ios/chrome/browser/download/download_directory_util.h" #import "ios/chrome/browser/external_files/external_file_remover_factory.h"
diff --git a/ios/chrome/app/strings/ios_chromium_strings.grd b/ios/chrome/app/strings/ios_chromium_strings.grd index 4e1504b..166b803 100644 --- a/ios/chrome/app/strings/ios_chromium_strings.grd +++ b/ios/chrome/app/strings/ios_chromium_strings.grd
@@ -190,7 +190,7 @@ Your account does not work on Chromium. Please contact your domain administrator or use a regular Google Account to sign in. </message> <message name="IDS_IOS_LONG_PRESS_TOOLBAR_IPH_PROMOTION_VOICE_OVER" desc="Text to be read by VoiceOver when the LongPress Toolbar Tip is presented to the user. Read by Text-to-Speech."> - Chromium tip. For more tab options, press and hold the Show Tabs button in the toolbar, which is at the bottom or top of your screen. + Chromium tip. For more tab options, touch & hold the Show Tabs button in the toolbar, which is at the bottom or top of your screen. </message> <message name="IDS_IOS_MANAGE_SYNC_DATA_FROM_CHROME_SYNC_TITLE" desc="Title for the cell to open 'Data from Chromium sync' web page where the user can control all their data data from sync."> Data from Chromium sync
diff --git a/ios/chrome/app/strings/ios_google_chrome_strings.grd b/ios/chrome/app/strings/ios_google_chrome_strings.grd index a6c44dd..5057cbc 100644 --- a/ios/chrome/app/strings/ios_google_chrome_strings.grd +++ b/ios/chrome/app/strings/ios_google_chrome_strings.grd
@@ -190,7 +190,7 @@ Your account does not work on Google Chrome. Please contact your domain administrator or use a regular Google Account to sign in. </message> <message name="IDS_IOS_LONG_PRESS_TOOLBAR_IPH_PROMOTION_VOICE_OVER" desc="Text to be read by VoiceOver when the LongPress Toolbar Tip is presented to the user. Read by Text-to-Speech."> - Chrome tip. For more tab options, press and hold the Show Tabs button in the toolbar, which is at the bottom or top of your screen. + Chrome tip. For more tab options, touch & hold the Show Tabs button in the toolbar, which is at the bottom or top of your screen. </message> <message name="IDS_IOS_MANAGE_SYNC_DATA_FROM_CHROME_SYNC_TITLE" desc="Title for the cell to open 'Data from Chrome sync' web page where the user can control all their data data from sync."> Data from Chrome sync
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd index 2175231f7..6c9f0fc 100644 --- a/ios/chrome/app/strings/ios_strings.grd +++ b/ios/chrome/app/strings/ios_strings.grd
@@ -846,7 +846,7 @@ Reopen Closed Tab </message> <message name="IDS_IOS_LONG_PRESS_TOOLBAR_IPH_PROMOTION_TEXT" desc="Text for the LongPress Toolbar Tip in-product help promotion, explaining that the user can long press on the toolbar's button to display more options. [iOS only]"> - Press and hold for more tab options + Touch & hold for more tab options </message> <message name="IDS_IOS_MANAGE_YOUR_GOOGLE_ACCOUNT_TITLE" desc="Title for the view in the Settings to open 'Google Account' web page."> Manage Your Google Account
diff --git a/ios/chrome/browser/BUILD.gn b/ios/chrome/browser/BUILD.gn index c72886e..fd91500 100644 --- a/ios/chrome/browser/BUILD.gn +++ b/ios/chrome/browser/BUILD.gn
@@ -41,8 +41,6 @@ "chrome_switches.h", "chrome_url_util.h", "chrome_url_util.mm", - "crash_loop_detection_util.h", - "crash_loop_detection_util.mm", "file_metadata_util.h", "file_metadata_util.mm", "install_time_util.h", @@ -255,7 +253,6 @@ "browser_about_rewriter_unittest.cc", "chrome_browser_provider_observer_bridge_unittest.mm", "chrome_url_util_unittest.mm", - "crash_loop_detection_util_unittest.mm", "install_time_util_unittest.mm", "installation_notifier_unittest.mm", "notification_promo_unittest.cc",
diff --git a/ios/chrome/browser/crash_report/BUILD.gn b/ios/chrome/browser/crash_report/BUILD.gn index 1f29f88b..fca86732 100644 --- a/ios/chrome/browser/crash_report/BUILD.gn +++ b/ios/chrome/browser/crash_report/BUILD.gn
@@ -6,6 +6,8 @@ sources = [ "breakpad_helper.h", "breakpad_helper.mm", + "crash_loop_detection_util.h", + "crash_loop_detection_util.mm", "crash_report_multi_parameter.h", "crash_report_multi_parameter.mm", "crash_report_user_application_state.h", @@ -73,6 +75,7 @@ testonly = true sources = [ "breakpad_helper_unittest.mm", + "crash_loop_detection_util_unittest.mm", "crash_restore_helper_unittest.mm", ] deps = [
diff --git a/ios/chrome/browser/crash_loop_detection_util.h b/ios/chrome/browser/crash_report/crash_loop_detection_util.h similarity index 86% rename from ios/chrome/browser/crash_loop_detection_util.h rename to ios/chrome/browser/crash_report/crash_loop_detection_util.h index ec8692f..2077ec53 100644 --- a/ios/chrome/browser/crash_loop_detection_util.h +++ b/ios/chrome/browser/crash_report/crash_loop_detection_util.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef IOS_CHROME_BROWSER_CRASH_LOOP_DETECTION_UTIL_H_ -#define IOS_CHROME_BROWSER_CRASH_LOOP_DETECTION_UTIL_H_ +#ifndef IOS_CHROME_BROWSER_CRASH_REPORT_CRASH_LOOP_DETECTION_UTIL_H_ +#define IOS_CHROME_BROWSER_CRASH_REPORT_CRASH_LOOP_DETECTION_UTIL_H_ namespace crash_util { @@ -30,4 +30,4 @@ } // namespace crash_util -#endif // IOS_CHROME_BROWSER_CRASH_LOOP_DETECTION_UTIL_H_ +#endif // IOS_CHROME_BROWSER_CRASH_REPORT_CRASH_LOOP_DETECTION_UTIL_H_
diff --git a/ios/chrome/browser/crash_loop_detection_util.mm b/ios/chrome/browser/crash_report/crash_loop_detection_util.mm similarity index 95% rename from ios/chrome/browser/crash_loop_detection_util.mm rename to ios/chrome/browser/crash_report/crash_loop_detection_util.mm index 0de92d6c..dd72964 100644 --- a/ios/chrome/browser/crash_loop_detection_util.mm +++ b/ios/chrome/browser/crash_report/crash_loop_detection_util.mm
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ios/chrome/browser/crash_loop_detection_util.h" +#include "ios/chrome/browser/crash_report/crash_loop_detection_util.h" #import <Foundation/Foundation.h>
diff --git a/ios/chrome/browser/crash_loop_detection_util_unittest.mm b/ios/chrome/browser/crash_report/crash_loop_detection_util_unittest.mm similarity index 95% rename from ios/chrome/browser/crash_loop_detection_util_unittest.mm rename to ios/chrome/browser/crash_report/crash_loop_detection_util_unittest.mm index 4fa5fcd..0720bf5f5 100644 --- a/ios/chrome/browser/crash_loop_detection_util_unittest.mm +++ b/ios/chrome/browser/crash_report/crash_loop_detection_util_unittest.mm
@@ -4,7 +4,7 @@ #import <Foundation/Foundation.h> -#include "ios/chrome/browser/crash_loop_detection_util.h" +#include "ios/chrome/browser/crash_report/crash_loop_detection_util.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h"
diff --git a/ios/chrome/browser/history/history_tab_helper_unittest.mm b/ios/chrome/browser/history/history_tab_helper_unittest.mm index d2ad8c0..f58ffee 100644 --- a/ios/chrome/browser/history/history_tab_helper_unittest.mm +++ b/ios/chrome/browser/history/history_tab_helper_unittest.mm
@@ -202,3 +202,23 @@ QueryURL(ntp_url); EXPECT_NE(ntp_url, latest_row_result_.url()); } + +// Tests that a file:// URL isn't added to history. +TEST_F(HistoryTabHelperTest, TestFileNotAdded) { + HistoryTabHelper* helper = HistoryTabHelper::FromWebState(&web_state_); + ASSERT_TRUE(helper); + + std::unique_ptr<web::NavigationItem> item = web::NavigationItem::Create(); + GURL test_url("https://www.google.com/"); + item->SetVirtualURL(test_url); + AddVisitForURL(test_url); + QueryURL(test_url); + EXPECT_EQ(test_url, latest_row_result_.url()); + + item = web::NavigationItem::Create(); + GURL file_url("file://path/to/file"); + item->SetVirtualURL(file_url); + AddVisitForURL(file_url); + QueryURL(file_url); + EXPECT_NE(file_url, latest_row_result_.url()); +}
diff --git a/ios/chrome/browser/history/history_utils.cc b/ios/chrome/browser/history/history_utils.cc index 59aeec1..1cc3dd7 100644 --- a/ios/chrome/browser/history/history_utils.cc +++ b/ios/chrome/browser/history/history_utils.cc
@@ -17,16 +17,17 @@ if (!url.is_valid()) return false; + // TODO(crbug.com/1007192): Don't store the URL as we aren't persiting the + // files. Maybe we should start persisting the files and store the URL. // TODO: We should allow ChromeUIScheme URLs if they have been explicitly // typed. Right now, however, these are marked as typed even when triggered // by a shortcut or menu action. if (url.SchemeIs(url::kJavaScriptScheme) || url.SchemeIs(dom_distiller::kDomDistillerScheme) || - url.SchemeIs(kChromeUIScheme)) + url.SchemeIs(kChromeUIScheme) || url.SchemeIs(url::kFileScheme)) return false; - // Allow all about: and chrome: URLs except about:blank|newtab, since the user - // may like to see "chrome://version", etc. in their history and autocomplete. + // Allow all about: URLs except about:blank|newtab. if (url == url::kAboutBlankURL || url == kChromeUIAboutNewTabURL) return false;
diff --git a/ios/chrome/browser/signin/authentication_service.h b/ios/chrome/browser/signin/authentication_service.h index 2628a49..33b9bb7 100644 --- a/ios/chrome/browser/signin/authentication_service.h +++ b/ios/chrome/browser/signin/authentication_service.h
@@ -145,9 +145,9 @@ // |should_store_accounts_| is true, it will also store the available accounts // in the browser state prefs. // - // |should_prompt| indicates whether the user should be prompted with the - // resign-in infobar if the method signs out. - void HandleIdentityListChanged(bool should_prompt); + // |in_foreground| indicates whether the application was in foreground when + // the identity list change notification was received. + void HandleIdentityListChanged(bool in_foreground); // Verifies that the authenticated user is still associated with a valid // ChromeIdentity. This method must only be called when the user is @@ -172,9 +172,10 @@ // Computes whether the available accounts have changed since the last time // they were stored in the browser state prefs. - // |should_prompt| indicates whether the user should be prompted if the - // authenticated identity was removed. - void ComputeHaveAccountsChanged(bool should_prompt); + // + // This method should only be called when the application is in background + // or when the application is entering foregorund. + void UpdateHaveAccountsChangedWhileInBackground(); // signin::IdentityManager::Observer implementation. void OnEndBatchOfRefreshTokenStateChanges() override;
diff --git a/ios/chrome/browser/signin/authentication_service.mm b/ios/chrome/browser/signin/authentication_service.mm index 7dfb493..f2837852 100644 --- a/ios/chrome/browser/signin/authentication_service.mm +++ b/ios/chrome/browser/signin/authentication_service.mm
@@ -130,9 +130,10 @@ // As the SSO library does not send notification when the app is in the // background, reload the credentials and check whether any accounts have - // changed (both are done by calling ComputeHaveAccountsChanged). After - // that, save the current list of accounts. - ComputeHaveAccountsChanged(/*should_prompt=*/true); + // changed (both are done by |UpdateHaveAccountsChangedWhileInBackground|). + // After that, save the current list of accounts. + UpdateHaveAccountsChangedWhileInBackground(); + StoreAccountsInPrefs(); if (IsAuthenticated()) { bool sync_enabled = sync_setup_service_->IsSyncEnabled(); @@ -186,7 +187,7 @@ return pref_service_->GetBoolean(prefs::kSigninShouldPromptForSigninAgain); } -void AuthenticationService::ComputeHaveAccountsChanged(bool should_prompt) { +void AuthenticationService::UpdateHaveAccountsChangedWhileInBackground() { // Load accounts from preference before synchronizing the accounts with // the system, otherwiser we would never detect any changes to the list // of accounts. @@ -195,7 +196,10 @@ // Reload credentials to ensure the accounts from the token service are // up-to-date. - ReloadCredentialsFromIdentities(should_prompt); + // As UpdateHaveAccountsChangedWhileInBackground is only called while the + // application is in background or when it enters foreground, |should_prompt| + // must be set to true. + ReloadCredentialsFromIdentities(/*should_prompt=*/true); std::vector<CoreAccountInfo> new_accounts_info = identity_manager_->GetAccountsWithRefreshTokens(); @@ -422,13 +426,11 @@ // the authenticated user at this time may lead to crashes (e.g. // http://crbug.com/398431 ). // Handle the change of the identity list on the next message loop cycle. - // If the identity list changed while the authentication service was in - // background, the user should be warned about it. base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&AuthenticationService::HandleIdentityListChanged, GetWeakPtr(), - !identity_manager_observer_.IsObservingSources())); + identity_manager_observer_.IsObservingSources())); } bool AuthenticationService::HandleMDMNotification(ChromeIdentity* identity, @@ -492,8 +494,16 @@ identity_service_observer_.RemoveAll(); } -void AuthenticationService::HandleIdentityListChanged(bool should_prompt) { - ComputeHaveAccountsChanged(should_prompt); +void AuthenticationService::HandleIdentityListChanged(bool in_foreground) { + // Only notify the user about an identity change notification if the + // application was in background. + if (in_foreground) { + // Do not update the have accounts change state when in foreground. + ReloadCredentialsFromIdentities(/*should_prompt=*/false); + return; + } + + UpdateHaveAccountsChangedWhileInBackground(); } void AuthenticationService::HandleForgottenIdentity(
diff --git a/ios/chrome/browser/signin/authentication_service_unittest.mm b/ios/chrome/browser/signin/authentication_service_unittest.mm index 74d6866..52dd32a 100644 --- a/ios/chrome/browser/signin/authentication_service_unittest.mm +++ b/ios/chrome/browser/signin/authentication_service_unittest.mm
@@ -301,11 +301,11 @@ EXPECT_EQ("fooID", accounts[2].account_id); } -TEST_F(AuthenticationServiceTest, HaveAccountsNotChangedDefault) { +TEST_F(AuthenticationServiceTest, HaveAccountsChanged_Default) { EXPECT_FALSE(authentication_service()->HaveAccountsChanged()); } -TEST_F(AuthenticationServiceTest, HaveAccountsNotChanged) { +TEST_F(AuthenticationServiceTest, HaveAccountsChanged_NoChange) { SetExpectationsForSignIn(); authentication_service()->SignIn(identity(0)); @@ -313,45 +313,87 @@ FireIdentityListChanged(); base::RunLoop().RunUntilIdle(); - // Simulate a switching to background and back to foreground. + // If an account is added while the application is in foreground, then the + // have accounts changed state should stay false. + EXPECT_FALSE(authentication_service()->HaveAccountsChanged()); + + // Backgrounding the app should not change the have accounts changed state. FireApplicationDidEnterBackground(); - FireApplicationWillEnterForeground(); + EXPECT_FALSE(authentication_service()->HaveAccountsChanged()); + // Foregrounding the app should not change the have accounts changed state. + FireApplicationWillEnterForeground(); EXPECT_FALSE(authentication_service()->HaveAccountsChanged()); } -TEST_F(AuthenticationServiceTest, HaveAccountsChanged) { +TEST_F(AuthenticationServiceTest, HaveAccountsChanged_ChangedInBackground) { SetExpectationsForSignIn(); authentication_service()->SignIn(identity(0)); identity_service()->AddIdentities(@[ @"foo3" ]); FireIdentityListChanged(); base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(authentication_service()->HaveAccountsChanged()); // Simulate a switching to background and back to foreground, changing the - // accounts while in background. + // accounts while in background (no notification fired by |identity_service|). FireApplicationDidEnterBackground(); identity_service()->AddIdentities(@[ @"foo4" ]); FireApplicationWillEnterForeground(); - EXPECT_TRUE(authentication_service()->HaveAccountsChanged()); } -TEST_F(AuthenticationServiceTest, HaveAccountsChangedBackground) { +TEST_F(AuthenticationServiceTest, HaveAccountsChanged_CalledInBackground) { SetExpectationsForSignIn(); authentication_service()->SignIn(identity(0)); identity_service()->AddIdentities(@[ @"foo3" ]); FireIdentityListChanged(); base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(authentication_service()->HaveAccountsChanged()); // Simulate a switching to background, changing the accounts while in // background. FireApplicationDidEnterBackground(); identity_service()->AddIdentities(@[ @"foo4" ]); + FireIdentityListChanged(); base::RunLoop().RunUntilIdle(); - EXPECT_TRUE(authentication_service()->HaveAccountsChanged()); + + // Entering foreground should not change the have accounts changed state. + FireApplicationWillEnterForeground(); + EXPECT_TRUE(authentication_service()->HaveAccountsChanged()); +} + +// Regression test for http://crbug.com/1006717 +TEST_F(AuthenticationServiceTest, HaveAccountsChanged_ResetOntwoBackgrounds) { + SetExpectationsForSignIn(); + authentication_service()->SignIn(identity(0)); + + identity_service()->AddIdentities(@[ @"foo3" ]); + FireIdentityListChanged(); + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(authentication_service()->HaveAccountsChanged()); + + // Simulate a switching to background, changing the accounts while in + // background. + FireApplicationDidEnterBackground(); + + // Clear |kSigninLastAccounts| pref to simulate a case when the list of + // accounts in pref |kSigninLastAccounts| are no the same as the ones + browser_state_->GetPrefs()->ClearPref(prefs::kSigninLastAccounts); + + // When entering foreground, the have accounts changed state should be + // updated. + FireApplicationWillEnterForeground(); + EXPECT_TRUE(authentication_service()->HaveAccountsChanged()); + + // Backgrounding and foregrounding the application a second time should update + // the list of accounts in |kSigninLastAccounts| and should reset the have + // account changed state. + FireApplicationDidEnterBackground(); + FireApplicationWillEnterForeground(); + EXPECT_FALSE(authentication_service()->HaveAccountsChanged()); } TEST_F(AuthenticationServiceTest, IsAuthenticatedBackground) {
diff --git a/ios/chrome/browser/tabs/BUILD.gn b/ios/chrome/browser/tabs/BUILD.gn index 96c2a12..e07ce23 100644 --- a/ios/chrome/browser/tabs/BUILD.gn +++ b/ios/chrome/browser/tabs/BUILD.gn
@@ -62,6 +62,7 @@ "//ios/chrome/browser/browser_state", "//ios/chrome/browser/browser_state_metrics", "//ios/chrome/browser/complex_tasks", + "//ios/chrome/browser/crash_report", "//ios/chrome/browser/download", "//ios/chrome/browser/favicon", "//ios/chrome/browser/find_in_page",
diff --git a/ios/chrome/browser/tabs/tab_model.mm b/ios/chrome/browser/tabs/tab_model.mm index a351dde8..d58b598 100644 --- a/ios/chrome/browser/tabs/tab_model.mm +++ b/ios/chrome/browser/tabs/tab_model.mm
@@ -29,7 +29,7 @@ #include "ios/chrome/browser/browser_state_metrics/browser_state_metrics.h" #include "ios/chrome/browser/chrome_url_constants.h" #import "ios/chrome/browser/chrome_url_util.h" -#include "ios/chrome/browser/crash_loop_detection_util.h" +#include "ios/chrome/browser/crash_report/crash_loop_detection_util.h" #import "ios/chrome/browser/geolocation/omnibox_geolocation_controller.h" #import "ios/chrome/browser/main/browser_web_state_list_delegate.h" #import "ios/chrome/browser/metrics/tab_usage_recorder.h"
diff --git a/ios/chrome/browser/ui/bubble/bubble_presenter.mm b/ios/chrome/browser/ui/bubble/bubble_presenter.mm index dd7b716..211e870 100644 --- a/ios/chrome/browser/ui/bubble/bubble_presenter.mm +++ b/ios/chrome/browser/ui/bubble/bubble_presenter.mm
@@ -181,8 +181,8 @@ BubbleArrowDirection arrowDirection = IsSplitToolbarMode() ? BubbleArrowDirectionDown : BubbleArrowDirectionUp; - NSString* text = l10n_util::GetNSStringWithFixup( - IDS_IOS_LONG_PRESS_TOOLBAR_IPH_PROMOTION_TEXT); + NSString* text = + l10n_util::GetNSString(IDS_IOS_LONG_PRESS_TOOLBAR_IPH_PROMOTION_TEXT); CGPoint searchButtonAnchor = IsRegularXRegularSizeClass() ? [self anchorPointToGuide:kTabStripTabSwitcherGuide
diff --git a/ios/chrome/browser/ui/safe_mode/safe_mode_coordinator.mm b/ios/chrome/browser/ui/safe_mode/safe_mode_coordinator.mm index 9006d74..bb63ccd 100644 --- a/ios/chrome/browser/ui/safe_mode/safe_mode_coordinator.mm +++ b/ios/chrome/browser/ui/safe_mode/safe_mode_coordinator.mm
@@ -5,7 +5,7 @@ #import "ios/chrome/browser/ui/safe_mode/safe_mode_coordinator.h" #include "base/logging.h" -#include "ios/chrome/browser/crash_loop_detection_util.h" +#include "ios/chrome/browser/crash_report/crash_loop_detection_util.h" #import "ios/chrome/browser/ui/safe_mode/safe_mode_view_controller.h" #if !defined(__has_feature) || !__has_feature(objc_arc)
diff --git a/ios/web/navigation/navigation_context_impl.h b/ios/web/navigation/navigation_context_impl.h index a59d5b2..57bd959 100644 --- a/ios/web/navigation/navigation_context_impl.h +++ b/ios/web/navigation/navigation_context_impl.h
@@ -11,6 +11,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "base/timer/elapsed_timer.h" #import "ios/web/public/navigation/navigation_context.h" #include "url/gurl.h" @@ -61,6 +62,9 @@ void SetResponseHeaders( const scoped_refptr<net::HttpResponseHeaders>& response_headers); + // Get elapsed time since context was created. + base::TimeDelta GetElapsedTimeSinceCreation() const; + // Optional unique id of the navigation item associated with this navigaiton. int GetNavigationItemUniqueID() const; void SetNavigationItemUniqueID(int unique_id); @@ -133,6 +137,7 @@ bool is_native_content_presented_ = false; bool is_placeholder_navigation_ = false; NSString* mime_type_ = nil; + base::ElapsedTimer elapsed_timer_; // Holds pending navigation item in this object. Pending item is stored in // NavigationContext after context is created. The item is still stored in
diff --git a/ios/web/navigation/navigation_context_impl.mm b/ios/web/navigation/navigation_context_impl.mm index 2aa5f702..04715c7 100644 --- a/ios/web/navigation/navigation_context_impl.mm +++ b/ios/web/navigation/navigation_context_impl.mm
@@ -207,6 +207,10 @@ item_ = std::move(item); } +base::TimeDelta NavigationContextImpl::GetElapsedTimeSinceCreation() const { + return elapsed_timer_.Elapsed(); +} + NavigationContextImpl::NavigationContextImpl(WebState* web_state, const GURL& url, bool has_user_gesture, @@ -220,7 +224,8 @@ is_same_document_(false), error_(nil), response_headers_(nullptr), - is_renderer_initiated_(is_renderer_initiated) {} + is_renderer_initiated_(is_renderer_initiated), + elapsed_timer_(base::ElapsedTimer()) {} NavigationContextImpl::~NavigationContextImpl() = default;
diff --git a/ios/web/web_state/ui/crw_web_request_controller.mm b/ios/web/web_state/ui/crw_web_request_controller.mm index 29d10fd..8f79bee 100644 --- a/ios/web/web_state/ui/crw_web_request_controller.mm +++ b/ios/web/web_state/ui/crw_web_request_controller.mm
@@ -481,7 +481,18 @@ } else { // There is another pending navigation, so the state is still loading. } + self.webState->OnPageLoaded(currentURL, YES); + + if (context) { + if (context->IsRendererInitiated()) { + UMA_HISTOGRAM_TIMES("PLT.iOS.RendererInitiatedPageLoadTime", + context->GetElapsedTimeSinceCreation()); + } else { + UMA_HISTOGRAM_TIMES("PLT.iOS.BrowserInitiatedPageLoadTime", + context->GetElapsedTimeSinceCreation()); + } + } } // Reports Navigation.IOSWKWebViewSlowFastBackForward UMA. No-op if pending
diff --git a/ios/web_view/internal/passwords/mock_credentials_filter.h b/ios/web_view/internal/passwords/mock_credentials_filter.h index 324ead0..79f536d1 100644 --- a/ios/web_view/internal/passwords/mock_credentials_filter.h +++ b/ios/web_view/internal/passwords/mock_credentials_filter.h
@@ -25,8 +25,7 @@ bool ShouldSaveEnterprisePasswordHash( const autofill::PasswordForm& form) const override; void ReportFormLoginSuccess( - const password_manager::PasswordFormManagerInterface& form_manager) - const override; + const password_manager::PasswordFormManager& form_manager) const override; bool IsSyncAccountEmail(const std::string& username) const override; private:
diff --git a/ios/web_view/internal/passwords/mock_credentials_filter.mm b/ios/web_view/internal/passwords/mock_credentials_filter.mm index 20f7775..a650253 100644 --- a/ios/web_view/internal/passwords/mock_credentials_filter.mm +++ b/ios/web_view/internal/passwords/mock_credentials_filter.mm
@@ -30,7 +30,7 @@ } void MockCredentialsFilter::ReportFormLoginSuccess( - const password_manager::PasswordFormManagerInterface& form_manager) const {} + const password_manager::PasswordFormManager& form_manager) const {} bool MockCredentialsFilter::IsSyncAccountEmail( const std::string& username) const {
diff --git a/media/gpu/test/video_player/video_decoder_client.h b/media/gpu/test/video_player/video_decoder_client.h index 1d6fd5f..ad2003c7 100644 --- a/media/gpu/test/video_player/video_decoder_client.h +++ b/media/gpu/test/video_player/video_decoder_client.h
@@ -11,6 +11,7 @@ #include <vector> #include "base/macros.h" +#include "base/memory/weak_ptr.h" #include "base/sequence_checker.h" #include "base/threading/thread.h" #include "media/base/decode_status.h"
diff --git a/media/gpu/v4l2/v4l2_slice_video_decoder.cc b/media/gpu/v4l2/v4l2_slice_video_decoder.cc index 8fbfe7b..66e6595c 100644 --- a/media/gpu/v4l2/v4l2_slice_video_decoder.cc +++ b/media/gpu/v4l2/v4l2_slice_video_decoder.cc
@@ -227,14 +227,11 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); DVLOGF(2); - if (avd_) { - avd_->Reset(); - avd_ = nullptr; - } - // Call all pending decode callback. ClearPendingRequests(DecodeStatus::ABORTED); + avd_ = nullptr; + // Stop and Destroy device. StopStreamV4L2Queue(); if (input_queue_) { @@ -543,9 +540,6 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); DVLOGF(3); - if (avd_) - avd_->Reset(); - // Call all pending decode callback. ClearPendingRequests(DecodeStatus::ABORTED); @@ -568,6 +562,9 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); DVLOGF(3); + if (avd_) + avd_->Reset(); + // Clear output_request_queue_. while (!output_request_queue_.empty()) output_request_queue_.pop(); @@ -601,7 +598,12 @@ void V4L2SliceVideoDecoder::EnqueueDecodeTask(DecodeRequest request) { DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); - DCHECK(state_ == State::kDecoding || state_ == State::kFlushing); + DCHECK_NE(state_, State::kUninitialized); + + if (state_ == State::kError) { + std::move(request.decode_cb).Run(DecodeStatus::DECODE_ERROR); + return; + } if (!request.buffer->end_of_stream()) { bitstream_id_to_timestamp_.Put(request.bitstream_id, @@ -615,11 +617,10 @@ void V4L2SliceVideoDecoder::PumpDecodeTask() { DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_); - DCHECK(state_ == State::kDecoding || state_ == State::kFlushing); DVLOGF(3) << "state_:" << static_cast<int>(state_) << " Number of Decode requests: " << decode_request_queue_.size(); - if (state_ == State::kFlushing) + if (state_ != State::kDecoding) return; pause_reason_ = PauseReason::kNone;
diff --git a/media/gpu/v4l2/v4l2_slice_video_decoder.h b/media/gpu/v4l2/v4l2_slice_video_decoder.h index 6e39049a..bb6eb9c3 100644 --- a/media/gpu/v4l2/v4l2_slice_video_decoder.h +++ b/media/gpu/v4l2/v4l2_slice_video_decoder.h
@@ -173,8 +173,8 @@ void DestroyTask(); // Reset on decoder thread. void ResetTask(base::OnceClosure closure); - // Clear all pending requests, and call all pending decode callback with - // |status| argument. + // Reset |avd_|, clear all pending requests, and call all pending decode + // callback with |status| argument. void ClearPendingRequests(DecodeStatus status); // Enqueue |request| to the pending decode request queue, and try to decode
diff --git a/remoting/host/native_messaging/pipe_messaging_channel.cc b/remoting/host/native_messaging/pipe_messaging_channel.cc index 54f89e0..e13fb78 100644 --- a/remoting/host/native_messaging/pipe_messaging_channel.cc +++ b/remoting/host/native_messaging/pipe_messaging_channel.cc
@@ -10,6 +10,7 @@ #include "base/callback.h" #include "base/callback_helpers.h" #include "base/location.h" +#include "base/process/process_info.h" #include "base/values.h" #include "build/build_config.h" @@ -19,6 +20,10 @@ #include "base/posix/eintr_wrapper.h" #endif +#if defined(OS_WIN) +#include <windows.h> +#endif + namespace { base::File DuplicatePlatformFile(base::File file) {
diff --git a/services/network/public/cpp/cors/cors_error_status.cc b/services/network/public/cpp/cors/cors_error_status.cc index e1a21928..684de47 100644 --- a/services/network/public/cpp/cors/cors_error_status.cc +++ b/services/network/public/cpp/cors/cors_error_status.cc
@@ -5,6 +5,7 @@ #include "services/network/public/cpp/cors/cors_error_status.h" #include "net/base/net_errors.h" +#include "services/network/public/mojom/cors.mojom-shared.h" namespace network {
diff --git a/services/network/public/cpp/cors/cors_error_status.h b/services/network/public/cpp/cors/cors_error_status.h index 3e79c69..32d4018 100644 --- a/services/network/public/cpp/cors/cors_error_status.h +++ b/services/network/public/cpp/cors/cors_error_status.h
@@ -10,10 +10,13 @@ #include "base/component_export.h" #include "base/memory/scoped_refptr.h" #include "net/http/http_response_headers.h" -#include "services/network/public/mojom/cors.mojom-shared.h" namespace network { +namespace mojom { +enum class CorsError : int32_t; +} + struct COMPONENT_EXPORT(NETWORK_CPP_BASE) CorsErrorStatus { // This constructor is used by generated IPC serialization code. // Should not use this explicitly.
diff --git a/services/resource_coordinator/memory_instrumentation/coordinator_impl.cc b/services/resource_coordinator/memory_instrumentation/coordinator_impl.cc index 0659a2d..92b72a1a 100644 --- a/services/resource_coordinator/memory_instrumentation/coordinator_impl.cc +++ b/services/resource_coordinator/memory_instrumentation/coordinator_impl.cc
@@ -33,6 +33,7 @@ #include "base/mac/mac_util.h" #endif +using base::trace_event::MemoryDumpDeterminism; using base::trace_event::MemoryDumpLevelOfDetail; using base::trace_event::MemoryDumpType; @@ -118,6 +119,7 @@ void CoordinatorImpl::RequestGlobalMemoryDump( MemoryDumpType dump_type, MemoryDumpLevelOfDetail level_of_detail, + MemoryDumpDeterminism determinism, const std::vector<std::string>& allocator_dump_names, RequestGlobalMemoryDumpCallback callback) { // This merely strips out the |dump_guid| argument. @@ -126,8 +128,9 @@ std::move(callback).Run(success, std::move(global_memory_dump)); }; - QueuedRequest::Args args(dump_type, level_of_detail, allocator_dump_names, - false /* add_to_trace */, base::kNullProcessId, + QueuedRequest::Args args(dump_type, level_of_detail, determinism, + allocator_dump_names, false /* add_to_trace */, + base::kNullProcessId, /*memory_footprint_only=*/false); RequestGlobalMemoryDumpInternal(args, base::BindOnce(adapter, std::move(callback))); @@ -155,7 +158,8 @@ QueuedRequest::Args args( base::trace_event::MemoryDumpType::SUMMARY_ONLY, base::trace_event::MemoryDumpLevelOfDetail::BACKGROUND, - allocator_dump_names, false /* add_to_trace */, pid, + base::trace_event::MemoryDumpDeterminism::NONE, allocator_dump_names, + false /* add_to_trace */, pid, /*memory_footprint_only=*/false); RequestGlobalMemoryDumpInternal(args, base::BindOnce(adapter, std::move(callback))); @@ -174,7 +178,8 @@ QueuedRequest::Args args( base::trace_event::MemoryDumpType::SUMMARY_ONLY, - base::trace_event::MemoryDumpLevelOfDetail::BACKGROUND, {}, + base::trace_event::MemoryDumpLevelOfDetail::BACKGROUND, + base::trace_event::MemoryDumpDeterminism::NONE, {}, false /* add_to_trace */, pid, /*memory_footprint_only=*/true); RequestGlobalMemoryDumpInternal(args, base::BindOnce(adapter, std::move(callback))); @@ -183,6 +188,7 @@ void CoordinatorImpl::RequestGlobalMemoryDumpAndAppendToTrace( MemoryDumpType dump_type, MemoryDumpLevelOfDetail level_of_detail, + MemoryDumpDeterminism determinism, RequestGlobalMemoryDumpAndAppendToTraceCallback callback) { // This merely strips out the |dump_ptr| argument. auto adapter = [](RequestGlobalMemoryDumpAndAppendToTraceCallback callback, @@ -191,7 +197,7 @@ std::move(callback).Run(success, dump_guid); }; - QueuedRequest::Args args(dump_type, level_of_detail, {}, + QueuedRequest::Args args(dump_type, level_of_detail, determinism, {}, true /* add_to_trace */, base::kNullProcessId, /*memory_footprint_only=*/false); RequestGlobalMemoryDumpInternal(args,
diff --git a/services/resource_coordinator/memory_instrumentation/coordinator_impl.h b/services/resource_coordinator/memory_instrumentation/coordinator_impl.h index 8b18b2c..2395d75 100644 --- a/services/resource_coordinator/memory_instrumentation/coordinator_impl.h +++ b/services/resource_coordinator/memory_instrumentation/coordinator_impl.h
@@ -59,6 +59,7 @@ void RequestGlobalMemoryDump( base::trace_event::MemoryDumpType, base::trace_event::MemoryDumpLevelOfDetail, + base::trace_event::MemoryDumpDeterminism, const std::vector<std::string>& allocator_dump_names, RequestGlobalMemoryDumpCallback) override; void RequestGlobalMemoryDumpForPid( @@ -71,6 +72,7 @@ void RequestGlobalMemoryDumpAndAppendToTrace( base::trace_event::MemoryDumpType, base::trace_event::MemoryDumpLevelOfDetail, + base::trace_event::MemoryDumpDeterminism, RequestGlobalMemoryDumpAndAppendToTraceCallback) override; // mojom::HeapProfilerHelper implementation.
diff --git a/services/resource_coordinator/memory_instrumentation/coordinator_impl_unittest.cc b/services/resource_coordinator/memory_instrumentation/coordinator_impl_unittest.cc index 09d740e..1f55838 100644 --- a/services/resource_coordinator/memory_instrumentation/coordinator_impl_unittest.cc +++ b/services/resource_coordinator/memory_instrumentation/coordinator_impl_unittest.cc
@@ -89,18 +89,20 @@ } void RequestGlobalMemoryDump(RequestGlobalMemoryDumpCallback callback) { - RequestGlobalMemoryDump(MemoryDumpType::SUMMARY_ONLY, - MemoryDumpLevelOfDetail::BACKGROUND, {}, - std::move(callback)); + RequestGlobalMemoryDump( + MemoryDumpType::SUMMARY_ONLY, MemoryDumpLevelOfDetail::BACKGROUND, + MemoryDumpDeterminism::NONE, {}, std::move(callback)); } void RequestGlobalMemoryDump( MemoryDumpType dump_type, MemoryDumpLevelOfDetail level_of_detail, + MemoryDumpDeterminism determinism, const std::vector<std::string>& allocator_dump_names, RequestGlobalMemoryDumpCallback callback) { - coordinator_->RequestGlobalMemoryDump( - dump_type, level_of_detail, allocator_dump_names, std::move(callback)); + coordinator_->RequestGlobalMemoryDump(dump_type, level_of_detail, + determinism, allocator_dump_names, + std::move(callback)); } void RequestGlobalMemoryDumpForPid( @@ -115,7 +117,7 @@ RequestGlobalMemoryDumpAndAppendToTraceCallback callback) { coordinator_->RequestGlobalMemoryDumpAndAppendToTrace( MemoryDumpType::EXPLICITLY_TRIGGERED, MemoryDumpLevelOfDetail::DETAILED, - std::move(callback)); + MemoryDumpDeterminism::NONE, std::move(callback)); } void GetVmRegionsForHeapProfiler( @@ -805,8 +807,8 @@ trace_analyzer::Start(MemoryDumpManager::kTraceCategory); RequestGlobalMemoryDump(MemoryDumpType::EXPLICITLY_TRIGGERED, - MemoryDumpLevelOfDetail::DETAILED, {}, - callback.Get()); + MemoryDumpLevelOfDetail::DETAILED, + MemoryDumpDeterminism::NONE, {}, callback.Get()); run_loop.Run(); auto analyzer = trace_analyzer::Stop();
diff --git a/services/resource_coordinator/memory_instrumentation/queued_request.cc b/services/resource_coordinator/memory_instrumentation/queued_request.cc index 40e97d44..f22dc41 100644 --- a/services/resource_coordinator/memory_instrumentation/queued_request.cc +++ b/services/resource_coordinator/memory_instrumentation/queued_request.cc
@@ -8,12 +8,14 @@ QueuedRequest::Args::Args(MemoryDumpType dump_type, MemoryDumpLevelOfDetail level_of_detail, + MemoryDumpDeterminism determinism, const std::vector<std::string>& allocator_dump_names, bool add_to_trace, base::ProcessId pid, bool memory_footprint_only) : dump_type(dump_type), level_of_detail(level_of_detail), + determinism(determinism), allocator_dump_names(allocator_dump_names), add_to_trace(add_to_trace), pid(pid), @@ -45,6 +47,7 @@ request_args.dump_guid = dump_guid; request_args.dump_type = args.dump_type; request_args.level_of_detail = args.level_of_detail; + request_args.determinism = args.determinism; return request_args; }
diff --git a/services/resource_coordinator/memory_instrumentation/queued_request.h b/services/resource_coordinator/memory_instrumentation/queued_request.h index a0df132..f51e232 100644 --- a/services/resource_coordinator/memory_instrumentation/queued_request.h +++ b/services/resource_coordinator/memory_instrumentation/queued_request.h
@@ -15,6 +15,7 @@ #include "base/trace_event/memory_dump_request_args.h" #include "services/resource_coordinator/public/mojom/memory_instrumentation/memory_instrumentation.mojom.h" +using base::trace_event::MemoryDumpDeterminism; using base::trace_event::MemoryDumpLevelOfDetail; using base::trace_event::MemoryDumpType; @@ -32,6 +33,7 @@ struct Args { Args(MemoryDumpType dump_type, MemoryDumpLevelOfDetail level_of_detail, + MemoryDumpDeterminism determinism, const std::vector<std::string>& allocator_dump_names, bool add_to_trace, base::ProcessId pid, @@ -41,6 +43,7 @@ const MemoryDumpType dump_type; const MemoryDumpLevelOfDetail level_of_detail; + const MemoryDumpDeterminism determinism; const std::vector<std::string> allocator_dump_names; const bool add_to_trace; const base::ProcessId pid;
diff --git a/services/resource_coordinator/public/cpp/memory_instrumentation/client_process_impl.cc b/services/resource_coordinator/public/cpp/memory_instrumentation/client_process_impl.cc index 0d9ca71..279ef11 100644 --- a/services/resource_coordinator/public/cpp/memory_instrumentation/client_process_impl.cc +++ b/services/resource_coordinator/public/cpp/memory_instrumentation/client_process_impl.cc
@@ -128,6 +128,7 @@ coordinator = MemoryInstrumentation::GetInstance()->GetCoordinator(); coordinator->RequestGlobalMemoryDumpAndAppendToTrace( dump_type, level_of_detail, + base::trace_event::MemoryDumpDeterminism::NONE, mojom::Coordinator::RequestGlobalMemoryDumpAndAppendToTraceCallback()); }
diff --git a/services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation.cc b/services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation.cc index ea896a00..c81d5f8 100644 --- a/services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation.cc +++ b/services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation.cc
@@ -45,7 +45,7 @@ RequestGlobalDumpCallback callback) { coordinator_->RequestGlobalMemoryDump( MemoryDumpType::SUMMARY_ONLY, MemoryDumpLevelOfDetail::BACKGROUND, - allocator_dump_names, + MemoryDumpDeterminism::NONE, allocator_dump_names, base::BindOnce(&WrapGlobalMemoryDump, std::move(callback))); } @@ -68,9 +68,10 @@ void MemoryInstrumentation::RequestGlobalDumpAndAppendToTrace( MemoryDumpType dump_type, MemoryDumpLevelOfDetail level_of_detail, + MemoryDumpDeterminism determinism, RequestGlobalMemoryDumpAndAppendToTraceCallback callback) { coordinator_->RequestGlobalMemoryDumpAndAppendToTrace( - dump_type, level_of_detail, std::move(callback)); + dump_type, level_of_detail, determinism, std::move(callback)); } } // namespace memory_instrumentation
diff --git a/services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation.h b/services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation.h index fd429c3..3264917 100644 --- a/services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation.h +++ b/services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation.h
@@ -25,6 +25,7 @@ public: using MemoryDumpType = base::trace_event::MemoryDumpType; using MemoryDumpLevelOfDetail = base::trace_event::MemoryDumpLevelOfDetail; + using MemoryDumpDeterminism = base::trace_event::MemoryDumpDeterminism; using RequestGlobalDumpCallback = base::OnceCallback<void(bool success, std::unique_ptr<GlobalMemoryDump> dump)>; @@ -93,6 +94,7 @@ void RequestGlobalDumpAndAppendToTrace( MemoryDumpType, MemoryDumpLevelOfDetail, + MemoryDumpDeterminism, RequestGlobalMemoryDumpAndAppendToTraceCallback); private:
diff --git a/services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation.typemap b/services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation.typemap index 04a084f2..421b6ee 100644 --- a/services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation.typemap +++ b/services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation.typemap
@@ -21,6 +21,7 @@ type_mappings = [ "memory_instrumentation.mojom.DumpType=::base::trace_event::MemoryDumpType", "memory_instrumentation.mojom.LevelOfDetail=::base::trace_event::MemoryDumpLevelOfDetail", + "memory_instrumentation.mojom.Determinism=::base::trace_event::MemoryDumpDeterminism", "memory_instrumentation.mojom.RequestArgs=::base::trace_event::MemoryDumpRequestArgs", "memory_instrumentation.mojom.RawAllocatorDumpEdge=::base::trace_event::ProcessMemoryDump::MemoryAllocatorDumpEdge", "memory_instrumentation.mojom.RawAllocatorDumpEntry=::base::trace_event::MemoryAllocatorDump::Entry[move_only]",
diff --git a/services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation_mojom_traits.cc b/services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation_mojom_traits.cc index a20880a..a7ab6f8 100644 --- a/services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation_mojom_traits.cc +++ b/services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation_mojom_traits.cc
@@ -89,6 +89,42 @@ } // static +memory_instrumentation::mojom::Determinism +EnumTraits<memory_instrumentation::mojom::Determinism, + base::trace_event::MemoryDumpDeterminism>:: + ToMojom(base::trace_event::MemoryDumpDeterminism determinism) { + switch (determinism) { + case base::trace_event::MemoryDumpDeterminism::NONE: + return memory_instrumentation::mojom::Determinism::NONE; + case base::trace_event::MemoryDumpDeterminism::FORCE_GC: + return memory_instrumentation::mojom::Determinism::FORCE_GC; + default: + CHECK(false) << "Invalid type: " << static_cast<uint8_t>(determinism); + // This should not be reached. Just return a random value. + return memory_instrumentation::mojom::Determinism::NONE; + } +} + +// static +bool EnumTraits<memory_instrumentation::mojom::Determinism, + base::trace_event::MemoryDumpDeterminism>:: + FromMojom(memory_instrumentation::mojom::Determinism input, + base::trace_event::MemoryDumpDeterminism* out) { + switch (input) { + case memory_instrumentation::mojom::Determinism::NONE: + *out = base::trace_event::MemoryDumpDeterminism::NONE; + break; + case memory_instrumentation::mojom::Determinism::FORCE_GC: + *out = base::trace_event::MemoryDumpDeterminism::FORCE_GC; + break; + default: + NOTREACHED() << "Invalid type: " << static_cast<uint8_t>(input); + return false; + } + return true; +} + +// static bool StructTraits<memory_instrumentation::mojom::RequestArgsDataView, base::trace_event::MemoryDumpRequestArgs>:: Read(memory_instrumentation::mojom::RequestArgsDataView input, @@ -98,6 +134,8 @@ return false; if (!input.ReadLevelOfDetail(&out->level_of_detail)) return false; + if (!input.ReadDeterminism(&out->determinism)) + return false; return true; }
diff --git a/services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation_mojom_traits.h b/services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation_mojom_traits.h index a048719..6493fee 100644 --- a/services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation_mojom_traits.h +++ b/services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation_mojom_traits.h
@@ -35,6 +35,16 @@ template <> struct COMPONENT_EXPORT(RESOURCE_COORDINATOR_PUBLIC_MOJOM) + EnumTraits<memory_instrumentation::mojom::Determinism, + base::trace_event::MemoryDumpDeterminism> { + static memory_instrumentation::mojom::Determinism ToMojom( + base::trace_event::MemoryDumpDeterminism determinism); + static bool FromMojom(memory_instrumentation::mojom::Determinism input, + base::trace_event::MemoryDumpDeterminism* out); +}; + +template <> +struct COMPONENT_EXPORT(RESOURCE_COORDINATOR_PUBLIC_MOJOM) StructTraits<memory_instrumentation::mojom::RequestArgsDataView, base::trace_event::MemoryDumpRequestArgs> { static uint64_t dump_guid( @@ -49,6 +59,10 @@ const base::trace_event::MemoryDumpRequestArgs& args) { return args.level_of_detail; } + static base::trace_event::MemoryDumpDeterminism determinism( + const base::trace_event::MemoryDumpRequestArgs& args) { + return args.determinism; + } static bool Read(memory_instrumentation::mojom::RequestArgsDataView input, base::trace_event::MemoryDumpRequestArgs* out); }; @@ -191,6 +205,10 @@ const std::unique_ptr<base::trace_event::ProcessMemoryDump>& pmd) { return pmd->dump_args().level_of_detail; } + static base::trace_event::MemoryDumpDeterminism determinism( + const std::unique_ptr<base::trace_event::ProcessMemoryDump>& pmd) { + return pmd->dump_args().determinism; + } static void SetToNull( std::unique_ptr<base::trace_event::ProcessMemoryDump>* out) {
diff --git a/services/resource_coordinator/public/cpp/memory_instrumentation/tracing_integration_unittest.cc b/services/resource_coordinator/public/cpp/memory_instrumentation/tracing_integration_unittest.cc index b210007..38590f67 100644 --- a/services/resource_coordinator/public/cpp/memory_instrumentation/tracing_integration_unittest.cc +++ b/services/resource_coordinator/public/cpp/memory_instrumentation/tracing_integration_unittest.cc
@@ -35,6 +35,7 @@ using base::trace_event::MemoryAllocatorDump; using base::trace_event::MemoryDumpArgs; +using base::trace_event::MemoryDumpDeterminism; using base::trace_event::MemoryDumpLevelOfDetail; using base::trace_event::MemoryDumpManager; using base::trace_event::MemoryDumpProvider; @@ -110,6 +111,7 @@ void RequestGlobalMemoryDump( MemoryDumpType dump_type, MemoryDumpLevelOfDetail level_of_detail, + MemoryDumpDeterminism determinism, const std::vector<std::string>& allocator_dump_names, RequestGlobalMemoryDumpCallback) override; @@ -125,6 +127,7 @@ void RequestGlobalMemoryDumpAndAppendToTrace( MemoryDumpType dump_type, MemoryDumpLevelOfDetail level_of_detail, + MemoryDumpDeterminism determinism, RequestGlobalMemoryDumpAndAppendToTraceCallback) override; private: @@ -193,9 +196,11 @@ } void RequestChromeDump(MemoryDumpType dump_type, - MemoryDumpLevelOfDetail level_of_detail) { + MemoryDumpLevelOfDetail level_of_detail, + MemoryDumpDeterminism determinism) { uint64_t req_guid = ++guid_counter_; - MemoryDumpRequestArgs request_args{req_guid, dump_type, level_of_detail}; + MemoryDumpRequestArgs request_args{req_guid, dump_type, level_of_detail, + determinism}; ClientProcessImpl::RequestChromeMemoryDumpCallback callback = base::BindOnce( [](bool success, uint64_t dump_guid, @@ -251,17 +256,19 @@ void MockCoordinator::RequestGlobalMemoryDump( MemoryDumpType dump_type, MemoryDumpLevelOfDetail level_of_detail, + MemoryDumpDeterminism determinism, const std::vector<std::string>& allocator_dump_names, RequestGlobalMemoryDumpCallback callback) { - client_->RequestChromeDump(dump_type, level_of_detail); + client_->RequestChromeDump(dump_type, level_of_detail, determinism); std::move(callback).Run(true, mojom::GlobalMemoryDumpPtr()); } void MockCoordinator::RequestGlobalMemoryDumpAndAppendToTrace( MemoryDumpType dump_type, MemoryDumpLevelOfDetail level_of_detail, + MemoryDumpDeterminism determinism, RequestGlobalMemoryDumpAndAppendToTraceCallback callback) { - client_->RequestChromeDump(dump_type, level_of_detail); + client_->RequestChromeDump(dump_type, level_of_detail, determinism); std::move(callback).Run(1, true); }
diff --git a/services/resource_coordinator/public/mojom/memory_instrumentation/memory_instrumentation.mojom b/services/resource_coordinator/public/mojom/memory_instrumentation/memory_instrumentation.mojom index 3a3c1b1..d12e4d9 100644 --- a/services/resource_coordinator/public/mojom/memory_instrumentation/memory_instrumentation.mojom +++ b/services/resource_coordinator/public/mojom/memory_instrumentation/memory_instrumentation.mojom
@@ -22,6 +22,13 @@ DETAILED }; +// Tells the MemoryDumpProvider(s) if they should try to make the result +// more deterministic by forcing garbage collection. +enum Determinism { + NONE, + FORCE_GC +}; + enum ProcessType { OTHER, BROWSER, @@ -53,6 +60,7 @@ uint64 dump_guid; DumpType dump_type; LevelOfDetail level_of_detail; + Determinism determinism; }; struct RawAllocatorDumpEdge { @@ -301,6 +309,7 @@ // entries which contain fields such as "size" and "effective_size". RequestGlobalMemoryDump(DumpType dump_type, LevelOfDetail level_of_detail, + Determinism determinsm, array<string> allocator_dump_names) => (bool success, GlobalMemoryDump? global_memory_dump); @@ -319,7 +328,8 @@ // Broadcasts a dump request to all registered client processes and injects the // dump in the trace buffer (if tracing is enabled). RequestGlobalMemoryDumpAndAppendToTrace(DumpType dump_type, - LevelOfDetail level_of_detail) => + LevelOfDetail level_of_detail, + Determinism determinism) => (bool success, uint64 dump_id); };
diff --git a/services/viz/public/cpp/gpu/gpu.cc b/services/viz/public/cpp/gpu/gpu.cc index eae7764..307cf41 100644 --- a/services/viz/public/cpp/gpu/gpu.cc +++ b/services/viz/public/cpp/gpu/gpu.cc
@@ -11,6 +11,7 @@ #include "base/bind.h" #include "base/memory/ptr_util.h" #include "base/synchronization/waitable_event.h" +#include "base/threading/thread_checker.h" #include "base/threading/thread_task_runner_handle.h" #include "base/trace_event/trace_event.h" #include "build/build_config.h"
diff --git a/skia/BUILD.gn b/skia/BUILD.gn index 3fda6d4..1f9e7c1 100644 --- a/skia/BUILD.gn +++ b/skia/BUILD.gn
@@ -314,6 +314,7 @@ "//third_party/skia/src/codec/SkJpegUtility.cpp", "//third_party/skia/src/codec/SkMaskSwizzler.cpp", "//third_party/skia/src/codec/SkMasks.cpp", + "//third_party/skia/src/codec/SkParseEncodedOrigin.cpp", "//third_party/skia/src/codec/SkPngCodec.cpp", "//third_party/skia/src/codec/SkSampler.cpp", "//third_party/skia/src/codec/SkStreamBuffer.cpp",
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index c519d0a..4d806ff0 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -4053,27 +4053,6 @@ ] } ], - "OutOfBlinkCors": [ - { - "platforms": [ - "android", - "android_webview", - "chromeos", - "ios", - "linux", - "mac", - "windows" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "OutOfBlinkCors" - ] - } - ] - } - ], "OutOfProcessQuarantine": [ { "platforms": [ @@ -4108,6 +4087,21 @@ ] } ], + "OverlayNewLayout": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "OverlayNewLayout", + "enable_features": [ + "OverlayNewLayout" + ] + } + ] + } + ], "PDFClickToOpen": [ { "platforms": [
diff --git a/third_party/blink/public/platform/web_localized_string.h b/third_party/blink/public/platform/web_localized_string.h index e62672e..61028d0 100644 --- a/third_party/blink/public/platform/web_localized_string.h +++ b/third_party/blink/public/platform/web_localized_string.h
@@ -72,8 +72,6 @@ kAXMediaTouchLessSeekAction, kAXMediaTouchLessVolumeAction, kBlockedPluginText, - kCalendarClear, - kCalendarToday, kDetailsLabel, kFileButtonNoFileSelectedLabel, kInputElementAltText,
diff --git a/third_party/blink/public/platform/web_runtime_features.h b/third_party/blink/public/platform/web_runtime_features.h index 7fc1ca3..f7c993b 100644 --- a/third_party/blink/public/platform/web_runtime_features.h +++ b/third_party/blink/public/platform/web_runtime_features.h
@@ -235,7 +235,6 @@ bool); BLINK_PLATFORM_EXPORT static void EnableIdleDetection(bool); BLINK_PLATFORM_EXPORT static void EnableSkipTouchEventFilter(bool); - BLINK_PLATFORM_EXPORT static void EnableStaleWhileRevalidate(bool); BLINK_PLATFORM_EXPORT static void EnableSmsReceiver(bool); BLINK_PLATFORM_EXPORT static void EnableDisplayLocking(bool); BLINK_PLATFORM_EXPORT static void
diff --git a/third_party/blink/public/platform/web_url_loader.h b/third_party/blink/public/platform/web_url_loader.h index 7bb0b6b..17d09c8 100644 --- a/third_party/blink/public/platform/web_url_loader.h +++ b/third_party/blink/public/platform/web_url_loader.h
@@ -37,6 +37,10 @@ #include "third_party/blink/public/platform/web_common.h" #include "third_party/blink/public/platform/web_url_request.h" +namespace base { +class SingleThreadTaskRunner; +} + namespace blink { class WebData;
diff --git a/third_party/blink/public/web/modules/service_worker/web_service_worker_context_client.h b/third_party/blink/public/web/modules/service_worker/web_service_worker_context_client.h index 98de584..c893f39 100644 --- a/third_party/blink/public/web/modules/service_worker/web_service_worker_context_client.h +++ b/third_party/blink/public/web/modules/service_worker/web_service_worker_context_client.h
@@ -81,11 +81,6 @@ mojo::ScopedMessagePipeHandle devtools_agent_ptr_info, mojo::ScopedMessagePipeHandle devtools_agent_host_request) {} - // Starting the worker failed. This could happen when loading the worker - // script failed, or the worker was asked to terminate before startup - // completed. Called on the initiator thread. - virtual void WorkerContextFailedToStartOnInitiatorThread() {} - // The worker started but it could not execute because loading the classic // script failed on the worker thread. This is called only for installed // scripts fetch or off-the-main-thread classic worker script fetch.
diff --git a/third_party/blink/renderer/bindings/core/v8/DEPS b/third_party/blink/renderer/bindings/core/v8/DEPS new file mode 100644 index 0000000..c386e5e --- /dev/null +++ b/third_party/blink/renderer/bindings/core/v8/DEPS
@@ -0,0 +1,5 @@ +specific_include_rules = { + "script_promise_resolver_test.cc": [ + "+base/run_loop.h", + ] +} \ No newline at end of file
diff --git a/third_party/blink/renderer/bindings/core/v8/js_event_handler.cc b/third_party/blink/renderer/bindings/core/v8/js_event_handler.cc index 8e525d16..b5062cc 100644 --- a/third_party/blink/renderer/bindings/core/v8/js_event_handler.cc +++ b/third_party/blink/renderer/bindings/core/v8/js_event_handler.cc
@@ -99,9 +99,10 @@ // https://html.spec.whatwg.org/C/#runtime-script-errors-2 ScriptValue error_attribute = error_event->error(script_state_of_listener); if (error_attribute.IsEmpty() || - error_event->target()->InterfaceName() == event_target_names::kWorker) - error_attribute = ScriptValue::CreateNull(script_state_of_listener); - + error_event->target()->InterfaceName() == event_target_names::kWorker) { + error_attribute = + ScriptValue::CreateNull(script_state_of_listener->GetIsolate()); + } arguments = { ScriptValue::From(script_state_of_listener, error_event->message()), ScriptValue::From(script_state_of_listener, error_event->filename()),
diff --git a/third_party/blink/renderer/bindings/core/v8/script_promise.cc b/third_party/blink/renderer/bindings/core/v8/script_promise.cc index 2efdbb19a..54ba036 100644 --- a/third_party/blink/renderer/bindings/core/v8/script_promise.cc +++ b/third_party/blink/renderer/bindings/core/v8/script_promise.cc
@@ -168,7 +168,7 @@ ScriptPromise::InternalResolver::InternalResolver(ScriptState* script_state) : script_state_(script_state), - resolver_(script_state, + resolver_(script_state->GetIsolate(), v8::Promise::Resolver::New(script_state->GetContext())) { // |resolver| can be empty when the thread is being terminated. We ignore such // errors. @@ -219,7 +219,7 @@ return; if (!value->IsPromise()) { - promise_ = ScriptValue(script_state, v8::Local<v8::Value>()); + promise_ = ScriptValue(); V8ThrowException::ThrowTypeError(script_state->GetIsolate(), "the given value is not a Promise"); return;
diff --git a/third_party/blink/renderer/bindings/core/v8/script_promise_resolver_test.cc b/third_party/blink/renderer/bindings/core/v8/script_promise_resolver_test.cc index 0243503..7d92626 100644 --- a/third_party/blink/renderer/bindings/core/v8/script_promise_resolver_test.cc +++ b/third_party/blink/renderer/bindings/core/v8/script_promise_resolver_test.cc
@@ -6,6 +6,7 @@ #include <memory> +#include "base/run_loop.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/bindings/core/v8/script_function.h" #include "third_party/blink/renderer/bindings/core/v8/script_value.h"
diff --git a/third_party/blink/renderer/bindings/core/v8/script_value.cc b/third_party/blink/renderer/bindings/core/v8/script_value.cc index 4df0bae..ee44862 100644 --- a/third_party/blink/renderer/bindings/core/v8/script_value.cc +++ b/third_party/blink/renderer/bindings/core/v8/script_value.cc
@@ -35,43 +35,13 @@ #include "third_party/blink/renderer/platform/bindings/script_state.h" namespace blink { -namespace { - -v8::Local<v8::Value> ToWorldSafeValue(ScriptState* target_script_state, - v8::Local<v8::Value> value) { - if (value.IsEmpty() || !value->IsObject()) - return value; - - v8::Local<v8::Context> creation_context = - value.As<v8::Object>()->CreationContext(); - v8::Isolate* isolate = target_script_state->GetIsolate(); - if (&ScriptState::From(creation_context)->World() == - &target_script_state->World()) { - return value; - } - - v8::Context::Scope target_context_scope(target_script_state->GetContext()); - scoped_refptr<SerializedScriptValue> serialized = - SerializedScriptValue::SerializeAndSwallowExceptions(isolate, value); - return serialized->Deserialize(isolate); -} - -} // namespace v8::Local<v8::Value> ScriptValue::V8Value() const { if (IsEmpty()) return v8::Local<v8::Value>(); DCHECK(GetIsolate()->InContext()); - - // This is a check to validate that you don't return a ScriptValue to a world - // different from the world that created the ScriptValue. - // Probably this could be: - // if (&script_state_->world() == &DOMWrapperWorld::current(isolate())) - // return v8::Local<v8::Value>(); - // instead of triggering CHECK. - CHECK_EQ(&script_state_->World(), &DOMWrapperWorld::Current(GetIsolate())); - return value_->NewLocal(GetIsolate()); + return value_.Get(ScriptState::From(isolate_->GetCurrentContext())); } v8::Local<v8::Value> ScriptValue::V8ValueFor( @@ -79,15 +49,13 @@ if (IsEmpty()) return v8::Local<v8::Value>(); - return ToWorldSafeValue(target_script_state, - value_->NewLocal(target_script_state->GetIsolate())); + return value_.GetAcrossWorld(target_script_state); } bool ScriptValue::ToString(String& result) const { if (IsEmpty()) return false; - ScriptState::Scope scope(script_state_); v8::Local<v8::Value> string = V8Value(); if (string.IsEmpty() || !string->IsString()) return false; @@ -95,8 +63,8 @@ return true; } -ScriptValue ScriptValue::CreateNull(ScriptState* script_state) { - return ScriptValue(script_state, v8::Null(script_state->GetIsolate())); +ScriptValue ScriptValue::CreateNull(v8::Isolate* isolate) { + return ScriptValue(isolate, v8::Null(isolate)); } } // namespace blink
diff --git a/third_party/blink/renderer/bindings/core/v8/script_value.h b/third_party/blink/renderer/bindings/core/v8/script_value.h index 5076538..134d872e 100644 --- a/third_party/blink/renderer/bindings/core/v8/script_value.h +++ b/third_party/blink/renderer/bindings/core/v8/script_value.h
@@ -33,9 +33,11 @@ #include "base/memory/scoped_refptr.h" #include "third_party/blink/renderer/bindings/core/v8/native_value_traits.h" +#include "third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" #include "third_party/blink/renderer/platform/bindings/shared_persistent.h" +#include "third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "v8/include/v8.h" @@ -69,51 +71,66 @@ ScriptValue() = default; + // TODO(rikaf): Forbid passing empty v8::Local<v8::Value> to ScriptValue's + // ctor. + + // TODO(crbug.com/998994): Remove ScriptValue(ScriptState*, + // v8::Local<v8::Value>) once we finish replacing with ScriptValue(Isolate*, + // v8::Local<v8::Value>) ScriptValue(ScriptState* script_state, v8::Local<v8::Value> value) - : script_state_(script_state), - value_(value.IsEmpty() ? nullptr - : SharedPersistent<v8::Value>::Create( - value, - script_state->GetIsolate())) { - DCHECK(IsEmpty() || script_state_); + : isolate_(script_state->GetIsolate()), + value_(value.IsEmpty() + ? WorldSafeV8Reference<v8::Value>() + : WorldSafeV8Reference<v8::Value>(script_state->GetIsolate(), + value)) { + DCHECK(isolate_); + } + + ScriptValue(v8::Isolate* isolate, v8::Local<v8::Value> value) + : isolate_(isolate), + value_(value.IsEmpty() + ? WorldSafeV8Reference<v8::Value>() + : WorldSafeV8Reference<v8::Value>(isolate, value)) { + DCHECK(isolate_); } template <typename T> - ScriptValue(ScriptState* script_state, v8::MaybeLocal<T> value) - : script_state_(script_state), - value_(value.IsEmpty() ? nullptr - : SharedPersistent<v8::Value>::Create( - value.ToLocalChecked(), - script_state->GetIsolate())) { - DCHECK(IsEmpty() || script_state_); + ScriptValue(v8::Isolate* isolate, v8::MaybeLocal<T> value) + : isolate_(isolate), + value_(value.IsEmpty() + ? WorldSafeV8Reference<v8::Value>() + : WorldSafeV8Reference<v8::Value>(isolate, + value.ToLocalChecked())) { + DCHECK(isolate_); } - ScriptValue(const ScriptValue& value) - : script_state_(value.script_state_), value_(value.value_) { - DCHECK(IsEmpty() || script_state_); + ScriptValue(v8::Isolate* isolate, WorldSafeV8Reference<v8::Value> value) + : isolate_(isolate), value_(value) { + DCHECK(isolate_); } - ScriptState* GetScriptState() const { return script_state_; } - - v8::Isolate* GetIsolate() const { - return script_state_ ? script_state_->GetIsolate() - : v8::Isolate::GetCurrent(); - } - - ScriptValue& operator=(const ScriptValue& value) { - if (this != &value) { - script_state_ = value.script_state_; + ScriptValue(const ScriptValue& value) { + // TODO(crbug.com/v8/9773): Deal with null value at the side of v8. + if (value.IsEmpty()) { + isolate_ = nullptr; + value_.Reset(); + } else { + isolate_ = value.isolate_; value_ = value.value_; + DCHECK(isolate_); } - return *this; } + // Use this GetIsolate() to do DCHECK inside ScriptValue. + v8::Isolate* GetIsolate() const { + DCHECK(isolate_); + return isolate_; + } + + ScriptValue& operator=(const ScriptValue& value) = default; + bool operator==(const ScriptValue& value) const { - if (IsEmpty()) - return value.IsEmpty(); - if (value.IsEmpty()) - return false; - return *value_ == *value.value_; + return value_ == value.value_; } bool operator!=(const ScriptValue& value) const { return !operator==(value); } @@ -150,9 +167,12 @@ return !value.IsEmpty() && value->IsObject(); } - bool IsEmpty() const { return !value_.get() || value_->IsEmpty(); } + bool IsEmpty() const { return value_.IsEmpty(); } - void Clear() { value_ = nullptr; } + void Clear() { + isolate_ = nullptr; + value_.Reset(); + } v8::Local<v8::Value> V8Value() const; // Returns v8Value() if a given ScriptState is the same as the @@ -160,15 +180,19 @@ // this "clones" the v8 value and returns it. v8::Local<v8::Value> V8ValueFor(ScriptState*) const; + const WorldSafeV8Reference<v8::Value>& ToWorldSafeV8Reference() const { + return value_; + } + bool ToString(String&) const; - static ScriptValue CreateNull(ScriptState*); + static ScriptValue CreateNull(v8::Isolate*); - void Trace(Visitor* visitor) { visitor->Trace(script_state_); } + void Trace(Visitor* visitor) { visitor->Trace(value_); } private: - Member<ScriptState> script_state_; - scoped_refptr<SharedPersistent<v8::Value>> value_; + v8::Isolate* isolate_ = nullptr; + WorldSafeV8Reference<v8::Value> value_; }; template <>
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_extras_test_utils.cc b/third_party/blink/renderer/bindings/core/v8/v8_extras_test_utils.cc index 7623ed7..16a021bd 100644 --- a/third_party/blink/renderer/bindings/core/v8/v8_extras_test_utils.cc +++ b/third_party/blink/renderer/bindings/core/v8/v8_extras_test_utils.cc
@@ -33,7 +33,7 @@ ADD_FAILURE() << "Compilation fails"; return ScriptValue(); } - return ScriptValue(scope->GetScriptState(), script->Run(scope->GetContext())); + return ScriptValue(scope->GetIsolate(), script->Run(scope->GetContext())); } ScriptValue EvalWithPrintingError(V8TestingScope* scope, const char* script) {
diff --git a/third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference.cc b/third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference.cc index 7ee67ac..6bc84e4 100644 --- a/third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference.cc +++ b/third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference.cc
@@ -40,6 +40,9 @@ v8::Local<v8::Value> value) { if (!value->IsObject()) return; + // TODO(crbug.com/v8/9713): Let JSModuleNamespaceObject have CreationContext. + if (value->IsModuleNamespaceObject()) + return; ScriptState* script_state = ScriptState::From(value.As<v8::Object>()->CreationContext());
diff --git a/third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference.h b/third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference.h index 85b3e32..f3bb51bc 100644 --- a/third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference.h +++ b/third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference.h
@@ -107,14 +107,19 @@ void Trace(blink::Visitor* visitor) { visitor->Trace(v8_reference_); } + WorldSafeV8Reference& operator=(const WorldSafeV8Reference<V8Type>& other) = + default; + + bool operator==(const WorldSafeV8Reference<V8Type>& other) const { + return v8_reference_ == other.v8_reference_; + } + private: TraceWrapperV8Reference<V8Type> v8_reference_; // The world of the current context at the time when |v8_reference_| was set. // It's guaranteed that, if |v8_reference_| is a v8::Object, the world of the // creation context of |v8_reference_| is the same as |world_|. scoped_refptr<const DOMWrapperWorld> world_; - - DISALLOW_COPY_AND_ASSIGN(WorldSafeV8Reference); }; } // namespace blink
diff --git a/third_party/blink/renderer/bindings/modules/v8/generated.gni b/third_party/blink/renderer/bindings/modules/v8/generated.gni index 88ea668..f933cbd 100644 --- a/third_party/blink/renderer/bindings/modules/v8/generated.gni +++ b/third_party/blink/renderer/bindings/modules/v8/generated.gni
@@ -52,8 +52,8 @@ "$bindings_modules_v8_output_dir/gpu_load_op_or_gpu_color.h", "$bindings_modules_v8_output_dir/gpu_load_op_or_float.cc", "$bindings_modules_v8_output_dir/gpu_load_op_or_float.h", - "$bindings_modules_v8_output_dir/gpu_load_op_or_long.cc", - "$bindings_modules_v8_output_dir/gpu_load_op_or_long.h", + "$bindings_modules_v8_output_dir/gpu_load_op_or_unsigned_long.cc", + "$bindings_modules_v8_output_dir/gpu_load_op_or_unsigned_long.h", "$bindings_modules_v8_output_dir/gpu_sampler_or_gpu_texture_view_or_gpu_buffer_binding.cc", "$bindings_modules_v8_output_dir/gpu_sampler_or_gpu_texture_view_or_gpu_buffer_binding.h", "$bindings_modules_v8_output_dir/html_canvas_element_or_offscreen_canvas.cc",
diff --git a/third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.cc b/third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.cc index 965f6ec..8e1db2c 100644 --- a/third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.cc +++ b/third_party/blink/renderer/bindings/modules/v8/v8_binding_for_modules.cc
@@ -724,7 +724,7 @@ v8::Isolate* isolate = script_state->GetIsolate(); v8::HandleScope handle_scope(isolate); if (!serialized_value) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); SerializedScriptValue::DeserializeOptions options; options.blob_info = blob_info;
diff --git a/third_party/blink/renderer/bindings/scripts/v8_types.py b/third_party/blink/renderer/bindings/scripts/v8_types.py index f14420c..cd9eef5 100644 --- a/third_party/blink/renderer/bindings/scripts/v8_types.py +++ b/third_party/blink/renderer/bindings/scripts/v8_types.py
@@ -1051,7 +1051,7 @@ """Converts an expression that is a valid C++ literal for this type.""" # FIXME: add validation that idl_type and idl_literal are compatible if idl_type.base_type in ('any', 'object') and idl_literal.is_null: - return 'ScriptValue::CreateNull(script_state)' + return 'ScriptValue::CreateNull(script_state->GetIsolate())' literal_value = str(idl_literal) if idl_type.base_type in ('octet', 'unsigned short', 'unsigned long'): return literal_value + 'u'
diff --git a/third_party/blink/renderer/core/animation/animation.h b/third_party/blink/renderer/core/animation/animation.h index e4ebcaf..313f50c7 100644 --- a/third_party/blink/renderer/core/animation/animation.h +++ b/third_party/blink/renderer/core/animation/animation.h
@@ -461,6 +461,8 @@ FRIEND_TEST_ALL_PREFIXES(AnimationAnimationTestCompositeAfterPaint, NoCompositeWithoutCompositedElementId); + FRIEND_TEST_ALL_PREFIXES(AnimationAnimationTestNoCompositing, + PendingActivityWithFinishedEventListener); }; } // namespace blink
diff --git a/third_party/blink/renderer/core/animation/animation_test.cc b/third_party/blink/renderer/core/animation/animation_test.cc index 98853f0..21a6051 100644 --- a/third_party/blink/renderer/core/animation/animation_test.cc +++ b/third_party/blink/renderer/core/animation/animation_test.cc
@@ -33,6 +33,7 @@ #include <memory> #include "base/bits.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/core/animation/animation_clock.h" #include "third_party/blink/renderer/core/animation/css/compositor_keyframe_double.h" @@ -45,6 +46,8 @@ #include "third_party/blink/renderer/core/animation/scroll_timeline.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/dom_node_ids.h" +#include "third_party/blink/renderer/core/dom/events/event.h" +#include "third_party/blink/renderer/core/dom/events/native_event_listener.h" #include "third_party/blink/renderer/core/dom/qualified_name.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" @@ -1349,4 +1352,120 @@ EXPECT_FALSE(is_null); } +TEST_F(AnimationAnimationTestNoCompositing, + RemoveCanceledAnimationFromActiveSet) { + EXPECT_EQ("running", animation->playState()); + EXPECT_TRUE(animation->Update(kTimingUpdateForAnimationFrame)); + SimulateFrame(1000); + EXPECT_TRUE(animation->Update(kTimingUpdateForAnimationFrame)); + animation->cancel(); + EXPECT_EQ("idle", animation->playState()); + EXPECT_FALSE(animation->Update(kTimingUpdateForAnimationFrame)); +} + +TEST_F(AnimationAnimationTestNoCompositing, + RemoveFinishedAnimationFromActiveSet) { + EXPECT_EQ("running", animation->playState()); + EXPECT_TRUE(animation->Update(kTimingUpdateForAnimationFrame)); + SimulateFrame(1000); + EXPECT_TRUE(animation->Update(kTimingUpdateForAnimationFrame)); + + // Synchronous completion. + animation->finish(); + EXPECT_EQ("finished", animation->playState()); + EXPECT_FALSE(animation->Update(kTimingUpdateForAnimationFrame)); + + // Play creates a new pending finished promise. + animation->play(); + EXPECT_EQ("running", animation->playState()); + EXPECT_TRUE(animation->Update(kTimingUpdateForAnimationFrame)); + + // Asynchronous completion. + animation->setCurrentTime(50000, false); + EXPECT_EQ("finished", animation->playState()); + EXPECT_FALSE(animation->Update(kTimingUpdateForAnimationFrame)); +} + +TEST_F(AnimationAnimationTestNoCompositing, + PendingActivityWithFinishedPromise) { + // No pending activity even when running if there is no finished promise + // or event listener. + EXPECT_EQ("running", animation->playState()); + SimulateFrame(1000); + EXPECT_FALSE(animation->HasPendingActivity()); + + // An unresolved finished promise indicates pending activity. + ScriptState* script_state = + ToScriptStateForMainWorld(GetDocument().GetFrame()); + animation->finished(script_state); + EXPECT_TRUE(animation->HasPendingActivity()); + + // Resolving the finished promise clears the pending activity. + animation->setCurrentTime(50000, false); + EXPECT_EQ("finished", animation->playState()); + EXPECT_FALSE(animation->Update(kTimingUpdateForAnimationFrame)); + EXPECT_FALSE(animation->HasPendingActivity()); + + // Playing an already finished animation creates a new pending finished + // promise. + animation->play(); + EXPECT_EQ("running", animation->playState()); + SimulateFrame(2000); + EXPECT_TRUE(animation->HasPendingActivity()); + // Cancel rejects the finished promise and creates a new pending finished + // promise. + // TODO(crbug.com/960944): Investigate if this should return false to prevent + // holding onto the animation indefinitely. + animation->cancel(); + EXPECT_TRUE(animation->HasPendingActivity()); +} + +class MockEventListener final : public NativeEventListener { + public: + MOCK_METHOD2(Invoke, void(ExecutionContext*, Event*)); +}; + +TEST_F(AnimationAnimationTestNoCompositing, + PendingActivityWithFinishedEventListener) { + EXPECT_EQ("running", animation->playState()); + EXPECT_FALSE(animation->HasPendingActivity()); + + // Attaching a listener for the finished event indicates pending activity. + Persistent<MockEventListener> event_listener = + MakeGarbageCollected<MockEventListener>(); + animation->addEventListener(event_type_names::kFinish, event_listener); + EXPECT_TRUE(animation->HasPendingActivity()); + + // Synchronous finish clears pending activity. + animation->finish(); + EXPECT_EQ("finished", animation->playState()); + EXPECT_FALSE(animation->Update(kTimingUpdateForAnimationFrame)); + EXPECT_TRUE(animation->HasPendingActivity()); + animation->pending_finished_event_ = nullptr; + EXPECT_FALSE(animation->HasPendingActivity()); + + // Playing an already finished animation resets the finished state. + animation->play(); + EXPECT_EQ("running", animation->playState()); + SimulateFrame(2000); + EXPECT_TRUE(animation->HasPendingActivity()); + + // Finishing the animation asynchronously clears the pending activity. + animation->setCurrentTime(50000, false); + EXPECT_EQ("finished", animation->playState()); + EXPECT_FALSE(animation->Update(kTimingUpdateForAnimationFrame)); + EXPECT_TRUE(animation->HasPendingActivity()); + animation->pending_finished_event_ = nullptr; + EXPECT_FALSE(animation->HasPendingActivity()); + + // Canceling an animation clears the pending activity. + animation->play(); + EXPECT_EQ("running", animation->playState()); + SimulateFrame(2000); + animation->cancel(); + EXPECT_EQ("idle", animation->playState()); + EXPECT_FALSE(animation->Update(kTimingUpdateForAnimationFrame)); + EXPECT_FALSE(animation->HasPendingActivity()); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/animation/keyframe_effect_test.cc b/third_party/blink/renderer/core/animation/keyframe_effect_test.cc index 7283904..50440af 100644 --- a/third_party/blink/renderer/core/animation/keyframe_effect_test.cc +++ b/third_party/blink/renderer/core/animation/keyframe_effect_test.cc
@@ -168,7 +168,7 @@ effect_options_dictionary, exception_state); EXPECT_FALSE(exception_state.HadException()); - ScriptValue js_keyframes = ScriptValue::CreateNull(script_state); + ScriptValue js_keyframes = ScriptValue::CreateNull(scope.GetIsolate()); KeyframeEffect* effect = CreateAnimationFromOption( script_state, element.Get(), js_keyframes, effect_options_dictionary); EXPECT_EQ("add", effect->composite()); @@ -220,7 +220,7 @@ TEST_F(AnimationKeyframeEffectV8Test, CanSetDuration) { V8TestingScope scope; ScriptState* script_state = scope.GetScriptState(); - ScriptValue js_keyframes = ScriptValue::CreateNull(script_state); + ScriptValue js_keyframes = ScriptValue::CreateNull(scope.GetIsolate()); double duration = 2000; KeyframeEffect* animation = CreateAnimationFromTiming( @@ -233,7 +233,7 @@ TEST_F(AnimationKeyframeEffectV8Test, CanOmitSpecifiedDuration) { V8TestingScope scope; ScriptState* script_state = scope.GetScriptState(); - ScriptValue js_keyframes = ScriptValue::CreateNull(script_state); + ScriptValue js_keyframes = ScriptValue::CreateNull(scope.GetIsolate()); KeyframeEffect* animation = CreateAnimation(script_state, element.Get(), js_keyframes); EXPECT_FALSE(animation->SpecifiedTiming().iteration_duration); @@ -242,7 +242,7 @@ TEST_F(AnimationKeyframeEffectV8Test, SpecifiedGetters) { V8TestingScope scope; ScriptState* script_state = scope.GetScriptState(); - ScriptValue js_keyframes = ScriptValue::CreateNull(script_state); + ScriptValue js_keyframes = ScriptValue::CreateNull(scope.GetIsolate()); v8::Local<v8::Object> timing_input = v8::Object::New(scope.GetIsolate()); SetV8ObjectPropertyAsNumber(scope.GetIsolate(), timing_input, "delay", 2); @@ -281,7 +281,7 @@ TEST_F(AnimationKeyframeEffectV8Test, SpecifiedDurationGetter) { V8TestingScope scope; ScriptState* script_state = scope.GetScriptState(); - ScriptValue js_keyframes = ScriptValue::CreateNull(script_state); + ScriptValue js_keyframes = ScriptValue::CreateNull(scope.GetIsolate()); v8::Local<v8::Object> timing_input_with_duration = v8::Object::New(scope.GetIsolate()); @@ -329,7 +329,7 @@ ScopedCSSAdditiveAnimationsForTest css_additive_animation(false); V8TestingScope scope; ScriptState* script_state = scope.GetScriptState(); - ScriptValue js_keyframes = ScriptValue::CreateNull(script_state); + ScriptValue js_keyframes = ScriptValue::CreateNull(scope.GetIsolate()); v8::Local<v8::Object> timing_input = v8::Object::New(scope.GetIsolate()); KeyframeEffectOptions* timing_input_dictionary = KeyframeEffectOptions::Create();
diff --git a/third_party/blink/renderer/core/css/BUILD.gn b/third_party/blink/renderer/core/css/BUILD.gn index 5372cf79..1cf96b76b 100644 --- a/third_party/blink/renderer/core/css/BUILD.gn +++ b/third_party/blink/renderer/core/css/BUILD.gn
@@ -353,6 +353,8 @@ "layout_tree_rebuild_root.h", "local_font_face_source.cc", "local_font_face_source.h", + "media_feature_overrides.cc", + "media_feature_overrides.h", "media_list.cc", "media_list.h", "media_query.cc", @@ -621,6 +623,7 @@ "invalidation/invalidation_set_test.cc", "invalidation/pending_invalidations_test.cc", "invalidation/style_invalidator_test.cc", + "media_feature_overrides_test.cc", "media_query_evaluator_test.cc", "media_query_list_test.cc", "media_query_matcher_test.cc",
diff --git a/third_party/blink/renderer/core/css/media_feature_overrides.cc b/third_party/blink/renderer/core/css/media_feature_overrides.cc new file mode 100644 index 0000000..c6a0850 --- /dev/null +++ b/third_party/blink/renderer/core/css/media_feature_overrides.cc
@@ -0,0 +1,25 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/core/css/media_feature_overrides.h" + +#include "third_party/blink/renderer/core/css/parser/css_parser_token_range.h" +#include "third_party/blink/renderer/core/css/parser/css_tokenizer.h" + +namespace blink { + +void MediaFeatureOverrides::SetOverride(const AtomicString& feature, + const String& value_string) { + CSSTokenizer tokenizer(value_string); + const auto tokens = tokenizer.TokenizeToEOF(); + CSSParserTokenRange range(tokens); + auto value = MediaQueryExp::Create(feature, range).ExpValue(); + + if (value.IsValid()) + overrides_.Set(feature, value); + else + overrides_.erase(feature); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/css/media_feature_overrides.h b/third_party/blink/renderer/core/css/media_feature_overrides.h new file mode 100644 index 0000000..96e2e1d --- /dev/null +++ b/third_party/blink/renderer/core/css/media_feature_overrides.h
@@ -0,0 +1,27 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_MEDIA_FEATURE_OVERRIDES_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_MEDIA_FEATURE_OVERRIDES_H_ + +#include "third_party/blink/renderer/core/css/media_query_exp.h" +#include "third_party/blink/renderer/platform/wtf/hash_map.h" +#include "third_party/blink/renderer/platform/wtf/text/atomic_string_hash.h" + +namespace blink { + +class CORE_EXPORT MediaFeatureOverrides { + public: + void SetOverride(const AtomicString& feature, const String& value_string); + MediaQueryExpValue GetOverride(const AtomicString& feature) const { + return overrides_.at(feature); + } + + private: + HashMap<AtomicString, MediaQueryExpValue> overrides_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_MEDIA_FEATURE_OVERRIDES_H_
diff --git a/third_party/blink/renderer/core/css/media_feature_overrides_test.cc b/third_party/blink/renderer/core/css/media_feature_overrides_test.cc new file mode 100644 index 0000000..573d6f0c --- /dev/null +++ b/third_party/blink/renderer/core/css/media_feature_overrides_test.cc
@@ -0,0 +1,59 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/core/css/media_feature_overrides.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace blink { + +TEST(MediaFeatureOverrides, GetOverrideInitial) { + MediaFeatureOverrides overrides; + + EXPECT_FALSE(overrides.GetOverride("unknown").IsValid()); + EXPECT_FALSE(overrides.GetOverride("prefers-color-scheme").IsValid()); + EXPECT_FALSE(overrides.GetOverride("display-mode").IsValid()); +} + +TEST(MediaFeatureOverrides, SetOverrideInvalid) { + MediaFeatureOverrides overrides; + + overrides.SetOverride("prefers-color-scheme", "1px"); + EXPECT_FALSE(overrides.GetOverride("prefers-color-scheme").IsValid()); + + overrides.SetOverride("prefers-color-scheme", "orange"); + EXPECT_FALSE(overrides.GetOverride("prefers-color-scheme").IsValid()); +} + +TEST(MediaFeatureOverrides, SetOverrideValid) { + MediaFeatureOverrides overrides; + + overrides.SetOverride("prefers-color-scheme", "light"); + auto light_override = overrides.GetOverride("prefers-color-scheme"); + EXPECT_TRUE(light_override.IsValid()); + EXPECT_TRUE(light_override.is_id); + EXPECT_EQ(CSSValueID::kLight, light_override.id); + + overrides.SetOverride("prefers-color-scheme", "dark"); + auto dark_override = overrides.GetOverride("prefers-color-scheme"); + EXPECT_TRUE(dark_override.IsValid()); + EXPECT_TRUE(dark_override.is_id); + EXPECT_EQ(CSSValueID::kDark, dark_override.id); +} + +TEST(MediaFeatureOverrides, ResetOverride) { + MediaFeatureOverrides overrides; + + overrides.SetOverride("prefers-color-scheme", "light"); + EXPECT_TRUE(overrides.GetOverride("prefers-color-scheme").IsValid()); + overrides.SetOverride("prefers-color-scheme", ""); + EXPECT_FALSE(overrides.GetOverride("prefers-color-scheme").IsValid()); + + overrides.SetOverride("prefers-color-scheme", "light"); + EXPECT_TRUE(overrides.GetOverride("prefers-color-scheme").IsValid()); + overrides.SetOverride("prefers-color-scheme", "invalid"); + EXPECT_FALSE(overrides.GetOverride("prefers-color-scheme").IsValid()); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/css/media_values.cc b/third_party/blink/renderer/core/css/media_values.cc index c31ccf3..63f27de 100644 --- a/third_party/blink/renderer/core/css/media_values.cc +++ b/third_party/blink/renderer/core/css/media_values.cc
@@ -6,6 +6,7 @@ #include "third_party/blink/public/platform/web_screen_info.h" #include "third_party/blink/renderer/core/css/css_resolution_units.h" +#include "third_party/blink/renderer/core/css/media_feature_overrides.h" #include "third_party/blink/renderer/core/css/media_values_cached.h" #include "third_party/blink/renderer/core/css/media_values_dynamic.h" #include "third_party/blink/renderer/core/dom/document.h" @@ -22,6 +23,20 @@ namespace blink { +PreferredColorScheme CSSValueIDToPreferredColorScheme(CSSValueID id) { + switch (id) { + case CSSValueID::kNoPreference: + return PreferredColorScheme::kNoPreference; + case CSSValueID::kLight: + return PreferredColorScheme::kLight; + case CSSValueID::kDark: + return PreferredColorScheme::kDark; + default: + NOTREACHED(); + return PreferredColorScheme::kNoPreference; + } +} + MediaValues* MediaValues::CreateDynamicIfFrameExists(LocalFrame* frame) { if (frame) return MediaValuesDynamic::Create(frame); @@ -181,12 +196,23 @@ DCHECK(frame); DCHECK(frame->GetSettings()); DCHECK(frame->GetDocument()); + DCHECK(frame->GetPage()); + if (const auto* overrides = frame->GetPage()->GetMediaFeatureOverrides()) { + MediaQueryExpValue value = overrides->GetOverride("prefers-color-scheme"); + if (value.IsValid()) + return CSSValueIDToPreferredColorScheme(value.id); + } return frame->GetDocument()->GetStyleEngine().GetPreferredColorScheme(); } bool MediaValues::CalculatePrefersReducedMotion(LocalFrame* frame) { DCHECK(frame); DCHECK(frame->GetSettings()); + if (const auto* overrides = frame->GetPage()->GetMediaFeatureOverrides()) { + MediaQueryExpValue value = overrides->GetOverride("prefers-reduced-motion"); + if (value.IsValid()) + return value.id == CSSValueID::kReduce; + } return frame->GetSettings()->GetPrefersReducedMotion(); }
diff --git a/third_party/blink/renderer/core/css/media_values.h b/third_party/blink/renderer/core/css/media_values.h index 9ec41d4..ef3a352 100644 --- a/third_party/blink/renderer/core/css/media_values.h +++ b/third_party/blink/renderer/core/css/media_values.h
@@ -17,10 +17,13 @@ class Document; class CSSPrimitiveValue; class LocalFrame; +enum class CSSValueID; enum class ColorSpaceGamut; enum class PreferredColorScheme; enum class ForcedColors; +PreferredColorScheme CSSValueIDToPreferredColorScheme(CSSValueID id); + class CORE_EXPORT MediaValues : public GarbageCollected<MediaValues> { public: virtual ~MediaValues() = default;
diff --git a/third_party/blink/renderer/core/css/style_engine.cc b/third_party/blink/renderer/core/css/style_engine.cc index e31b232..65a3531 100644 --- a/third_party/blink/renderer/core/css/style_engine.cc +++ b/third_party/blink/renderer/core/css/style_engine.cc
@@ -39,6 +39,8 @@ #include "third_party/blink/renderer/core/css/document_style_sheet_collector.h" #include "third_party/blink/renderer/core/css/font_face_cache.h" #include "third_party/blink/renderer/core/css/invalidation/invalidation_set.h" +#include "third_party/blink/renderer/core/css/media_feature_overrides.h" +#include "third_party/blink/renderer/core/css/media_values.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/css/resolver/scoped_style_resolver.h" @@ -1863,6 +1865,12 @@ PreferredColorScheme old_preferred_color_scheme = preferred_color_scheme_; preferred_color_scheme_ = settings->GetPreferredColorScheme(); + if (const auto* overrides = + GetDocument().GetPage()->GetMediaFeatureOverrides()) { + MediaQueryExpValue value = overrides->GetOverride("prefers-color-scheme"); + if (value.IsValid()) + preferred_color_scheme_ = CSSValueIDToPreferredColorScheme(value.id); + } bool use_dark_scheme = preferred_color_scheme_ == PreferredColorScheme::kDark && SupportsDarkColorScheme();
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 3722659..5af643f6 100644 --- a/third_party/blink/renderer/core/css/style_engine_test.cc +++ b/third_party/blink/renderer/core/css/style_engine_test.cc
@@ -1656,6 +1656,73 @@ GetCSSPropertyColor())); } +TEST_F(StyleEngineTest, MediaQueriesColorSchemeOverride) { + ScopedMediaQueryPrefersColorSchemeForTest feature_scope(true); + + EXPECT_EQ(PreferredColorScheme::kNoPreference, + GetDocument().GetSettings()->GetPreferredColorScheme()); + + GetDocument().body()->SetInnerHTMLFromString(R"HTML( + <style> + body { color: red } + @media (prefers-color-scheme: dark) { + body { color: green } + } + </style> + <body></body> + )HTML"); + + UpdateAllLifecyclePhases(); + EXPECT_EQ(MakeRGB(255, 0, 0), + GetDocument().body()->GetComputedStyle()->VisitedDependentColor( + GetCSSPropertyColor())); + + GetDocument().GetPage()->SetMediaFeatureOverride("prefers-color-scheme", + "dark"); + UpdateAllLifecyclePhases(); + EXPECT_EQ(MakeRGB(0, 128, 0), + GetDocument().body()->GetComputedStyle()->VisitedDependentColor( + GetCSSPropertyColor())); + + GetDocument().GetPage()->ClearMediaFeatureOverrides(); + UpdateAllLifecyclePhases(); + EXPECT_EQ(MakeRGB(255, 0, 0), + GetDocument().body()->GetComputedStyle()->VisitedDependentColor( + GetCSSPropertyColor())); +} + +TEST_F(StyleEngineTest, MediaQueriesReducedMotionOverride) { + EXPECT_FALSE(GetDocument().GetSettings()->GetPrefersReducedMotion()); + + GetDocument().body()->SetInnerHTMLFromString(R"HTML( + <style> + body { color: red } + @media (prefers-reduced-motion: reduce) { + body { color: green } + } + </style> + <body></body> + )HTML"); + + UpdateAllLifecyclePhases(); + EXPECT_EQ(MakeRGB(255, 0, 0), + GetDocument().body()->GetComputedStyle()->VisitedDependentColor( + GetCSSPropertyColor())); + + GetDocument().GetPage()->SetMediaFeatureOverride("prefers-reduced-motion", + "reduce"); + UpdateAllLifecyclePhases(); + EXPECT_EQ(MakeRGB(0, 128, 0), + GetDocument().body()->GetComputedStyle()->VisitedDependentColor( + GetCSSPropertyColor())); + + GetDocument().GetPage()->ClearMediaFeatureOverrides(); + UpdateAllLifecyclePhases(); + EXPECT_EQ(MakeRGB(255, 0, 0), + GetDocument().body()->GetComputedStyle()->VisitedDependentColor( + GetCSSPropertyColor())); +} + TEST_F(StyleEngineTest, ShadowRootStyleRecalcCrash) { GetDocument().body()->SetInnerHTMLFromString("<div id=host></div>"); auto* host = To<HTMLElement>(GetDocument().getElementById("host")); @@ -2035,6 +2102,26 @@ EXPECT_EQ(Color::kBlack, GetDocument().View()->BaseBackgroundColor()); } +TEST_F(StyleEngineTest, ColorSchemeOverride) { + ScopedCSSColorSchemeForTest enable_color_scheme(true); + + GetDocument().documentElement()->SetInlineStyleProperty( + CSSPropertyID::kColorScheme, "light dark"); + UpdateAllLifecyclePhases(); + + EXPECT_EQ( + WebColorScheme::kLight, + GetDocument().documentElement()->GetComputedStyle()->UsedColorScheme()); + + GetDocument().GetPage()->SetMediaFeatureOverride("prefers-color-scheme", + "dark"); + + UpdateAllLifecyclePhases(); + EXPECT_EQ( + WebColorScheme::kDark, + GetDocument().documentElement()->GetComputedStyle()->UsedColorScheme()); +} + TEST_F(StyleEngineTest, PseudoElementBaseComputedStyle) { GetDocument().body()->SetInnerHTMLFromString(R"HTML( <style>
diff --git a/third_party/blink/renderer/core/events/error_event.cc b/third_party/blink/renderer/core/events/error_event.cc index 2a9f4bc6..eb1f2e7 100644 --- a/third_party/blink/renderer/core/events/error_event.cc +++ b/third_party/blink/renderer/core/events/error_event.cc
@@ -44,7 +44,8 @@ return MakeGarbageCollected<ErrorEvent>( "Script error.", std::make_unique<SourceLocation>(String(), 0, 0, nullptr), - ScriptValue::CreateNull(script_state), &script_state->World()); + ScriptValue::CreateNull(script_state->GetIsolate()), + &script_state->World()); } ErrorEvent::ErrorEvent() @@ -65,7 +66,7 @@ initializer->hasLineno() ? initializer->lineno() : 0, initializer->hasColno() ? initializer->colno() : 0, nullptr); if (initializer->hasError()) { - error_.Set(script_state->GetIsolate(), initializer->error().V8Value()); + error_ = initializer->error().ToWorldSafeV8Reference(); } } @@ -78,7 +79,7 @@ location_(std::move(location)), world_(world) { if (!error.IsEmpty()) - error_.Set(error.GetIsolate(), error.V8Value()); + error_ = error.ToWorldSafeV8Reference(); } void ErrorEvent::SetUnsanitizedMessage(const String& message) { @@ -108,7 +109,7 @@ // thus passing it around would cause leakage. // 2) Errors cannot be cloned (or serialized): if (World() != &script_state->World() || error_.IsEmpty()) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); return ScriptValue(script_state, error_.Get(script_state)); }
diff --git a/third_party/blink/renderer/core/events/message_event.cc b/third_party/blink/renderer/core/events/message_event.cc index f941210..fc2e77b1 100644 --- a/third_party/blink/renderer/core/events/message_event.cc +++ b/third_party/blink/renderer/core/events/message_event.cc
@@ -73,8 +73,7 @@ data_type_(kDataTypeScriptValue), source_(nullptr) { if (initializer->hasData()) { - data_as_v8_value_.Set(initializer->data().GetIsolate(), - initializer->data().V8Value()); + data_as_v8_value_ = initializer->data().ToWorldSafeV8Reference(); } if (initializer->hasOrigin()) origin_ = initializer->origin(); @@ -195,7 +194,7 @@ initEvent(type, bubbles, cancelable); data_type_ = kDataTypeScriptValue; - data_as_v8_value_.Set(data.GetIsolate(), data.V8Value()); + data_as_v8_value_ = data.ToWorldSafeV8Reference(); is_data_dirty_ = true; origin_ = origin; last_event_id_ = last_event_id;
diff --git a/third_party/blink/renderer/core/feature_policy/feature_policy_features.json5 b/third_party/blink/renderer/core/feature_policy/feature_policy_features.json5 index 299b6a94..abc6f09 100644 --- a/third_party/blink/renderer/core/feature_policy/feature_policy_features.json5 +++ b/third_party/blink/renderer/core/feature_policy/feature_policy_features.json5
@@ -45,62 +45,62 @@ { name: "ClientHintDPR", feature_policy_name: "ch-dpr", - depends_on: ["ClientHintsFeaturePolicy"], + depends_on: ["FeaturePolicyForClientHints"], }, { name: "ClientHintDeviceMemory", feature_policy_name: "ch-device-memory", - depends_on: ["ClientHintsFeaturePolicy"], + depends_on: ["FeaturePolicyForClientHints"], }, { name: "ClientHintDownlink", feature_policy_name: "ch-downlink", - depends_on: ["ClientHintsFeaturePolicy"], + depends_on: ["FeaturePolicyForClientHints"], }, { name: "ClientHintECT", feature_policy_name: "ch-ect", - depends_on: ["ClientHintsFeaturePolicy"], + depends_on: ["FeaturePolicyForClientHints"], }, { name: "ClientHintLang", feature_policy_name: "ch-lang", - depends_on: ["ClientHintsFeaturePolicy"], + depends_on: ["FeaturePolicyForClientHints"], }, { name: "ClientHintRTT", feature_policy_name: "ch-rtt", - depends_on: ["ClientHintsFeaturePolicy"], + depends_on: ["FeaturePolicyForClientHints"], }, { name: "ClientHintUA", feature_policy_name: "ch-ua", - depends_on: ["ClientHintsFeaturePolicy"], + depends_on: ["FeaturePolicyForClientHints"], }, { name: "ClientHintUAArch", feature_policy_name: "ch-ua-arch", - depends_on: ["ClientHintsFeaturePolicy"], + depends_on: ["FeaturePolicyForClientHints"], }, { name: "ClientHintUAPlatform", feature_policy_name: "ch-ua-platform", - depends_on: ["ClientHintsFeaturePolicy"], + depends_on: ["FeaturePolicyForClientHints"], }, { name: "ClientHintUAModel", feature_policy_name: "ch-ua-model", - depends_on: ["ClientHintsFeaturePolicy"], + depends_on: ["FeaturePolicyForClientHints"], }, { name: "ClientHintViewportWidth", feature_policy_name: "ch-viewport-width", - depends_on: ["ClientHintsFeaturePolicy"], + depends_on: ["FeaturePolicyForClientHints"], }, { name: "ClientHintWidth", feature_policy_name: "ch-width", - depends_on: ["ClientHintsFeaturePolicy"], + depends_on: ["FeaturePolicyForClientHints"], }, { name: "DocumentAccess",
diff --git a/third_party/blink/renderer/core/fetch/body_stream_buffer_test.cc b/third_party/blink/renderer/core/fetch/body_stream_buffer_test.cc index 4c795238..1ef31be4 100644 --- a/third_party/blink/renderer/core/fetch/body_stream_buffer_test.cc +++ b/third_party/blink/renderer/core/fetch/body_stream_buffer_test.cc
@@ -59,7 +59,8 @@ ADD_FAILURE() << "Compilation fails"; return ScriptValue(); } - return ScriptValue(script_state, script->Run(script_state->GetContext())); + return ScriptValue(script_state->GetIsolate(), + script->Run(script_state->GetContext())); } ScriptValue EvalWithPrintingError(ScriptState* script_state, const char* s) { v8::TryCatch block(script_state->GetIsolate());
diff --git a/third_party/blink/renderer/core/frame/DEPS b/third_party/blink/renderer/core/frame/DEPS new file mode 100644 index 0000000..974ea72 --- /dev/null +++ b/third_party/blink/renderer/core/frame/DEPS
@@ -0,0 +1,5 @@ +specific_include_rules = { + "local_frame_back_forward_cache_test.cc": [ + "+base/run_loop.h", + ] +} \ No newline at end of file
diff --git a/third_party/blink/renderer/core/frame/local_frame_back_forward_cache_test.cc b/third_party/blink/renderer/core/frame/local_frame_back_forward_cache_test.cc index ab5e3cf..53e94ed 100644 --- a/third_party/blink/renderer/core/frame/local_frame_back_forward_cache_test.cc +++ b/third_party/blink/renderer/core/frame/local_frame_back_forward_cache_test.cc
@@ -4,6 +4,7 @@ #include "third_party/blink/renderer/core/frame/local_frame.h" +#include "base/run_loop.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h" #include "third_party/blink/renderer/bindings/core/v8/script_controller.h"
diff --git a/third_party/blink/renderer/core/html/BUILD.gn b/third_party/blink/renderer/core/html/BUILD.gn index da50720..7e64691 100644 --- a/third_party/blink/renderer/core/html/BUILD.gn +++ b/third_party/blink/renderer/core/html/BUILD.gn
@@ -584,6 +584,7 @@ deps = [ "//services/metrics/public/cpp:metrics_cpp", "//skia:skcms", + "//third_party/blink/public/strings", "//third_party/blink/renderer/core/html/parser:parser", ] }
diff --git a/third_party/blink/renderer/core/html/forms/DEPS b/third_party/blink/renderer/core/html/forms/DEPS new file mode 100644 index 0000000..4a90b3a --- /dev/null +++ b/third_party/blink/renderer/core/html/forms/DEPS
@@ -0,0 +1,5 @@ +specific_include_rules = { + "file_input_type_test.cc": [ + "+base/run_loop.h", + ] +} \ No newline at end of file
diff --git a/third_party/blink/renderer/core/html/forms/date_time_chooser_impl.cc b/third_party/blink/renderer/core/html/forms/date_time_chooser_impl.cc index d50788a..74478dc8 100644 --- a/third_party/blink/renderer/core/html/forms/date_time_chooser_impl.cc +++ b/third_party/blink/renderer/core/html/forms/date_time_chooser_impl.cc
@@ -117,8 +117,7 @@ other_date_label_string = GetLocale().QueryString(WebLocalizedString::kOtherWeekLabel); } else { - today_label_string = - GetLocale().QueryString(WebLocalizedString::kCalendarToday); + today_label_string = GetLocale().QueryString(IDS_FORM_CALENDAR_TODAY); other_date_label_string = GetLocale().QueryString(WebLocalizedString::kOtherDateLabel); } @@ -155,8 +154,7 @@ data); AddProperty("locale", parameters_->locale.GetString(), data); AddProperty("todayLabel", today_label_string, data); - AddProperty("clearLabel", - GetLocale().QueryString(WebLocalizedString::kCalendarClear), + AddProperty("clearLabel", GetLocale().QueryString(IDS_FORM_CALENDAR_CLEAR), data); AddProperty("weekLabel", GetLocale().QueryString(WebLocalizedString::kWeekNumberLabel),
diff --git a/third_party/blink/renderer/core/html/forms/file_input_type_test.cc b/third_party/blink/renderer/core/html/forms/file_input_type_test.cc index bdf321a..76fc73e 100644 --- a/third_party/blink/renderer/core/html/forms/file_input_type_test.cc +++ b/third_party/blink/renderer/core/html/forms/file_input_type_test.cc
@@ -4,6 +4,7 @@ #include "third_party/blink/renderer/core/html/forms/file_input_type.h" +#include "base/run_loop.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/core/clipboard/data_object.h" #include "third_party/blink/renderer/core/dom/document.h"
diff --git a/third_party/blink/renderer/core/inspector/inspector_performance_agent.cc b/third_party/blink/renderer/core/inspector/inspector_performance_agent.cc index a2b2823..c8222ba0 100644 --- a/third_party/blink/renderer/core/inspector/inspector_performance_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_performance_agent.cc
@@ -16,6 +16,7 @@ #include "third_party/blink/renderer/core/probe/core_probes.h" #include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h" #include "third_party/blink/renderer/platform/instrumentation/instance_counters.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread.h" namespace blink {
diff --git a/third_party/blink/renderer/core/layout/BUILD.gn b/third_party/blink/renderer/core/layout/BUILD.gn index a93d0d54..47330337 100644 --- a/third_party/blink/renderer/core/layout/BUILD.gn +++ b/third_party/blink/renderer/core/layout/BUILD.gn
@@ -444,6 +444,7 @@ "ng/ng_constraint_space_builder.h", "ng/ng_container_fragment_builder.cc", "ng/ng_container_fragment_builder.h", + "ng/ng_early_break.h", "ng/ng_fieldset_layout_algorithm.cc", "ng/ng_fieldset_layout_algorithm.h", "ng/ng_flex_layout_algorithm.cc",
diff --git a/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.cc b/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.cc index 8d6b0ecc..b052acc1 100644 --- a/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.cc +++ b/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.cc
@@ -135,6 +135,10 @@ return false; } LayoutUnit FreeSpaceForStretchAutoTracksStep() const override; + LayoutUnit MinContentForChild(LayoutBox&) const override; + LayoutUnit MinLogicalSizeForChild(LayoutBox&, + const Length& child_min_size, + LayoutUnit available_size) const override; bool IsComputingSizeContainment() const override { return false; } }; @@ -149,10 +153,18 @@ GridLayoutUtils::FlowAwareDirectionForChild(grid, child, kForColumns); if (direction == child_inline_direction) { return child.HasRelativeLogicalWidth() || - child.StyleRef().LogicalWidth().IsIntrinsicOrAuto(); + child.StyleRef().LogicalWidth().IsIntrinsicOrAuto() || + child.StyleRef().MarginStart().IsPercentOrCalc() || + child.StyleRef().MarginEnd().IsPercentOrCalc() || + child.StyleRef().PaddingStart().IsPercentOrCalc() || + child.StyleRef().PaddingEnd().IsPercentOrCalc(); } return child.HasRelativeLogicalHeight() || - child.StyleRef().LogicalHeight().IsIntrinsicOrAuto(); + child.StyleRef().LogicalHeight().IsIntrinsicOrAuto() || + child.StyleRef().MarginBefore().IsPercentOrCalc() || + child.StyleRef().MarginAfter().IsPercentOrCalc() || + child.StyleRef().PaddingBefore().IsPercentOrCalc() || + child.StyleRef().PaddingAfter().IsPercentOrCalc(); } void GridTrackSizingAlgorithmStrategy:: @@ -404,21 +416,8 @@ LayoutUnit grid_area_size = algorithm_.GridAreaBreadthForChild(child, child_inline_direction); - - if (is_row_axis) { - return MinLogicalWidthForChild(child, child_min_size, grid_area_size) + - baseline_shim; - } - - bool override_size_has_changed = - UpdateOverrideContainingBlockContentSizeForChild( - child, child_inline_direction, grid_area_size); - LayoutGridItemForMinSizeComputation(child, override_size_has_changed); - - return child.ComputeLogicalHeightUsing(kMinSize, child_min_size, - child.IntrinsicLogicalHeight()) + - GridLayoutUtils::MarginLogicalHeightForChild(*GetLayoutGrid(), child) + - child.ScrollbarLogicalHeight() + baseline_shim; + return MinLogicalSizeForChild(child, child_min_size, grid_area_size) + + baseline_shim; } bool GridTrackSizingAlgorithm::CanParticipateInBaselineAlignment( @@ -526,13 +525,47 @@ available_logical_space); } -LayoutUnit GridTrackSizingAlgorithmStrategy::MinLogicalWidthForChild( +LayoutUnit GridTrackSizingAlgorithmStrategy::MinLogicalSizeForChild( LayoutBox& child, const Length& child_min_size, LayoutUnit available_size) const { - return child.ComputeLogicalWidthUsing(kMinSize, child_min_size, - available_size, GetLayoutGrid()) + - GridLayoutUtils::MarginLogicalWidthForChild(*GetLayoutGrid(), child); + GridTrackSizingDirection child_inline_direction = + GridLayoutUtils::FlowAwareDirectionForChild(*GetLayoutGrid(), child, + kForColumns); + bool is_row_axis = Direction() == child_inline_direction; + + if (is_row_axis) { + return child.ComputeLogicalWidthUsing(kMinSize, child_min_size, + available_size, GetLayoutGrid()) + + GridLayoutUtils::MarginLogicalWidthForChild(*GetLayoutGrid(), child); + } + + bool override_size_has_changed = + UpdateOverrideContainingBlockContentSizeForChild( + child, child_inline_direction, available_size); + LayoutGridItemForMinSizeComputation(child, override_size_has_changed); + + return child.ComputeLogicalHeightUsing(kMinSize, child_min_size, + child.IntrinsicLogicalHeight()) + + GridLayoutUtils::MarginLogicalHeightForChild(*GetLayoutGrid(), child); +} + +LayoutUnit DefiniteSizeStrategy::MinLogicalSizeForChild( + LayoutBox& child, + const Length& child_min_size, + LayoutUnit available_size) const { + GridTrackSizingDirection child_inline_direction = + GridLayoutUtils::FlowAwareDirectionForChild(*GetLayoutGrid(), child, + kForColumns); + LayoutUnit indefinite_size = + Direction() == child_inline_direction ? LayoutUnit() : LayoutUnit(-1); + if (ShouldClearOverrideContainingBlockContentSizeForChild( + *GetLayoutGrid(), child, Direction())) { + SetOverrideContainingBlockContentSizeForChild(child, Direction(), + indefinite_size); + } + return GridTrackSizingAlgorithmStrategy::MinLogicalSizeForChild( + child, child_min_size, available_size); } void DefiniteSizeStrategy::LayoutGridItemForMinSizeComputation( @@ -577,6 +610,21 @@ return algorithm_.FreeSpace(Direction()).value(); } +DISABLE_CFI_PERF +LayoutUnit DefiniteSizeStrategy::MinContentForChild(LayoutBox& child) const { + GridTrackSizingDirection child_inline_direction = + GridLayoutUtils::FlowAwareDirectionForChild(*GetLayoutGrid(), child, + kForColumns); + if (Direction() == child_inline_direction && child.NeedsLayout() && + ShouldClearOverrideContainingBlockContentSizeForChild( + *GetLayoutGrid(), child, child_inline_direction)) { + SetOverrideContainingBlockContentSizeForChild(child, child_inline_direction, + LayoutUnit()); + } + + return GridTrackSizingAlgorithmStrategy::MinContentForChild(child); +} + void IndefiniteSizeStrategy::LayoutGridItemForMinSizeComputation( LayoutBox& child, bool override_size_has_changed) const {
diff --git a/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.h b/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.h index 1f81a76..6107043 100644 --- a/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.h +++ b/third_party/blink/renderer/core/layout/grid_track_sizing_algorithm.h
@@ -293,9 +293,9 @@ GridTrackSizingAlgorithmStrategy(GridTrackSizingAlgorithm& algorithm) : algorithm_(algorithm) {} - virtual LayoutUnit MinLogicalWidthForChild(LayoutBox&, - const Length& child_min_size, - LayoutUnit available_size) const; + virtual LayoutUnit MinLogicalSizeForChild(LayoutBox&, + const Length& child_min_size, + LayoutUnit available_size) const; virtual void LayoutGridItemForMinSizeComputation( LayoutBox&, bool override_size_has_changed) const = 0;
diff --git a/third_party/blink/renderer/core/layout/layout_grid.cc b/third_party/blink/renderer/core/layout/layout_grid.cc index a418fdb..6599466 100644 --- a/third_party/blink/renderer/core/layout/layout_grid.cc +++ b/third_party/blink/renderer/core/layout/layout_grid.cc
@@ -1247,6 +1247,9 @@ } void LayoutGrid::LayoutGridItems() { + if (LayoutBlockedByDisplayLock(DisplayLockLifecycleTarget::kChildren)) + return; + PopulateGridPositionsForDirection(kForColumns); PopulateGridPositionsForDirection(kForRows); @@ -1325,6 +1328,9 @@ void LayoutGrid::LayoutPositionedObjects(bool relayout_children, PositionedLayoutBehavior info) { + if (LayoutBlockedByDisplayLock(DisplayLockLifecycleTarget::kChildren)) + return; + column_of_positioned_item_.clear(); row_of_positioned_item_.clear();
diff --git a/third_party/blink/renderer/core/layout/ng/custom/custom_layout_constraints.cc b/third_party/blink/renderer/core/layout/ng/custom/custom_layout_constraints.cc index 2bb3946..3ff221a 100644 --- a/third_party/blink/renderer/core/layout/ng/custom/custom_layout_constraints.cc +++ b/third_party/blink/renderer/core/layout/ng/custom/custom_layout_constraints.cc
@@ -43,7 +43,7 @@ DCHECK(script_state->World().IsWorkerWorld()); if (layout_worklet_world_v8_data_.IsEmpty()) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); return ScriptValue(script_state, layout_worklet_world_v8_data_.NewLocal( script_state->GetIsolate()));
diff --git a/third_party/blink/renderer/core/layout/ng/custom/custom_layout_fragment.cc b/third_party/blink/renderer/core/layout/ng/custom/custom_layout_fragment.cc index 83ea4e1..ce90299 100644 --- a/third_party/blink/renderer/core/layout/ng/custom/custom_layout_fragment.cc +++ b/third_party/blink/renderer/core/layout/ng/custom/custom_layout_fragment.cc
@@ -44,7 +44,7 @@ DCHECK(script_state->World().IsWorkerWorld()); if (layout_worklet_world_v8_data_.IsEmpty()) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); return ScriptValue(script_state, layout_worklet_world_v8_data_.NewLocal( script_state->GetIsolate()));
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc index ce3ceb09..b12baeb 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
@@ -19,6 +19,7 @@ #include "third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h" #include "third_party/blink/renderer/core/layout/ng/ng_constraint_space.h" #include "third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h" +#include "third_party/blink/renderer/core/layout/ng/ng_early_break.h" #include "third_party/blink/renderer/core/layout/ng/ng_floats_utils.h" #include "third_party/blink/renderer/core/layout/ng/ng_fragment.h" #include "third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.h" @@ -137,6 +138,11 @@ child_bfc_offset.block_offset - parent_bfc_offset.block_offset}; } +inline bool IsEarlyBreakpoint(const NGEarlyBreak& breakpoint, + const NGBoxFragmentBuilder& builder) { + return breakpoint.LineNumber() == builder.LineCount(); +} + } // namespace NGBlockLayoutAlgorithm::NGBlockLayoutAlgorithm( @@ -326,12 +332,22 @@ } scoped_refptr<const NGLayoutResult> NGBlockLayoutAlgorithm::Layout() { + scoped_refptr<const NGLayoutResult> result; // Inline children require an inline child layout context to be // passed between siblings. We want to stack-allocate that one, but // only on demand, as it's quite big. if (Node().ChildrenInline()) - return LayoutWithInlineChildLayoutContext(); - return Layout(nullptr); + result = LayoutWithInlineChildLayoutContext(); + else + result = Layout(nullptr); + if (UNLIKELY(result->Status() == NGLayoutResult::kNeedsEarlierBreak)) { + // If we found a good break somewhere inside this block, re-layout and break + // at that location. + DCHECK(!early_break_); + DCHECK(result->GetEarlyBreak()); + return RelayoutAndBreakEarlier(*result->GetEarlyBreak()); + } + return result; } NOINLINE scoped_refptr<const NGLayoutResult> @@ -357,6 +373,23 @@ return result; } +NOINLINE scoped_refptr<const NGLayoutResult> +NGBlockLayoutAlgorithm::RelayoutAndBreakEarlier( + const NGEarlyBreak& breakpoint) { + NGLayoutAlgorithmParams params(Node(), + container_builder_.InitialFragmentGeometry(), + ConstraintSpace(), BreakToken()); + NGBlockLayoutAlgorithm algorithm_with_break(params); + algorithm_with_break.early_break_ = &breakpoint; + NGBoxFragmentBuilder& new_builder = algorithm_with_break.container_builder_; + new_builder.SetBoxType(container_builder_.BoxType()); + // We're not going to run out of space in the next layout pass, since we're + // breaking earlier, so no space shortage will be detected. Repeat what we + // found in this pass. + new_builder.PropagateSpaceShortage(container_builder_.MinimalSpaceShortage()); + return algorithm_with_break.Layout(); +} + inline scoped_refptr<const NGLayoutResult> NGBlockLayoutAlgorithm::Layout( NGInlineChildLayoutContext* inline_child_layout_context) { const LogicalSize border_box_size = container_builder_.InitialBorderBoxSize(); @@ -526,6 +559,10 @@ } break; } else { + if (UNLIKELY(early_break_ && + FindEarlyBreakpoint(child, &previous_inflow_position))) + break; + bool abort; if (child.CreatesNewFormattingContext()) { abort = !HandleNewFormattingContext(child, child_break_token, @@ -726,8 +763,10 @@ // This may occur with a zero block size fragment. We need to know the BFC // block offset to determine where the fragmentation line is relative to us. if (container_builder_.BfcBlockOffset() && - ConstraintSpace().HasBlockFragmentation()) - FinalizeForFragmentation(); + ConstraintSpace().HasBlockFragmentation()) { + if (!FinalizeForFragmentation()) + return container_builder_.Abort(NGLayoutResult::kNeedsEarlierBreak); + } NGOutOfFlowLayoutPart( Node(), ConstraintSpace(), @@ -755,6 +794,19 @@ return container_builder_.ToBoxFragment(); } +bool NGBlockLayoutAlgorithm::FindEarlyBreakpoint( + NGLayoutInputNode child, + NGPreviousInflowPosition* previous_inflow_position) { + DCHECK(early_break_); + if (!IsEarlyBreakpoint(*early_break_, container_builder_)) + return false; + + container_builder_.AddBreakBeforeChild(child, /* is_forced_break */ false); + previous_inflow_position->logical_block_offset = + FragmentainerSpaceAvailable(); + return true; +} + const NGInlineBreakToken* NGBlockLayoutAlgorithm::TryReuseFragmentsFromCache( NGInlineNode inline_node, NGPreviousInflowPosition* previous_inflow_position, @@ -1879,7 +1931,7 @@ return block_offset >= FragmentainerSpaceAvailable(); } -void NGBlockLayoutAlgorithm::FinalizeForFragmentation() { +bool NGBlockLayoutAlgorithm::FinalizeForFragmentation() { if (first_overflowing_line_ && !fit_all_lines_) { // A line box overflowed the fragmentainer, but we continued layout anyway, // in order to determine where to break in order to honor the widows @@ -1913,26 +1965,36 @@ // detect that there's no room for a fragment for this node, and drop the // fragment on the floor. Therefore it doesn't matter how we set up the // container builder, so just return. - return; + return true; } - if (container_builder_.DidBreak() && first_overflowing_line_) { - int line_number; - if (fit_all_lines_) { - line_number = first_overflowing_line_; - } else { - // We managed to finish layout of all the lines for the node, which means - // that we won't have enough widows, unless we break earlier than where we - // overflowed. - int line_count = container_builder_.LineCount(); - line_number = std::max(line_count - Style().Widows(), - std::min(line_count, int(Style().Orphans()))); + if (Node().ChildrenInline()) { + if (container_builder_.DidBreak() || first_overflowing_line_) { + if (first_overflowing_line_ && + first_overflowing_line_ < container_builder_.LineCount()) { + int line_number; + if (fit_all_lines_) { + line_number = first_overflowing_line_; + } else { + // We managed to finish layout of all the lines for the node, which + // means that we won't have enough widows, unless we break earlier + // than where we overflowed. + int line_count = container_builder_.LineCount(); + line_number = std::max(line_count - Style().Widows(), + std::min(line_count, int(Style().Orphans()))); + } + // We need to layout again, and stop at the right line number. + NGEarlyBreak breakpoint(line_number); + container_builder_.SetEarlyBreak(breakpoint); + return false; + } } - container_builder_.AddBreakBeforeLine(line_number); } FinishFragmentation(&container_builder_, block_size, intrinsic_block_size_, consumed_block_size, space_left); + + return true; } bool NGBlockLayoutAlgorithm::BreakBeforeChild(
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.h index edd2d5b9..7e144a1 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.h +++ b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.h
@@ -20,6 +20,7 @@ namespace blink { class NGConstraintSpace; +class NGEarlyBreak; class NGFragment; class NGLayoutResult; class NGPhysicalLineBoxFragment; @@ -66,11 +67,22 @@ NOINLINE scoped_refptr<const NGLayoutResult> LayoutWithItemsBuilder( NGInlineChildLayoutContext* context); + // Lay out again, this time with a predefined good breakpoint that we + // discovered in the first pass. This happens when we run out of space in a + // fragmentainer at an less-than-ideal location, due to breaking restrictions, + // such as orphans or widows. + NOINLINE scoped_refptr<const NGLayoutResult> RelayoutAndBreakEarlier( + const NGEarlyBreak&); + inline scoped_refptr<const NGLayoutResult> Layout( NGInlineChildLayoutContext* inline_child_layout_context); scoped_refptr<const NGLayoutResult> FinishLayout(NGPreviousInflowPosition*); + // If the child is the one we have already determined to break before, do so + // and return true. Otherwise, return false. + bool FindEarlyBreakpoint(NGLayoutInputNode child, NGPreviousInflowPosition*); + // Return the BFC block offset of this block. LayoutUnit BfcBlockOffset() const { // If we have resolved our BFC block offset, use that. @@ -230,10 +242,13 @@ LayoutUnit block_offset, bool is_pushed_by_floats) const; - // Final adjustments before fragment creation. We need to prevent the - // fragment from crossing fragmentainer boundaries, and rather create a break - // token if we're out of space. - void FinalizeForFragmentation(); + // Final adjustments before fragment creation. We need to prevent the fragment + // from crossing fragmentainer boundaries, and rather create a break token if + // we're out of space. As part of finalizing we may also discover that we need + // to abort layout, because we've run out of space at a less-than-ideal + // location. In this case, false will be returned. Otherwise, true will be + // returned. + bool FinalizeForFragmentation(); void PropagateBaselinesFromChildren(); bool AddBaseline(const NGBaselineRequest&, @@ -364,6 +379,9 @@ bool has_processed_first_child_ = false; NGExclusionSpace exclusion_space_; + + // When set, this will specify where to break before or inside. + const NGEarlyBreak* early_break_ = nullptr; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.cc b/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.cc index c3fe64c..2771884 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.cc
@@ -100,33 +100,6 @@ child_break_tokens_.push_back(token); } -void NGBoxFragmentBuilder::AddBreakBeforeLine(int line_number) { - DCHECK(has_block_fragmentation_); - DCHECK_GT(line_number, 0); - DCHECK_LE(unsigned(line_number), inline_break_tokens_.size()); - SetDidBreak(); - int lines_to_remove = inline_break_tokens_.size() - line_number; - if (lines_to_remove > 0) { - // Remove widows that should be pushed to the next fragment. We'll also - // remove all other child fragments than line boxes (typically floats) that - // come after the first line that's moved, as those also have to be re-laid - // out in the next fragment. - inline_break_tokens_.resize(line_number); - DCHECK_GT(children_.size(), 0UL); - for (int i = children_.size() - 1; i >= 0; i--) { - DCHECK_NE(i, 0); - if (!children_[i].fragment->IsLineBox()) - continue; - if (!--lines_to_remove) { - // This is the first line that is going to the next fragment. Remove it, - // and everything after it. - children_.resize(i); - break; - } - } - } -} - void NGBoxFragmentBuilder::AddResult(const NGLayoutResult& child_layout_result, const LogicalOffset offset, const LayoutInline* inline_container) {
diff --git a/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h b/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h index 8f8dd37..ca29d37 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h +++ b/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h
@@ -63,6 +63,11 @@ is_initial_block_size_indefinite_ = size_.block_size == kIndefiniteSize; } + const NGFragmentGeometry& InitialFragmentGeometry() const { + DCHECK(initial_fragment_geometry_); + return *initial_fragment_geometry_; + } + void SetIntrinsicBlockSize(LayoutUnit intrinsic_block_size) { intrinsic_block_size_ = intrinsic_block_size; } @@ -89,9 +94,6 @@ // add a break token for the child, but no fragment. void AddBreakBeforeChild(NGLayoutInputNode child, bool is_forced_break); - // Prepare for a break token before the specified line. - void AddBreakBeforeLine(int line_number); - // Add a layout result. This involves appending the fragment and its relative // offset to the builder, but also keeping track of out-of-flow positioned // descendants, propagating fragmentainer breaks, and more. @@ -128,6 +130,7 @@ if (minimal_space_shortage_ > space_shortage) minimal_space_shortage_ = space_shortage; } + LayoutUnit MinimalSpaceShortage() const { return minimal_space_shortage_; } void SetInitialBreakBefore(EBreakBetween break_before) { initial_break_before_ = break_before; @@ -164,6 +167,9 @@ void SetColumnSpanner(NGBlockNode spanner) { column_spanner_ = spanner; } bool FoundColumnSpanner() const { return !!column_spanner_; } + void SetEarlyBreak(NGEarlyBreak breakpoint) { early_break_ = breakpoint; } + bool HasEarlyBreak() const { return early_break_.has_value(); } + // Offsets are not supposed to be set during fragment construction, so we // do not provide a setter here.
diff --git a/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm_test.cc b/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm_test.cc index 18edf3f..310a86f 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm_test.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm_test.cc
@@ -1876,6 +1876,57 @@ EXPECT_EQ(expectation, dump); } +TEST_F(NGColumnLayoutAlgorithmTest, WidowsAndAbspos) { + SetBodyInnerHTML(R"HTML( + <style> + #parent { + columns: 3; + column-fill: auto; + column-gap: 10px; + width: 320px; + height: 70px; + line-height: 20px; + orphans: 1; + widows: 3; + } + </style> + <div id="container"> + <div id="parent"> + <div style="position:relative;"> + <br> + <br> + <br> + <br> + <div style="position:absolute; width:33px; height:33px;"></div> + <br> + </div> + </div> + </div> + )HTML"); + + String dump = DumpFragmentTree(GetElementById("container")); + String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. + offset:unplaced size:1000x70 + offset:0,0 size:320x70 + offset:0,0 size:100x70 + offset:0,0 size:100x70 + offset:0,0 size:0x20 + offset:0,9 size:0x1 + offset:0,20 size:0x20 + offset:0,9 size:0x1 + offset:110,0 size:100x60 + offset:0,0 size:100x60 + offset:0,0 size:0x20 + offset:0,9 size:0x1 + offset:0,20 size:0x20 + offset:0,9 size:0x1 + offset:0,40 size:0x20 + offset:0,9 size:0x1 + offset:0,40 size:33x33 +)DUMP"; + EXPECT_EQ(expectation, dump); +} + // TODO(crbug.com/915929): Fix inline-level float fragmentation. TEST_F(NGColumnLayoutAlgorithmTest, DISABLED_FloatInBlockMovedByOrphans) { SetBodyInnerHTML(R"HTML(
diff --git a/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h b/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h index 9fc1edd..38d558f 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h +++ b/third_party/blink/renderer/core/layout/ng/ng_container_fragment_builder.h
@@ -13,6 +13,7 @@ #include "third_party/blink/renderer/core/layout/ng/geometry/ng_margin_strut.h" #include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.h" #include "third_party/blink/renderer/core/layout/ng/list/ng_unpositioned_list_marker.h" +#include "third_party/blink/renderer/core/layout/ng/ng_early_break.h" #include "third_party/blink/renderer/core/layout/ng/ng_floats_utils.h" #include "third_party/blink/renderer/core/layout/ng/ng_fragment_builder.h" #include "third_party/blink/renderer/core/layout/ng/ng_link.h" @@ -214,6 +215,8 @@ NGBreakTokenVector child_break_tokens_; NGBreakTokenVector inline_break_tokens_; + base::Optional<NGEarlyBreak> early_break_; + NGAdjoiningObjectTypes adjoining_object_types_ = kAdjoiningNone; bool has_adjoining_object_descendants_ = false;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_early_break.h b/third_party/blink/renderer/core/layout/ng/ng_early_break.h new file mode 100644 index 0000000..4e8880f --- /dev/null +++ b/third_party/blink/renderer/core/layout/ng/ng_early_break.h
@@ -0,0 +1,25 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_NG_EARLY_BREAK_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_NG_EARLY_BREAK_H_ + +namespace blink { + +// Possible early unforced breakpoint. This represents a possible (and good) +// location to break. In cases where we run out of space at an unideal location, +// we may want to go back and break here instead. +class NGEarlyBreak { + public: + explicit NGEarlyBreak(int line_number) : line_number_(line_number) {} + + int LineNumber() const { return line_number_; } + + private: + int line_number_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_NG_EARLY_BREAK_H_
diff --git a/third_party/blink/renderer/core/layout/ng/ng_layout_result.cc b/third_party/blink/renderer/core/layout/ng/ng_layout_result.cc index 495711087..d991ccd 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_layout_result.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_layout_result.cc
@@ -155,6 +155,11 @@ space_.ExclusionSpace().MoveDerivedGeometry(builder->exclusion_space_); } + // If we found an early breakpoint inside that we need to break at, we're + // going to re-layout now, and break at the early breakpoint. + if (builder->early_break_ && !physical_fragment_) + EnsureRareData()->early_break = *builder->early_break_; + if (HasRareData()) { rare_data_->bfc_line_offset = builder->bfc_line_offset_; rare_data_->bfc_block_offset = builder->bfc_block_offset_;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_layout_result.h b/third_party/blink/renderer/core/layout/ng/ng_layout_result.h index ae90f2a..f30903d 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_layout_result.h +++ b/third_party/blink/renderer/core/layout/ng/ng_layout_result.h
@@ -13,6 +13,7 @@ #include "third_party/blink/renderer/core/layout/ng/geometry/ng_margin_strut.h" #include "third_party/blink/renderer/core/layout/ng/list/ng_unpositioned_list_marker.h" #include "third_party/blink/renderer/core/layout/ng/ng_block_node.h" +#include "third_party/blink/renderer/core/layout/ng/ng_early_break.h" #include "third_party/blink/renderer/core/layout/ng/ng_floats_utils.h" #include "third_party/blink/renderer/core/layout/ng/ng_fragment.h" #include "third_party/blink/renderer/core/layout/ng/ng_link.h" @@ -38,6 +39,7 @@ enum NGLayoutResultStatus { kSuccess = 0, kBfcBlockOffsetResolved = 1, + kNeedsEarlierBreak = 2, // When adding new values, make sure the bit size of |Bitfields::status| is // large enough to store. }; @@ -75,6 +77,12 @@ return HasRareData() ? rare_data_->column_spanner : NGBlockNode(nullptr); } + const NGEarlyBreak* GetEarlyBreak() const { + if (!HasRareData()) + return nullptr; + return &rare_data_->early_break.value(); + } + const NGExclusionSpace& ExclusionSpace() const { if (bitfields_.has_rare_data_exclusion_space) { DCHECK(HasRareData()); @@ -294,6 +302,7 @@ LayoutUnit bfc_line_offset; base::Optional<LayoutUnit> bfc_block_offset; + base::Optional<NGEarlyBreak> early_break; LogicalOffset oof_positioned_offset; NGMarginStrut end_margin_strut; NGUnpositionedListMarker unpositioned_list_marker; @@ -362,7 +371,7 @@ unsigned initial_break_before : 4; // EBreakBetween unsigned final_break_after : 4; // EBreakBetween - unsigned status : 1; // NGLayoutResultStatus + unsigned status : 2; // NGLayoutResultStatus }; // The constraint space which generated this layout result, may not be valid
diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc index e2786f2..940cc33 100644 --- a/third_party/blink/renderer/core/loader/document_loader.cc +++ b/third_party/blink/renderer/core/loader/document_loader.cc
@@ -1637,10 +1637,6 @@ OriginTrialContext::ActivateNavigationFeaturesFromInitiator( document, &initiator_origin_trial_features_); } - bool stale_while_revalidate_enabled = - RuntimeEnabledFeatures::StaleWhileRevalidateEnabled(document); - document->Fetcher()->SetStaleWhileRevalidateEnabled( - stale_while_revalidate_enabled); bool opted_out_mixed_autoupgrade = EqualIgnoringASCIICase( response_.HttpHeaderField("mixed-content"), "noupgrade"); @@ -1651,11 +1647,6 @@ UMA_HISTOGRAM_BOOLEAN("MixedAutoupgrade.Navigation.OptedOut", opted_out_mixed_autoupgrade); - // If stale while revalidate is enabled via Origin Trials count it as such. - if (stale_while_revalidate_enabled && - !RuntimeEnabledFeatures::StaleWhileRevalidateEnabledByRuntimeFlag()) - UseCounter::Count(document, WebFeature::kStaleWhileRevalidateEnabled); - parser_ = document->OpenForNavigation(parsing_policy, mime_type, encoding); // If this is a scriptable parser and there is a resource, register the
diff --git a/third_party/blink/renderer/core/loader/idleness_detector.cc b/third_party/blink/renderer/core/loader/idleness_detector.cc index a0348835..dd1f4ce89 100644 --- a/third_party/blink/renderer/core/loader/idleness_detector.cc +++ b/third_party/blink/renderer/core/loader/idleness_detector.cc
@@ -18,6 +18,7 @@ #include "third_party/blink/renderer/core/probe/core_probes.h" #include "third_party/blink/renderer/platform/instrumentation/resource_coordinator/document_resource_coordinator.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread.h" namespace blink {
diff --git a/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.cc b/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.cc index 4d12ca0..e2c000bc 100644 --- a/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.cc +++ b/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.cc
@@ -342,6 +342,8 @@ void ModuleTreeLinker::FetchDescendants(const ModuleScript* module_script) { DCHECK(module_script); + v8::Isolate* isolate = modulator_->GetScriptState()->GetIsolate(); + v8::HandleScope scope(isolate); // [nospec] Abort the steps if the browsing context is discarded. if (!modulator_->HasValidContext()) { result_ = nullptr; @@ -349,9 +351,6 @@ return; } - // TODO(crbug.com/1000152): Replace ScriptState::Scope with v8::HandleScope - ScriptState::Scope scope(modulator_->GetScriptState()); - // <spec step="2">Let record be module script's record.</spec> v8::Local<v8::Module> record = module_script->V8Module();
diff --git a/third_party/blink/renderer/core/loader/resource/script_resource.h b/third_party/blink/renderer/core/loader/resource/script_resource.h index 4e31c0c..010d122 100644 --- a/third_party/blink/renderer/core/loader/resource/script_resource.h +++ b/third_party/blink/renderer/core/loader/resource/script_resource.h
@@ -37,6 +37,10 @@ #include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h" #include "third_party/blink/renderer/platform/loader/fetch/text_resource_decoder_options.h" +namespace mojo { +class SimpleWatcher; +} + namespace blink { class FetchParameters;
diff --git a/third_party/blink/renderer/core/loader/threaded_icon_loader.cc b/third_party/blink/renderer/core/loader/threaded_icon_loader.cc index 06a30a5..5a9c983 100644 --- a/third_party/blink/renderer/core/loader/threaded_icon_loader.cc +++ b/third_party/blink/renderer/core/loader/threaded_icon_loader.cc
@@ -16,6 +16,7 @@ #include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_request.h" #include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread.h" #include "third_party/blink/renderer/platform/scheduler/public/worker_pool.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" #include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
diff --git a/third_party/blink/renderer/core/loader/web_associated_url_loader_impl.cc b/third_party/blink/renderer/core/loader/web_associated_url_loader_impl.cc index 23db6c7..4b89d66 100644 --- a/third_party/blink/renderer/core/loader/web_associated_url_loader_impl.cc +++ b/third_party/blink/renderer/core/loader/web_associated_url_loader_impl.cc
@@ -58,6 +58,7 @@ #include "third_party/blink/renderer/platform/loader/fetch/resource_error.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h" #include "third_party/blink/renderer/platform/network/http_parsers.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread.h" #include "third_party/blink/renderer/platform/timer.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" #include "third_party/blink/renderer/platform/wtf/hash_set.h"
diff --git a/third_party/blink/renderer/core/page/page.cc b/third_party/blink/renderer/core/page/page.cc index a071c23..4e8dcaf 100644 --- a/third_party/blink/renderer/core/page/page.cc +++ b/third_party/blink/renderer/core/page/page.cc
@@ -25,6 +25,7 @@ #include "third_party/blink/public/web/blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_controller.h" #include "third_party/blink/renderer/bindings/core/v8/source_location.h" +#include "third_party/blink/renderer/core/css/media_feature_overrides.h" #include "third_party/blink/renderer/core/css/style_change_reason.h" #include "third_party/blink/renderer/core/css/style_engine.h" #include "third_party/blink/renderer/core/dom/events/event.h" @@ -977,6 +978,26 @@ } } +void Page::SetMediaFeatureOverride(const AtomicString& media_feature, + const String& value) { + if (!media_feature_overrides_) { + if (value.IsEmpty()) + return; + media_feature_overrides_ = std::make_unique<MediaFeatureOverrides>(); + } + media_feature_overrides_->SetOverride(media_feature, value); + if (media_feature == "prefers-color-scheme") + SettingsChanged(SettingsDelegate::kColorSchemeChange); + else + SettingsChanged(SettingsDelegate::kMediaQueryChange); +} + +void Page::ClearMediaFeatureOverrides() { + media_feature_overrides_.reset(); + SettingsChanged(SettingsDelegate::kMediaQueryChange); + SettingsChanged(SettingsDelegate::kColorSchemeChange); +} + Page::PageClients::PageClients() : chrome_client(nullptr) {} Page::PageClients::~PageClients() = default;
diff --git a/third_party/blink/renderer/core/page/page.h b/third_party/blink/renderer/core/page/page.h index f916d59..734027e 100644 --- a/third_party/blink/renderer/core/page/page.h +++ b/third_party/blink/renderer/core/page/page.h
@@ -63,6 +63,7 @@ class LinkHighlights; class LocalFrame; class LocalFrameView; +class MediaFeatureOverrides; class OverscrollController; struct PageScaleConstraints; class PageScaleConstraintsSet; @@ -323,6 +324,13 @@ return web_text_autosizer_page_info_; } + void SetMediaFeatureOverride(const AtomicString& media_feature, + const String& value); + const MediaFeatureOverrides* GetMediaFeatureOverrides() const { + return media_feature_overrides_.get(); + } + void ClearMediaFeatureOverrides(); + private: friend class ScopedPagePauser; @@ -419,6 +427,9 @@ std::unique_ptr<PageScheduler> page_scheduler_; + // Overrides for various media features set from the devtools. + std::unique_ptr<MediaFeatureOverrides> media_feature_overrides_; + int32_t autoplay_flags_; // Accessed by frames to determine whether to expose the PortalHost object.
diff --git a/third_party/blink/renderer/core/script/module_script.cc b/third_party/blink/renderer/core/script/module_script.cc index b742a27..3c4b687 100644 --- a/third_party/blink/renderer/core/script/module_script.cc +++ b/third_party/blink/renderer/core/script/module_script.cc
@@ -50,27 +50,23 @@ DCHECK(!error.IsEmpty()); record_.Clear(); - parse_error_.Set(error.GetIsolate(), error.V8Value()); + parse_error_ = error.ToWorldSafeV8Reference(); } ScriptValue ModuleScript::CreateParseError() const { - ScriptState* script_state = settings_object_->GetScriptState(); - v8::Isolate* isolate = script_state->GetIsolate(); - ScriptState::Scope scope(script_state); - ScriptValue error(script_state, parse_error_.NewLocal(isolate)); + v8::Isolate* isolate = settings_object_->GetScriptState()->GetIsolate(); + ScriptValue error(isolate, parse_error_); DCHECK(!error.IsEmpty()); return error; } void ModuleScript::SetErrorToRethrow(ScriptValue error) { - error_to_rethrow_.Set(error.GetIsolate(), error.V8Value()); + error_to_rethrow_ = error.ToWorldSafeV8Reference(); } ScriptValue ModuleScript::CreateErrorToRethrow() const { - ScriptState* script_state = settings_object_->GetScriptState(); - v8::Isolate* isolate = script_state->GetIsolate(); - ScriptState::Scope scope(script_state); - ScriptValue error(script_state, error_to_rethrow_.NewLocal(isolate)); + v8::Isolate* isolate = settings_object_->GetScriptState()->GetIsolate(); + ScriptValue error(isolate, error_to_rethrow_); DCHECK(!error.IsEmpty()); return error; }
diff --git a/third_party/blink/renderer/core/script/module_script.h b/third_party/blink/renderer/core/script/module_script.h index b949655..aabe3a6c 100644 --- a/third_party/blink/renderer/core/script/module_script.h +++ b/third_party/blink/renderer/core/script/module_script.h
@@ -7,6 +7,7 @@ #include "third_party/blink/renderer/bindings/core/v8/module_record.h" #include "third_party/blink/renderer/bindings/core/v8/script_value.h" +#include "third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/script/modulator.h" #include "third_party/blink/renderer/core/script/script.h" @@ -115,10 +116,10 @@ // https://github.com/whatwg/html/pull/2991. This shouldn't cause any // observable functional changes, and updating the classic script handling // will require moderate code changes (e.g. to move compilation timing). - TraceWrapperV8Reference<v8::Value> parse_error_; + WorldSafeV8Reference<v8::Value> parse_error_; // https://html.spec.whatwg.org/C/#concept-script-error-to-rethrow - TraceWrapperV8Reference<v8::Value> error_to_rethrow_; + WorldSafeV8Reference<v8::Value> error_to_rethrow_; mutable HashMap<String, KURL> specifier_to_url_cache_; KURL source_url_;
diff --git a/third_party/blink/renderer/core/script/pending_import_map.cc b/third_party/blink/renderer/core/script/pending_import_map.cc index 5e762238..d5fd6dc 100644 --- a/third_party/blink/renderer/core/script/pending_import_map.cc +++ b/third_party/blink/renderer/core/script/pending_import_map.cc
@@ -37,9 +37,7 @@ import_map_(import_map), original_context_document_(&original_context_document) { if (!error_to_rethrow.IsEmpty()) { - ScriptState::Scope scope(error_to_rethrow.GetScriptState()); - error_to_rethrow_.Set(error_to_rethrow.GetIsolate(), - error_to_rethrow.V8Value()); + error_to_rethrow_ = error_to_rethrow.ToWorldSafeV8Reference(); } } @@ -83,10 +81,8 @@ Modulator* modulator = Modulator::From(ToScriptStateForMainWorld(frame)); - ScriptState* script_state = modulator->GetScriptState(); - ScriptState::Scope scope(script_state); - ScriptValue error(script_state, - error_to_rethrow_.NewLocal(script_state->GetIsolate())); + v8::Isolate* isolate = modulator->GetScriptState()->GetIsolate(); + ScriptValue error(isolate, error_to_rethrow_); modulator->RegisterImportMap(import_map_, error); // <spec step="9">If element is from an external file, then fire an event
diff --git a/third_party/blink/renderer/core/script/pending_import_map.h b/third_party/blink/renderer/core/script/pending_import_map.h index 99a3578d..5fb56f7 100644 --- a/third_party/blink/renderer/core/script/pending_import_map.h +++ b/third_party/blink/renderer/core/script/pending_import_map.h
@@ -5,8 +5,8 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_PENDING_IMPORT_MAP_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_PENDING_IMPORT_MAP_H_ +#include "third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference.h" #include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" #include "third_party/blink/renderer/platform/heap/member.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" @@ -57,7 +57,7 @@ // https://wicg.github.io/import-maps/#import-map-parse-result-error-to-rethrow // The error is TypeError if the string is non-null, or null otherwise. - TraceWrapperV8Reference<v8::Value> error_to_rethrow_; + WorldSafeV8Reference<v8::Value> error_to_rethrow_; // https://wicg.github.io/import-maps/#import-map-parse-result-settings-object // The context document at the time when PrepareScript() is executed.
diff --git a/third_party/blink/renderer/core/streams/readable_stream_operations.cc b/third_party/blink/renderer/core/streams/readable_stream_operations.cc index 3012abf..a387185a 100644 --- a/third_party/blink/renderer/core/streams/readable_stream_operations.cc +++ b/third_party/blink/renderer/core/streams/readable_stream_operations.cc
@@ -87,7 +87,7 @@ v8::Local<v8::Value> js_strategy = strategy.V8Value(); v8::Local<v8::Value> args[] = {js_underlying_source, js_strategy}; return ScriptValue( - script_state, + script_state->GetIsolate(), V8ScriptRunner::CallExtra( script_state, "createReadableStreamWithExternalController", args)); } @@ -122,7 +122,7 @@ v8::Local<v8::Value> args[] = { v8::Number::New(script_state->GetIsolate(), high_water_mark)}; return ScriptValue( - script_state, + script_state->GetIsolate(), V8ScriptRunner::CallExtra(script_state, "createBuiltInCountQueuingStrategy", args)); } @@ -136,7 +136,7 @@ v8::TryCatch block(script_state->GetIsolate()); v8::Local<v8::Value> args[] = {stream.V8Value()}; ScriptValue result( - script_state, + script_state->GetIsolate(), V8ScriptRunner::CallExtra(script_state, "AcquireReadableStreamDefaultReader", args)); if (block.HasCaught()) { @@ -276,7 +276,7 @@ DCHECK(!port_v8_value.IsEmpty()); v8::Local<v8::Value> args[] = {stream.V8Value(), port_v8_value}; ScriptValue result( - script_state, + script_state->GetIsolate(), V8ScriptRunner::CallExtra(script_state, "ReadableStreamSerialize", args)); if (block.HasCaught()) { exception_state.RethrowV8Exception(block.Exception()); @@ -296,7 +296,7 @@ v8::Local<v8::Value> port_v8 = ToV8(port, script_state); DCHECK(!port_v8.IsEmpty()); v8::Local<v8::Value> args[] = {port_v8}; - ScriptValue result(script_state, + ScriptValue result(script_state->GetIsolate(), V8ScriptRunner::CallExtra( script_state, "ReadableStreamDeserialize", args)); if (block.HasCaught()) {
diff --git a/third_party/blink/renderer/core/streams/readable_stream_operations_test.cc b/third_party/blink/renderer/core/streams/readable_stream_operations_test.cc index 467820d..b047091b 100644 --- a/third_party/blink/renderer/core/streams/readable_stream_operations_test.cc +++ b/third_party/blink/renderer/core/streams/readable_stream_operations_test.cc
@@ -143,7 +143,7 @@ .value_or(true)); EXPECT_FALSE(ReadableStreamOperations::IsReadableStream( scope.GetScriptState(), - ScriptValue::CreateNull(scope.GetScriptState()), + ScriptValue::CreateNull(scope.GetIsolate()), ASSERT_NO_EXCEPTION) .value_or(true)); EXPECT_FALSE(ReadableStreamOperations::IsReadableStream( @@ -181,7 +181,7 @@ .value_or(true)); EXPECT_FALSE(ReadableStreamOperations::IsReadableStreamDefaultReader( scope.GetScriptState(), - ScriptValue::CreateNull(scope.GetScriptState()), + ScriptValue::CreateNull(scope.GetIsolate()), ASSERT_NO_EXCEPTION) .value_or(true)); EXPECT_FALSE(ReadableStreamOperations::IsReadableStreamDefaultReader(
diff --git a/third_party/blink/renderer/core/streams/transferable_streams_test.cc b/third_party/blink/renderer/core/streams/transferable_streams_test.cc index 3811b05..e8f7de5 100644 --- a/third_party/blink/renderer/core/streams/transferable_streams_test.cc +++ b/third_party/blink/renderer/core/streams/transferable_streams_test.cc
@@ -49,7 +49,7 @@ .V8Value() .As<v8::Object>()); - writer->write(script_state, ScriptValue::CreateNull(script_state)); + writer->write(script_state, ScriptValue::CreateNull(scope.GetIsolate())); class ExpectNullResponse : public ScriptFunction { public:
diff --git a/third_party/blink/renderer/core/streams/writable_stream_test.cc b/third_party/blink/renderer/core/streams/writable_stream_test.cc index e87946d1..109a4de 100644 --- a/third_party/blink/renderer/core/streams/writable_stream_test.cc +++ b/third_party/blink/renderer/core/streams/writable_stream_test.cc
@@ -52,7 +52,7 @@ EXPECT_EQ(stream->IsLocked(script_state, ASSERT_NO_EXCEPTION), base::make_optional(false)); - ScriptValue writer = stream->getWriter(script_state, ASSERT_NO_EXCEPTION); + stream->getWriter(script_state, ASSERT_NO_EXCEPTION); EXPECT_TRUE(stream->locked(script_state, ASSERT_NO_EXCEPTION)); EXPECT_EQ(stream->IsLocked(script_state, ASSERT_NO_EXCEPTION),
diff --git a/third_party/blink/renderer/core/streams/writable_stream_wrapper.cc b/third_party/blink/renderer/core/streams/writable_stream_wrapper.cc index 6e6ffcd..8ed9eff1 100644 --- a/third_party/blink/renderer/core/streams/writable_stream_wrapper.cc +++ b/third_party/blink/renderer/core/streams/writable_stream_wrapper.cc
@@ -233,8 +233,8 @@ DCHECK(!port_v8.IsEmpty()); v8::Local<v8::Value> args[] = {port_v8}; ScriptValue internal_stream( - script_state, V8ScriptRunner::CallExtra( - script_state, "WritableStreamDeserialize", args)); + isolate, V8ScriptRunner::CallExtra(script_state, + "WritableStreamDeserialize", args)); if (block.HasCaught()) { exception_state.RethrowV8Exception(block.Exception()); return nullptr;
diff --git a/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc b/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc index bcf78ac5..3f82428 100644 --- a/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc +++ b/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc
@@ -1261,7 +1261,7 @@ DispatchEvent(*Event::Create(event_type)); } -bool SVGSMILElement::HasValidTarget() { +bool SVGSMILElement::HasValidTarget() const { return targetElement() && targetElement()->InActiveDocument(); }
diff --git a/third_party/blink/renderer/core/svg/animation/svg_smil_element.h b/third_party/blink/renderer/core/svg/animation/svg_smil_element.h index a7bd8c3..fd11d50 100644 --- a/third_party/blink/renderer/core/svg/animation/svg_smil_element.h +++ b/third_party/blink/renderer/core/svg/animation/svg_smil_element.h
@@ -55,7 +55,7 @@ InsertionNotificationRequest InsertedInto(ContainerNode&) override; void RemovedFrom(ContainerNode&) override; - virtual bool HasValidTarget(); + virtual bool HasValidTarget() const; virtual void AnimationAttributeChanged() = 0; SMILTimeContainer* TimeContainer() const { return time_container_.Get(); } @@ -115,7 +115,7 @@ // Returns true if this animation "sets" the // value of the animation. Thus all previous // animations are rendered useless. - virtual bool OverwritesUnderlyingAnimationValue() = 0; + virtual bool OverwritesUnderlyingAnimationValue() const = 0; bool AnimatedTypeIsLocked() const { return animated_property_locked_; } void LockAnimatedType() {
diff --git a/third_party/blink/renderer/core/svg/svg_animate_element.cc b/third_party/blink/renderer/core/svg/svg_animate_element.cc index 72a2abc9..c4c8633 100644 --- a/third_party/blink/renderer/core/svg/svg_animate_element.cc +++ b/third_party/blink/renderer/core/svg/svg_animate_element.cc
@@ -203,19 +203,23 @@ css_property_id_ = CSSPropertyID::kInvalid; } -AnimatedPropertyType SVGAnimateElement::GetAnimatedPropertyType() { - if (!targetElement()) - return kAnimatedUnknown; - ResolveTargetProperty(); - return type_; +void SVGAnimateElement::UpdateTargetProperty() { + if (SVGElement* target = targetElement()) + ResolveTargetProperty(); + else + ClearTargetProperty(); } -bool SVGAnimateElement::HasValidTarget() { +AnimatedPropertyType SVGAnimateElement::GetAnimatedPropertyType() const { + // TODO(fs): Should be possible to DCHECK targetElement() here instead. + return !targetElement() ? kAnimatedUnknown : type_; +} + +bool SVGAnimateElement::HasValidTarget() const { if (!SVGAnimationElement::HasValidTarget()) return false; if (AttributeName() == AnyQName()) return false; - ResolveTargetProperty(); if (type_ == kAnimatedUnknown) return false; // Always animate CSS properties using the ApplyCSSAnimation code path, @@ -227,8 +231,7 @@ } bool SVGAnimateElement::ShouldApplyAnimation( - const SVGElement& target_element, - const QualifiedName& attribute_name) { + const SVGElement& target_element) const { return target_element.parentNode() && HasValidTarget(); } @@ -416,24 +419,20 @@ } void SVGAnimateElement::ResetAnimatedType() { - ResolveTargetProperty(); - SVGElement* target_element = targetElement(); - const QualifiedName& attribute_name = AttributeName(); - - if (!ShouldApplyAnimation(*target_element, attribute_name)) + if (!ShouldApplyAnimation(*target_element)) return; if (IsAnimatingSVGDom()) { // SVG DOM animVal animation code-path. animated_value_ = target_property_->CreateAnimatedValue(); DCHECK_EQ(animated_value_->GetType(), type_); - target_element->SetAnimatedAttribute(attribute_name, animated_value_); + target_element->SetAnimatedAttribute(AttributeName(), animated_value_); return; } DCHECK(IsAnimatingCSSProperty()); // Presentation attributes which has an SVG DOM representation should use the // "SVG DOM" code-path (above.) - DCHECK(SVGElement::IsAnimatableCSSProperty(attribute_name)); + DCHECK(SVGElement::IsAnimatableCSSProperty(AttributeName())); // CSS properties animation code-path. String base_value = ComputeCSSPropertyValue(target_element, css_property_id_); @@ -456,7 +455,7 @@ return; } - bool should_apply = ShouldApplyAnimation(*target_element, AttributeName()); + bool should_apply = ShouldApplyAnimation(*target_element); if (IsAnimatingCSSProperty()) { // CSS properties animation code-path. if (should_apply) { @@ -477,7 +476,6 @@ } animated_value_.Clear(); - ClearTargetProperty(); } void SVGAnimateElement::ApplyResultsToTarget() { @@ -489,7 +487,7 @@ return; SVGElement* target_element = targetElement(); - if (!ShouldApplyAnimation(*target_element, AttributeName())) + if (!ShouldApplyAnimation(*target_element)) return; // We do update the style and the animation property independent of each @@ -520,7 +518,7 @@ } } -bool SVGAnimateElement::AnimatedPropertyTypeSupportsAddition() { +bool SVGAnimateElement::AnimatedPropertyTypeSupportsAddition() const { // http://www.w3.org/TR/SVG/animate.html#AnimationAttributesAndProperties. switch (GetAnimatedPropertyType()) { case kAnimatedBoolean: @@ -534,7 +532,7 @@ } } -bool SVGAnimateElement::IsAdditive() { +bool SVGAnimateElement::IsAdditive() const { if (GetAnimationMode() == kByAnimation || GetAnimationMode() == kFromByAnimation) { if (!AnimatedPropertyTypeSupportsAddition()) @@ -561,8 +559,11 @@ } void SVGAnimateElement::DidChangeAnimationTarget() { + // Call this before calling the super-class, because it will check + // HasValidTarget() which depends on the animation type being resolved. + UpdateTargetProperty(); SVGAnimationElement::DidChangeAnimationTarget(); - ResetAnimatedPropertyType(); + ResetCachedAnimationState(); } void SVGAnimateElement::SetAttributeName(const QualifiedName& attribute_name) { @@ -587,13 +588,12 @@ DidChangeAnimationTarget(); } -void SVGAnimateElement::ResetAnimatedPropertyType() { +void SVGAnimateElement::ResetCachedAnimationState() { DCHECK(!animated_value_); InvalidatedValuesCache(); from_property_.Clear(); to_property_.Clear(); to_at_end_of_duration_property_.Clear(); - ClearTargetProperty(); } void SVGAnimateElement::Trace(blink::Visitor* visitor) {
diff --git a/third_party/blink/renderer/core/svg/svg_animate_element.h b/third_party/blink/renderer/core/svg/svg_animate_element.h index 094435ae..5bd334bb 100644 --- a/third_party/blink/renderer/core/svg/svg_animate_element.h +++ b/third_party/blink/renderer/core/svg/svg_animate_element.h
@@ -49,11 +49,11 @@ bool IsSVGAnimationAttributeSettingJavaScriptURL( const Attribute&) const override; - AnimatedPropertyType GetAnimatedPropertyType(); - bool AnimatedPropertyTypeSupportsAddition(); + AnimatedPropertyType GetAnimatedPropertyType() const; + bool AnimatedPropertyTypeSupportsAddition() const; protected: - bool HasValidTarget() override; + bool HasValidTarget() const override; void WillChangeAnimationTarget() final; void DidChangeAnimationTarget() final; @@ -73,7 +73,7 @@ void ApplyResultsToTarget() final; float CalculateDistance(const String& from_string, const String& to_string) final; - bool IsAdditive() final; + bool IsAdditive() const final; void ParseAttribute(const AttributeModificationParams&) override; @@ -90,10 +90,9 @@ stringsShouldNotSupportAddition); private: - void ResetAnimatedPropertyType(); + void ResetCachedAnimationState(); - bool ShouldApplyAnimation(const SVGElement& target_element, - const QualifiedName& attribute_name); + bool ShouldApplyAnimation(const SVGElement& target_element) const; void SetAttributeType(const AtomicString&); @@ -102,6 +101,7 @@ virtual void ResolveTargetProperty(); void ClearTargetProperty(); + void UpdateTargetProperty(); virtual SVGPropertyBase* CreatePropertyForAnimation(const String&) const; SVGPropertyBase* CreatePropertyForAttributeAnimation(const String&) const;
diff --git a/third_party/blink/renderer/core/svg/svg_animate_motion_element.cc b/third_party/blink/renderer/core/svg/svg_animate_motion_element.cc index c0c87d9..d2815ff 100644 --- a/third_party/blink/renderer/core/svg/svg_animate_motion_element.cc +++ b/third_party/blink/renderer/core/svg/svg_animate_motion_element.cc
@@ -64,7 +64,7 @@ SVGAnimateMotionElement::~SVGAnimateMotionElement() = default; -bool SVGAnimateMotionElement::HasValidTarget() { +bool SVGAnimateMotionElement::HasValidTarget() const { return SVGAnimationElement::HasValidTarget() && TargetCanHaveMotionTransform(*targetElement()); }
diff --git a/third_party/blink/renderer/core/svg/svg_animate_motion_element.h b/third_party/blink/renderer/core/svg/svg_animate_motion_element.h index 2b0eba2..6ccda14 100644 --- a/third_party/blink/renderer/core/svg/svg_animate_motion_element.h +++ b/third_party/blink/renderer/core/svg/svg_animate_motion_element.h
@@ -36,7 +36,7 @@ void UpdateAnimationPath(); private: - bool HasValidTarget() override; + bool HasValidTarget() const override; void ParseAttribute(const AttributeModificationParams&) override;
diff --git a/third_party/blink/renderer/core/svg/svg_animate_transform_element.cc b/third_party/blink/renderer/core/svg/svg_animate_transform_element.cc index c7a94f3..e1a8942 100644 --- a/third_party/blink/renderer/core/svg/svg_animate_transform_element.cc +++ b/third_party/blink/renderer/core/svg/svg_animate_transform_element.cc
@@ -33,7 +33,7 @@ : SVGAnimateElement(svg_names::kAnimateTransformTag, document), transform_type_(SVGTransformType::kUnknown) {} -bool SVGAnimateTransformElement::HasValidTarget() { +bool SVGAnimateTransformElement::HasValidTarget() const { if (!SVGAnimateElement::HasValidTarget()) return false; if (GetAttributeType() == kAttributeTypeCSS)
diff --git a/third_party/blink/renderer/core/svg/svg_animate_transform_element.h b/third_party/blink/renderer/core/svg/svg_animate_transform_element.h index 102b4c3f..8260fab 100644 --- a/third_party/blink/renderer/core/svg/svg_animate_transform_element.h +++ b/third_party/blink/renderer/core/svg/svg_animate_transform_element.h
@@ -35,7 +35,7 @@ explicit SVGAnimateTransformElement(Document&); private: - bool HasValidTarget() override; + bool HasValidTarget() const override; void ParseAttribute(const AttributeModificationParams&) override;
diff --git a/third_party/blink/renderer/core/svg/svg_animation_element.cc b/third_party/blink/renderer/core/svg/svg_animation_element.cc index 5e80887..17210de 100644 --- a/third_party/blink/renderer/core/svg/svg_animation_element.cc +++ b/third_party/blink/renderer/core/svg/svg_animation_element.cc
@@ -322,7 +322,7 @@ return FastGetAttribute(svg_names::kFromAttr); } -bool SVGAnimationElement::IsAdditive() { +bool SVGAnimationElement::IsAdditive() const { DEFINE_STATIC_LOCAL(const AtomicString, sum, ("sum")); const AtomicString& value = FastGetAttribute(svg_names::kAdditiveAttr); return value == sum || GetAnimationMode() == kByAnimation; @@ -633,7 +633,7 @@ CalculateAnimatedValue(effective_percent, repeat_count, result_element); } -bool SVGAnimationElement::OverwritesUnderlyingAnimationValue() { +bool SVGAnimationElement::OverwritesUnderlyingAnimationValue() const { return !IsAdditive() && !IsAccumulated() && GetAnimationMode() != kToAnimation && GetAnimationMode() != kByAnimation &&
diff --git a/third_party/blink/renderer/core/svg/svg_animation_element.h b/third_party/blink/renderer/core/svg/svg_animation_element.h index 3df1f11..92721a9 100644 --- a/third_party/blink/renderer/core/svg/svg_animation_element.h +++ b/third_party/blink/renderer/core/svg/svg_animation_element.h
@@ -69,12 +69,12 @@ DEFINE_ATTRIBUTE_EVENT_LISTENER(end, kEndEvent) DEFINE_ATTRIBUTE_EVENT_LISTENER(repeat, kRepeatEvent) - virtual bool IsAdditive(); + virtual bool IsAdditive() const; bool IsAccumulated() const; AnimationMode GetAnimationMode() const { return animation_mode_; } CalcMode GetCalcMode() const { return calc_mode_; } - bool OverwritesUnderlyingAnimationValue() override; + bool OverwritesUnderlyingAnimationValue() const override; template <typename AnimatedType> void AnimateDiscreteType(float percentage,
diff --git a/third_party/blink/renderer/core/svg/svg_discard_element.h b/third_party/blink/renderer/core/svg/svg_discard_element.h index 8b7b0263..ade098b 100644 --- a/third_party/blink/renderer/core/svg/svg_discard_element.h +++ b/third_party/blink/renderer/core/svg/svg_discard_element.h
@@ -49,7 +49,7 @@ void ApplyResultsToTarget() override {} void AnimationAttributeChanged() override {} - bool OverwritesUnderlyingAnimationValue() override { return false; } + bool OverwritesUnderlyingAnimationValue() const override { return false; } void StartedActiveInterval() override {} void UpdateAnimation(float percent,
diff --git a/third_party/blink/renderer/core/timing/performance.cc b/third_party/blink/renderer/core/timing/performance.cc index dc44422..e5571db 100644 --- a/third_party/blink/renderer/core/timing/performance.cc +++ b/third_party/blink/renderer/core/timing/performance.cc
@@ -755,7 +755,7 @@ /* duration = */ base::nullopt, end_mark ? StringOrDouble::FromString(*end_mark) : NativeValueTraits<StringOrDouble>::NullValue(), - ScriptValue::CreateNull(script_state), exception_state); + ScriptValue::CreateNull(script_state->GetIsolate()), exception_state); } // For consistency with UserTimingL2: the L2 API took |start| as a string, // so any object passed in became a string '[object, object]', null became @@ -772,7 +772,8 @@ /* duration = */ base::nullopt, end_mark ? StringOrDouble::FromString(*end_mark) : NativeValueTraits<StringOrDouble>::NullValue(), - ScriptValue::CreateNull(script_state), exception_state); + ScriptValue::CreateNull(script_state->GetIsolate()), + exception_state); // Return nullptr to distinguish from L3. return nullptr; }
diff --git a/third_party/blink/renderer/core/timing/performance_user_timing.cc b/third_party/blink/renderer/core/timing/performance_user_timing.cc index ddabb64..c8fb44c 100644 --- a/third_party/blink/renderer/core/timing/performance_user_timing.cc +++ b/third_party/blink/renderer/core/timing/performance_user_timing.cc
@@ -115,7 +115,7 @@ start = performance_->now(); } - ScriptValue detail = ScriptValue::CreateNull(script_state); + ScriptValue detail = ScriptValue::CreateNull(script_state->GetIsolate()); if (RuntimeEnabledFeatures::CustomUserTimingEnabled() && mark_options) detail = mark_options->detail();
diff --git a/third_party/blink/renderer/devtools/front_end/coverage/CoverageDecorationManager.js b/third_party/blink/renderer/devtools/front_end/coverage/CoverageDecorationManager.js index 44d43c8..9fd998f 100644 --- a/third_party/blink/renderer/devtools/front_end/coverage/CoverageDecorationManager.js +++ b/third_party/blink/renderer/devtools/front_end/coverage/CoverageDecorationManager.js
@@ -201,6 +201,11 @@ * @implements {SourceFrame.LineDecorator} */ Coverage.CoverageView.LineDecorator = class { + constructor() { + /** @type {!WeakMap<!TextEditor.CodeMirrorTextEditor, function(!Common.Event)>} */ + this._listeners = new WeakMap(); + } + /** * @override * @param {!Workspace.UISourceCode} uiSourceCode @@ -209,31 +214,78 @@ decorate(uiSourceCode, textEditor) { const decorations = uiSourceCode.decorationsForType(Coverage.CoverageDecorationManager._decoratorType); if (!decorations || !decorations.size) { - textEditor.uninstallGutter(Coverage.CoverageView.LineDecorator._gutterType); + this._uninstallGutter(textEditor); return; } const decorationManager = /** @type {!Coverage.CoverageDecorationManager} */ (decorations.values().next().value.data()); decorationManager.usageByLine(uiSourceCode).then(lineUsage => { - textEditor.operation(() => this._innerDecorate(textEditor, lineUsage)); + textEditor.operation(() => this._innerDecorate(uiSourceCode, textEditor, lineUsage)); }); } /** + * @param {!Workspace.UISourceCode} uiSourceCode * @param {!TextEditor.CodeMirrorTextEditor} textEditor * @param {!Array<boolean>} lineUsage */ - _innerDecorate(textEditor, lineUsage) { + _innerDecorate(uiSourceCode, textEditor, lineUsage) { const gutterType = Coverage.CoverageView.LineDecorator._gutterType; - textEditor.uninstallGutter(gutterType); + this._uninstallGutter(textEditor); if (lineUsage.length) - textEditor.installGutter(gutterType, false); + this._installGutter(textEditor, uiSourceCode.url()); for (let line = 0; line < lineUsage.length; ++line) { // Do not decorate the line if we don't have data. if (typeof lineUsage[line] !== 'boolean') continue; const className = lineUsage[line] ? 'text-editor-coverage-used-marker' : 'text-editor-coverage-unused-marker'; - textEditor.setGutterDecoration(line, gutterType, createElementWithClass('div', className)); + const gutterElement = createElementWithClass('div', className); + textEditor.setGutterDecoration(line, gutterType, gutterElement); + } + } + + /** + * @param {string} url - the url of the file this click handler will select in the coverage drawer + * @return {function(!Common.Event)} + */ + makeGutterClickHandler(url) { + function handleGutterClick(event) { + const eventData = /** @type {!SourceFrame.SourcesTextEditor.GutterClickEventData} */ (event.data); + if (eventData.gutterType !== Coverage.CoverageView.LineDecorator._gutterType) + return; + const coverageViewId = 'coverage'; + UI.viewManager.showView(coverageViewId).then(() => UI.viewManager.view(coverageViewId).widget()).then(widget => { + const matchFormattedSuffix = url.match(/(.*):formatted$/); + const urlWithoutFormattedSuffix = (matchFormattedSuffix && matchFormattedSuffix[1]) || url; + widget.selectCoverageItemByUrl(urlWithoutFormattedSuffix); + }); + } + return handleGutterClick; + } + + /** + * @param {!TextEditor.CodeMirrorTextEditor} textEditor - the text editor to install the gutter on + * @param {string} url - the url of the file in the text editor + */ + _installGutter(textEditor, url) { + let listener = this._listeners.get(textEditor); + if (!listener) { + listener = this.makeGutterClickHandler(url); + this._listeners.set(textEditor, listener); + } + textEditor.installGutter(Coverage.CoverageView.LineDecorator._gutterType, false); + textEditor.addEventListener(SourceFrame.SourcesTextEditor.Events.GutterClick, listener, this); + } + + /** + * @param {!TextEditor.CodeMirrorTextEditor} textEditor - the text editor to uninstall the gutter from + */ + _uninstallGutter(textEditor) { + textEditor.uninstallGutter(Coverage.CoverageView.LineDecorator._gutterType); + const listener = this._listeners.get(textEditor); + if (listener) { + textEditor.removeEventListener(SourceFrame.SourcesTextEditor.Events.GutterClick, listener, this); + this._listeners.delete(textEditor); } } };
diff --git a/third_party/blink/renderer/devtools/front_end/coverage/CoverageListView.js b/third_party/blink/renderer/devtools/front_end/coverage/CoverageListView.js index c3ed61c..a2b0231 100644 --- a/third_party/blink/renderer/devtools/front_end/coverage/CoverageListView.js +++ b/third_party/blink/renderer/devtools/front_end/coverage/CoverageListView.js
@@ -99,6 +99,15 @@ this._sortingChanged(); } + selectByUrl(url) { + for (const [info, node] of this._nodeForCoverageInfo.entries()) { + if (info.url() === url) { + node.revealAndSelect(); + break; + } + } + } + _onOpenedNode() { this._revealSourceForSelectedNode(); }
diff --git a/third_party/blink/renderer/devtools/front_end/coverage/CoverageView.js b/third_party/blink/renderer/devtools/front_end/coverage/CoverageView.js index ba45c2e..d2fd173 100644 --- a/third_party/blink/renderer/devtools/front_end/coverage/CoverageView.js +++ b/third_party/blink/renderer/devtools/front_end/coverage/CoverageView.js
@@ -109,7 +109,14 @@ if (enable) this._startRecording(false); else - this._stopRecording(); + this.stopRecording(); + } + + async ensureRecordingStarted() { + const enable = !this._toggleRecordAction.toggled(); + + if (enable) + await this._startRecording(false); } /** @@ -153,7 +160,7 @@ this._updateViews(event.data); } - async _stopRecording() { + async stopRecording() { if (this._resourceTreeModel) { this._resourceTreeModel.removeEventListener( SDK.ResourceTreeModel.Events.MainFrameNavigated, this._onMainFrameNavigated, this); @@ -232,6 +239,10 @@ return; this._model.exportReport(fos); } + + selectCoverageItemByUrl(url) { + this._listView.selectByUrl(url); + } }; Coverage.CoverageView._extensionBindingsURLPrefix = 'extensions::';
diff --git a/third_party/blink/renderer/devtools/front_end/coverage/coverage_strings.grdp b/third_party/blink/renderer/devtools/front_end/coverage/coverage_strings.grdp index eee29fb..94f74f0 100644 --- a/third_party/blink/renderer/devtools/front_end/coverage/coverage_strings.grdp +++ b/third_party/blink/renderer/devtools/front_end/coverage/coverage_strings.grdp
@@ -38,9 +38,6 @@ <ph name="NUMBER_BYTESTOSTRING_USED_">$1s<ex>1.5 MB</ex></ph> of <ph name="NUMBER_BYTESTOSTRING_TOTAL_">$2s<ex>2.1 MB</ex></ph> (<ph name="PERCENTUSED">$3s<ex>71%</ex></ph>%) used so far. <ph name="NUMBER_BYTESTOSTRING_UNUSED_">$4s<ex>29%</ex></ph> unused. </message> - <message name="IDS_DEVTOOLS_9841bdc50c4226cb6ec5db76494249e6" desc="Title of the 'Coverage' tool in the bottom drawer"> - Coverage - </message> <message name="IDS_DEVTOOLS_bca27ccb808f436cd1ce828dd47604b7" desc="Title of an action in the coverage tool to start with reload"> Start instrumenting coverage and reload page </message>
diff --git a/third_party/blink/renderer/devtools/front_end/coverage_test_runner/CoverageTestRunner.js b/third_party/blink/renderer/devtools/front_end/coverage_test_runner/CoverageTestRunner.js index 1d13d37..8724d4a 100644 --- a/third_party/blink/renderer/devtools/front_end/coverage_test_runner/CoverageTestRunner.js +++ b/third_party/blink/renderer/devtools/front_end/coverage_test_runner/CoverageTestRunner.js
@@ -18,7 +18,7 @@ */ CoverageTestRunner.stopCoverage = function() { const coverageView = self.runtime.sharedInstance(Coverage.CoverageView); - return coverageView._stopRecording(); + return coverageView.stopRecording(); }; /**
diff --git a/third_party/blink/renderer/devtools/front_end/langpacks/shared_strings.grdp b/third_party/blink/renderer/devtools/front_end/langpacks/shared_strings.grdp index 2314bfc..f8b16f8 100644 --- a/third_party/blink/renderer/devtools/front_end/langpacks/shared_strings.grdp +++ b/third_party/blink/renderer/devtools/front_end/langpacks/shared_strings.grdp
@@ -334,6 +334,9 @@ <message name="IDS_DEVTOOLS_96e9bc575b5d3ed541113a249da8bd24" desc="Text to take screenshots"> Capture screenshots </message> + <message name="IDS_DEVTOOLS_9841bdc50c4226cb6ec5db76494249e6" desc="Title of the 'Coverage' tool in the bottom drawer"> + Coverage + </message> <message name="IDS_DEVTOOLS_997a8c473db4f81c5fb3d5900030d44d" desc="Text that shows there is no recording"> (no recordings) </message>
diff --git a/third_party/blink/renderer/devtools/front_end/main/Main.js b/third_party/blink/renderer/devtools/front_end/main/Main.js index 0c17d6a..787c31a 100644 --- a/third_party/blink/renderer/devtools/front_end/main/Main.js +++ b/third_party/blink/renderer/devtools/front_end/main/Main.js
@@ -121,6 +121,7 @@ Runtime.experiments.register('liveHeapProfile', 'Live heap profile', true); Runtime.experiments.register('nativeHeapProfiler', 'Native memory sampling heap profiler', true); Runtime.experiments.register('protocolMonitor', 'Protocol Monitor'); + Runtime.experiments.register('recordCoverageWithPerformanceTracing', 'Record coverage while performance tracing'); Runtime.experiments.register('samplingHeapProfilerTimeline', 'Sampling heap profiler timeline', true); Runtime.experiments.register('sourceDiff', 'Source diff'); Runtime.experiments.register('splitInDrawer', 'Split in drawer', true);
diff --git a/third_party/blink/renderer/devtools/front_end/source_frame/SourcesTextEditor.js b/third_party/blink/renderer/devtools/front_end/source_frame/SourcesTextEditor.js index ec9551e..8b90bcee 100644 --- a/third_party/blink/renderer/devtools/front_end/source_frame/SourcesTextEditor.js +++ b/third_party/blink/renderer/devtools/front_end/source_frame/SourcesTextEditor.js
@@ -46,7 +46,7 @@ this._tokenHighlighter = new SourceFrame.SourcesTextEditor.TokenHighlighter(this, this.codeMirror()); /** @type {!Array<string>} */ - this._gutters = ['CodeMirror-linenumbers']; + this._gutters = [SourceFrame.SourcesTextEditor.lineNumbersGutterType]; this.codeMirror().setOption('gutters', this._gutters.slice()); this.codeMirror().setOption('electricChars', false); @@ -323,11 +323,8 @@ return classNames.indexOf(className) !== -1; } - _gutterClick(instance, lineNumber, gutter, event) { - if (gutter !== 'CodeMirror-linenumbers') - return; - this.dispatchEventToListeners( - SourceFrame.SourcesTextEditor.Events.GutterClick, {lineNumber: lineNumber, event: event}); + _gutterClick(instance, lineNumber, gutterType, event) { + this.dispatchEventToListeners(SourceFrame.SourcesTextEditor.Events.GutterClick, {gutterType, lineNumber, event}); } _contextMenu(event) { @@ -634,7 +631,7 @@ } }; -/** @typedef {{lineNumber: number, event: !Event}} */ +/** @typedef {{gutterType: string, lineNumber: number, event: !Event}} */ SourceFrame.SourcesTextEditor.GutterClickEventData; /** @enum {symbol} */ @@ -935,3 +932,4 @@ SourceFrame.SourcesTextEditor.LinesToScanForIndentationGuessing = 1000; SourceFrame.SourcesTextEditor.MaximumNumberOfWhitespacesPerSingleSpan = 16; +SourceFrame.SourcesTextEditor.lineNumbersGutterType = 'CodeMirror-linenumbers';
diff --git a/third_party/blink/renderer/devtools/front_end/sources/DebuggerPlugin.js b/third_party/blink/renderer/devtools/front_end/sources/DebuggerPlugin.js index 0ca3fb8..d3cc9a28 100644 --- a/third_party/blink/renderer/devtools/front_end/sources/DebuggerPlugin.js +++ b/third_party/blink/renderer/devtools/front_end/sources/DebuggerPlugin.js
@@ -1453,6 +1453,8 @@ return; const eventData = /** @type {!SourceFrame.SourcesTextEditor.GutterClickEventData} */ (event.data); + if (eventData.gutterType !== SourceFrame.SourcesTextEditor.lineNumbersGutterType) + return; const editorLineNumber = eventData.lineNumber; const eventObject = eventData.event;
diff --git a/third_party/blink/renderer/devtools/front_end/timeline/TimelineController.js b/third_party/blink/renderer/devtools/front_end/timeline/TimelineController.js index 002dabe..92d4a31 100644 --- a/third_party/blink/renderer/devtools/front_end/timeline/TimelineController.js +++ b/third_party/blink/renderer/devtools/front_end/timeline/TimelineController.js
@@ -373,7 +373,8 @@ * @typedef {!{ * enableJSSampling: (boolean|undefined), * capturePictures: (boolean|undefined), - * captureFilmStrip: (boolean|undefined) + * captureFilmStrip: (boolean|undefined), + * startCoverage: (boolean|undefined) * }} */ Timeline.TimelineController.RecordingOptions;
diff --git a/third_party/blink/renderer/devtools/front_end/timeline/TimelinePanel.js b/third_party/blink/renderer/devtools/front_end/timeline/TimelinePanel.js index 1182538..4311b1f 100644 --- a/third_party/blink/renderer/devtools/front_end/timeline/TimelinePanel.js +++ b/third_party/blink/renderer/devtools/front_end/timeline/TimelinePanel.js
@@ -70,6 +70,13 @@ this._showScreenshotsSetting.setTitle(Common.UIString('Screenshots')); this._showScreenshotsSetting.addChangeListener(this._updateOverviewControls, this); + this._startCoverage = Common.settings.createSetting('timelineStartCoverage', false); + this._startCoverage.setTitle(ls`Coverage`); + + if (!Runtime.experiments.isEnabled('recordCoverageWithPerformanceTracing')) + this._startCoverage.set(false); + + this._showMemorySetting = Common.settings.createSetting('timelineShowMemory', false); this._showMemorySetting.setTitle(Common.UIString('Memory')); this._showMemorySetting.addChangeListener(this._onModeChanged, this); @@ -226,6 +233,12 @@ this._createSettingCheckbox(this._showMemorySetting, Common.UIString('Show memory timeline')); this._panelToolbar.appendToolbarItem(this._showMemoryToolbarCheckbox); + if (Runtime.experiments.isEnabled('recordCoverageWithPerformanceTracing')) { + this._startCoverageCheckbox = + this._createSettingCheckbox(this._startCoverage, ls`Record coverage with performance trace`); + this._panelToolbar.appendToolbarItem(this._startCoverageCheckbox); + } + // GC this._panelToolbar.appendToolbarItem(UI.Toolbar.createActionButtonForId('components.collect-garbage')); @@ -470,17 +483,25 @@ async _startRecording() { console.assert(!this._statusPane, 'Status pane is already opened.'); this._setState(Timeline.TimelinePanel.State.StartPending); - this._showRecordingStarted(); - - const enabledTraceProviders = Extensions.extensionServer.traceProviders().filter( - provider => Timeline.TimelinePanel._settingForTraceProvider(provider).get()); const recordingOptions = { enableJSSampling: !this._disableCaptureJSProfileSetting.get(), capturePictures: this._captureLayersAndPicturesSetting.get(), - captureFilmStrip: this._showScreenshotsSetting.get() + captureFilmStrip: this._showScreenshotsSetting.get(), + startCoverage: this._startCoverage.get() }; + if (recordingOptions.startCoverage) { + await UI.viewManager.showView('coverage') + .then(() => UI.viewManager.view('coverage').widget()) + .then(widget => widget.ensureRecordingStarted()); + } + + this._showRecordingStarted(); + + const enabledTraceProviders = Extensions.extensionServer.traceProviders().filter( + provider => Timeline.TimelinePanel._settingForTraceProvider(provider).get()); + const mainTarget = /** @type {!SDK.Target} */ (SDK.targetManager.mainTarget()); this._controller = new Timeline.TimelineController(mainTarget, this); this._setUIControlsEnabled(false); @@ -746,6 +767,12 @@ this._performanceModel.setTracingModel(tracingModel); this._setModel(this._performanceModel); this._historyManager.addRecording(this._performanceModel); + + if (this._startCoverage.get()) { + UI.viewManager.showView('coverage') + .then(() => UI.viewManager.view('coverage').widget()) + .then(widget => widget.stopRecording()); + } } _showRecordingStarted() {
diff --git a/third_party/blink/renderer/devtools/front_end/timeline/TimelineTreeView.js b/third_party/blink/renderer/devtools/front_end/timeline/TimelineTreeView.js index 2815c593..2b454dd 100644 --- a/third_party/blink/renderer/devtools/front_end/timeline/TimelineTreeView.js +++ b/third_party/blink/renderer/devtools/front_end/timeline/TimelineTreeView.js
@@ -787,8 +787,7 @@ {label: Common.UIString('Group by Subdomain'), value: groupBy.Subdomain}, {label: Common.UIString('Group by URL'), value: groupBy.URL}, ]; - toolbar.appendToolbarItem( - new UI.ToolbarSettingComboBox(options, this._groupBySetting, undefined /* optGroup */, ls`Group by`)); + toolbar.appendToolbarItem(new UI.ToolbarSettingComboBox(options, this._groupBySetting, ls`Group by`)); toolbar.appendSpacer(); toolbar.appendToolbarItem(this._splitWidget.createShowHideSidebarButton(Common.UIString('heaviest stack'))); }
diff --git a/third_party/blink/renderer/devtools/front_end/timeline/timeline_strings.grdp b/third_party/blink/renderer/devtools/front_end/timeline/timeline_strings.grdp index 389883b..9442d983 100644 --- a/third_party/blink/renderer/devtools/front_end/timeline/timeline_strings.grdp +++ b/third_party/blink/renderer/devtools/front_end/timeline/timeline_strings.grdp
@@ -663,6 +663,9 @@ <message name="IDS_DEVTOOLS_aed0e2bd848c2ac9dddb03d8c21c67b6" desc="Text in Timeline UIUtils of the Performance panel"> Touch Cancel </message> + <message name="IDS_DEVTOOLS_af812f467030e02c8bc8a81b4db8e562" desc="Text in Timeline Panel of the Performance panel"> + Record coverage with performance trace + </message> <message name="IDS_DEVTOOLS_b030f7d30297555390c6d2d23af55fa1" desc="Text in Timeline History Manager of the Performance panel"> moments </message>
diff --git a/third_party/blink/renderer/devtools/front_end/ui/Toolbar.js b/third_party/blink/renderer/devtools/front_end/ui/Toolbar.js index 5882bdf..ff51637 100644 --- a/third_party/blink/renderer/devtools/front_end/ui/Toolbar.js +++ b/third_party/blink/renderer/devtools/front_end/ui/Toolbar.js
@@ -766,12 +766,10 @@ * @param {!Common.Setting} setting * @param {string} glyph * @param {string} title - * @param {string=} toggledTitle */ - constructor(setting, glyph, title, toggledTitle) { + constructor(setting, glyph, title) { super(title, glyph); this._defaultTitle = title; - this._toggledTitle = toggledTitle || title; this._setting = setting; this._settingChanged(); this._setting.addChangeListener(this._settingChanged, this); @@ -780,7 +778,7 @@ _settingChanged() { const toggled = this._setting.get(); this.setToggled(toggled); - this.setTitle(toggled ? this._toggledTitle : this._defaultTitle); + this.setTitle(this._defaultTitle); } /** @@ -971,23 +969,15 @@ /** * @param {!Array<!{value: string, label: string}>} options * @param {!Common.Setting} setting - * @param {string=} optGroup * @param {string=} accessibleName */ - constructor(options, setting, optGroup, accessibleName) { + constructor(options, setting, accessibleName) { super(null); - this._setting = setting; this._options = options; + this._setting = setting; this._selectElement.addEventListener('change', this._valueChanged.bind(this), false); if (accessibleName) UI.ARIAUtils.setAccessibleName(this._selectElement, accessibleName); - if (optGroup) { - const optGroupElement = this._selectElement.createChild('optgroup'); - optGroupElement.label = optGroup; - this._optionContainer = optGroupElement; - } else { - this._optionContainer = this._selectElement; - } this.setOptions(options); setting.addChangeListener(this._settingChanged, this); } @@ -997,11 +987,11 @@ */ setOptions(options) { this._options = options; - this._optionContainer.removeChildren(); + this._selectElement.removeChildren(); for (let i = 0; i < options.length; ++i) { const dataOption = options[i]; const option = this.createOption(dataOption.label, dataOption.value); - this._optionContainer.appendChild(option); + this._selectElement.appendChild(option); if (this._setting.get() === dataOption.value) this.setSelectedIndex(i); }
diff --git a/third_party/blink/renderer/devtools/karma.conf.js b/third_party/blink/renderer/devtools/karma.conf.js index ceafc53..acc4d2be 100644 --- a/third_party/blink/renderer/devtools/karma.conf.js +++ b/third_party/blink/renderer/devtools/karma.conf.js
@@ -13,6 +13,9 @@ },{ pattern: 'tests/**/*.ts', type: 'module' + }, { + pattern: 'tests/**/*.js', + type: 'module' }], reporters: ["dots"],
diff --git a/third_party/blink/renderer/devtools/scripts/localization_utils/localization_utils.js b/third_party/blink/renderer/devtools/scripts/localization_utils/localization_utils.js index db48e8d..ee1a0a6 100644 --- a/third_party/blink/renderer/devtools/scripts/localization_utils/localization_utils.js +++ b/third_party/blink/renderer/devtools/scripts/localization_utils/localization_utils.js
@@ -36,7 +36,7 @@ const SRC_PATH = path.resolve(THIRD_PARTY_PATH, '..'); const GRD_PATH = path.resolve(__dirname, '..', '..', 'front_end', 'langpacks', 'devtools_ui_strings.grd'); const SHARED_STRINGS_PATH = path.resolve(__dirname, '..', '..', 'front_end', 'langpacks', 'shared_strings.grdp'); -const REPO_NODE_MODULES_PATH = path.resolve(THIRD_PARTY_PATH, 'node', 'node_modules'); +const REPO_NODE_MODULES_PATH = path.resolve(THIRD_PARTY_PATH, 'devtools-node-modules', 'third_party', 'node_modules'); const escodegen = require(path.resolve(REPO_NODE_MODULES_PATH, 'escodegen')); const esprima = require(path.resolve(REPO_NODE_MODULES_PATH, 'esprima'));
diff --git a/third_party/blink/renderer/devtools/tests/front_end/platform/dom-extension.js b/third_party/blink/renderer/devtools/tests/front_end/platform/dom-extension.js new file mode 100644 index 0000000..30510a7 --- /dev/null +++ b/third_party/blink/renderer/devtools/tests/front_end/platform/dom-extension.js
@@ -0,0 +1,227 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +const { assert } = chai; +import '../../../front_end/dom_extension/DOMExtension.js'; + + +function createSlot(parent, name) { + const slot = parent.createChild('slot'); + if (name) + slot.name = name; + return slot; +} + +function createChild(parent, tagName, name, text = '') { + const child = parent.createChild(tagName, name); + if (name) + child.slot = name; + child.textContent = text; + return child; +} + + +describe('DataGrid', () => { + it('Traverse Node with Children', () => { + let component1 = createElementWithClass('div', 'component1'); + createChild(component1, 'div', 'component1-content', 'text 1'); + createChild(component1, 'div', 'component2-content', 'text 2'); + createChild(component1, 'span', undefined, 'text 3'); + createChild(component1, 'span', 'component1-content', 'text 4'); + + // Now we have: + /* + * <div class="component1"> + * <div class="component1-content" slot="component1-content">text 1</div> + * <div class="component2-content" slot="component2-content">text 2</div> + * <span>text 3</span><span class="component1-content" slot="component1-content">text 4</span> + * </div> + */ + + + let node = component1; + assert.equal(node.nodeValue, null, 'root node value is incorrect'); + assert.equal(node.nodeName, 'DIV', 'root node name is incorrect'); + assert.equal(node.className, 'component1', 'root node class is incorrect'); + + node = node.traverseNextNode(component1); + assert.equal(node.nodeName, 'DIV', 'first child node name is incorrect'); + assert.equal(node.className, 'component1-content', 'first child class is incorrect'); + + node = node.traverseNextNode(component1); + assert.equal(node.nodeValue, "text 1", 'second child node value is incorrect'); + + node = node.traverseNextNode(component1); + assert.equal(node.nodeName, 'DIV', 'second child node name is incorrect'); + assert.equal(node.className, 'component2-content', 'second child class is incorrect'); + + node = node.traverseNextNode(component1); + assert.equal(node.nodeValue, "text 2", 'second child node value is incorrect'); + + node = node.traverseNextNode(component1); + assert.equal(node.nodeName, 'SPAN', 'third child node name is incorrect'); + assert.equal(node.className, '', 'third child class is incorrect'); + + node = node.traverseNextNode(component1); + assert.equal(node.nodeValue, "text 3", 'third child node value is incorrect'); + + node = node.traverseNextNode(component1); + assert.equal(node.nodeName, 'SPAN', 'forth child node name is incorrect'); + assert.equal(node.className, 'component1-content', 'forth child class is incorrect'); + + node = node.traverseNextNode(component1); + assert.equal(node.nodeValue, "text 4", 'forth child node value is incorrect'); + }); + + it('Traverse Node with Shadows', () => { + var component1 = createElementWithClass('div', 'component1'); + var shadow1 = component1.attachShadow({mode: 'open'}); + var shadow1Content = createElementWithClass('div', 'shadow-component1'); + shadow1.appendChild(shadow1Content); + var component2 = shadow1Content.createChild('div', 'component2'); + var shadow2 = component2.attachShadow({mode: 'open'}); + var shadow2Content = createElementWithClass('div', 'shadow-component1'); + shadow2.appendChild(shadow2Content); + var midDiv = createChild(shadow2Content, 'div', 'mid-div'); + createChild(midDiv, 'div', undefined, 'component2-text'); + + // Now we have: + /* + * <div class="component1"></div> + * <div class="shadow-component1"><div class="component2"></div></div> + * <div class="shadow-component1"><div class="mid-div" slot="mid-div"><div>component2-text</div></div></div> + */ + + let node = component1; + assert.equal(node.nodeName, 'DIV', 'root node name is incorrect'); + assert.equal(node.className, 'component1', 'root node class is incorrect'); + + node = node.traverseNextNode(component1); + assert.equal(node.nodeName, '#document-fragment', 'first document fragment node name is incorrect'); + + node = node.traverseNextNode(component1); + assert.equal(node.nodeName, 'DIV', 'first document fragment child node name is incorrect'); + assert.equal(node.className, 'shadow-component1', 'first document fragment child node name is incorrect'); + + node = node.traverseNextNode(component1); + assert.equal(node.nodeName, 'DIV'); + assert.equal(node.className, 'component2'); + + node = node.traverseNextNode(component1); + assert.equal(node.nodeName, '#document-fragment'); + + node = node.traverseNextNode(component1); + assert.equal(node.nodeName, 'DIV'); + assert.equal(node.className, 'shadow-component1'); + + node = node.traverseNextNode(component1); + assert.equal(node.nodeName, 'DIV'); + assert.equal(node.className, 'mid-div'); + + node = node.traverseNextNode(component1); + assert.equal(node.nodeName, 'DIV'); + assert.equal(node.className, ''); + + node = node.traverseNextNode(component1); + assert.equal(node.nodeName, '#text'); + assert.equal(node.nodeValue, 'component2-text'); + }); + + it('Traverse Node with Slots', () => { + var component1 = createElementWithClass('div', 'component1'); + var shadow1 = component1.attachShadow({mode: 'open'}); + var shadow1Content = createElementWithClass('div', 'shadow-component1'); + shadow1.appendChild(shadow1Content); + createSlot(shadow1Content, 'component1-content'); + createSlot(shadow1Content, null); + var component2 = shadow1Content.createChild('div', 'component2'); + var shadow2 = component2.attachShadow({mode: 'open'}); + createSlot(component2, 'component2-content'); + createChild( + component2, 'div', 'component2-content', 'component2 light dom text'); + var shadow2Content = createElementWithClass('div', 'shadow-component1'); + shadow2.appendChild(shadow2Content); + var midDiv = createChild(shadow2Content, 'div', 'mid-div'); + createChild(midDiv, 'div', undefined, 'component2-text'); + createSlot(midDiv, null); + createSlot(midDiv, 'component2-content'); + + // Now we have: + /* + * <div class="component1"></div> + * <div class="shadow-component1"> + * <slot name="component1-content"></slot> + * <slot></slot> + * <div class="component2"> + * <slot name="component2-content"></slot> + * <div class="component2-content" slot="component2-content">component2 light dom text</div> + * </div> + * </div> + * <div class="shadow-component1"> + * <div class="mid-div" slot="mid-div"> + * <div>component2-text</div> + * <slot></slot> + * <slot name="component2-content"></slot> + * </div> + * </div> + */ + + let node = component1; + assert.equal(node.nodeName, 'DIV', 'root node name is incorrect'); + assert.equal(node.className, 'component1', 'root node class is incorrect'); + + node = node.traverseNextNode(component1); + assert.equal(node.nodeName, '#document-fragment', 'first document fragment node name is incorrect'); + + node = node.traverseNextNode(component1); + assert.equal(node.nodeName, 'DIV', 'first document fragment child node name is incorrect'); + assert.equal(node.className, 'shadow-component1', 'first document fragment child node name is incorrect'); + + node = node.traverseNextNode(component1); + assert.equal(node.nodeName, 'SLOT', 'first slot node name is incorrect'); + + node = node.traverseNextNode(component1); + assert.equal(node.nodeName, 'SLOT', 'second slot node name is incorrect'); + + node = node.traverseNextNode(component1); + assert.equal(node.nodeName, 'DIV'); + assert.equal(node.className, 'component2'); + + node = node.traverseNextNode(component1); + assert.equal(node.nodeName, '#document-fragment'); + + node = node.traverseNextNode(component1); + assert.equal(node.nodeName, 'DIV'); + assert.equal(node.className, 'shadow-component1'); + + node = node.traverseNextNode(component1); + assert.equal(node.nodeName, 'DIV'); + assert.equal(node.className, 'mid-div'); + + node = node.traverseNextNode(component1); + assert.equal(node.nodeName, 'DIV'); + assert.equal(node.className, ''); + + node = node.traverseNextNode(component1); + assert.equal(node.nodeValue, 'component2-text'); + assert.equal(node.nodeName, '#text'); + + node = node.traverseNextNode(component1); + assert.equal(node.nodeName, 'SLOT'); + + node = node.traverseNextNode(component1); + assert.equal(node.nodeName, 'SLOT'); + + node = node.traverseNextNode(component1); + assert.equal(node.nodeName, 'SLOT'); + + node = node.traverseNextNode(component1); + assert.equal(node.nodeName, 'DIV'); + assert.equal(node.className, 'component2-content'); + + node = node.traverseNextNode(component1); + assert.equal(node.nodeValue, 'component2 light dom text'); + assert.equal(node.nodeName, '#text'); + }); +}); \ No newline at end of file
diff --git a/third_party/blink/renderer/modules/bluetooth/bluetooth.cc b/third_party/blink/renderer/modules/bluetooth/bluetooth.cc index bfe0afa..44fb098 100644 --- a/third_party/blink/renderer/modules/bluetooth/bluetooth.cc +++ b/third_party/blink/renderer/modules/bluetooth/bluetooth.cc
@@ -10,7 +10,7 @@ #include "mojo/public/cpp/bindings/pending_associated_remote.h" #include "mojo/public/cpp/bindings/receiver_set.h" #include "mojo/public/cpp/bindings/remote.h" -#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom-blink.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" @@ -469,7 +469,7 @@ if (!service_) { // See https://bit.ly/2S0zRAS for task types. auto task_runner = context->GetTaskRunner(TaskType::kMiscPlatformAPI); - context->GetInterfaceProvider()->GetInterface( + context->GetBrowserInterfaceBroker().GetInterface( service_.BindNewPipeAndPassReceiver(task_runner)); } }
diff --git a/third_party/blink/renderer/modules/contacts_picker/contacts_manager.cc b/third_party/blink/renderer/modules/contacts_picker/contacts_manager.cc index 9181ed7..55fcfe49 100644 --- a/third_party/blink/renderer/modules/contacts_picker/contacts_manager.cc +++ b/third_party/blink/renderer/modules/contacts_picker/contacts_manager.cc
@@ -4,7 +4,7 @@ #include "third_party/blink/renderer/modules/contacts_picker/contacts_manager.h" -#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" @@ -72,8 +72,8 @@ ContactsManager::GetContactsManager(ScriptState* script_state) { if (!contacts_manager_) { ExecutionContext::From(script_state) - ->GetInterfaceProvider() - ->GetInterface(contacts_manager_.BindNewPipeAndPassReceiver()); + ->GetBrowserInterfaceBroker() + .GetInterface(contacts_manager_.BindNewPipeAndPassReceiver()); } return contacts_manager_; }
diff --git a/third_party/blink/renderer/modules/content_index/content_index.cc b/third_party/blink/renderer/modules/content_index/content_index.cc index a8b4d6f7..3e0afe73 100644 --- a/third_party/blink/renderer/modules/content_index/content_index.cc +++ b/third_party/blink/renderer/modules/content_index/content_index.cc
@@ -5,7 +5,7 @@ #include "third_party/blink/renderer/modules/content_index/content_index.h" #include "base/optional.h" -#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/platform/web_size.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" @@ -279,8 +279,10 @@ mojom::blink::ContentIndexService* ContentIndex::GetService() { if (!content_index_service_) { - registration_->GetExecutionContext()->GetInterfaceProvider()->GetInterface( - content_index_service_.BindNewPipeAndPassReceiver(task_runner_)); + registration_->GetExecutionContext() + ->GetBrowserInterfaceBroker() + .GetInterface( + content_index_service_.BindNewPipeAndPassReceiver(task_runner_)); } return content_index_service_.get(); }
diff --git a/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc b/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc index e16b3d83..9fd088b 100644 --- a/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc +++ b/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc
@@ -167,15 +167,8 @@ if (asked_to_terminate_) return; asked_to_terminate_ = true; - if (!worker_thread_) { - // The worker thread has not been created yet if the worker is asked to - // terminate during waiting for debugger. - DCHECK_EQ(WebEmbeddedWorkerStartData::kWaitForDebugger, - worker_start_data_.wait_for_debugger_mode); - // This deletes 'this'. - worker_context_client_->WorkerContextFailedToStartOnInitiatorThread(); - return; - } + // StartWorkerThread() must be called before. + DCHECK(worker_thread_); worker_thread_->Terminate(); }
diff --git a/third_party/blink/renderer/modules/hid/hid.cc b/third_party/blink/renderer/modules/hid/hid.cc index 5168514..dd6d595 100644 --- a/third_party/blink/renderer/modules/hid/hid.cc +++ b/third_party/blink/renderer/modules/hid/hid.cc
@@ -4,7 +4,7 @@ #include "third_party/blink/renderer/modules/hid/hid.h" -#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" @@ -227,7 +227,7 @@ auto task_runner = GetExecutionContext()->GetTaskRunner(TaskType::kMiscPlatformAPI); - GetExecutionContext()->GetInterfaceProvider()->GetInterface( + GetExecutionContext()->GetBrowserInterfaceBroker().GetInterface( service_.BindNewPipeAndPassReceiver(task_runner)); service_.set_disconnect_handler( WTF::Bind(&HID::OnServiceConnectionError, WrapWeakPersistent(this)));
diff --git a/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.cc b/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.cc index 56ff8283..e278a249 100644 --- a/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.cc +++ b/third_party/blink/renderer/modules/indexeddb/inspector_indexed_db_agent.cc
@@ -896,7 +896,8 @@ ScriptState::Scope scope(script_state); DummyExceptionStateForTesting exception_state; IDBRequest* idb_request_get_entries_count = idb_object_store->count( - script_state, ScriptValue::CreateNull(script_state), exception_state); + script_state, ScriptValue::CreateNull(script_state->GetIsolate()), + exception_state); DCHECK(!exception_state.HadException()); if (exception_state.HadException()) { ExceptionCode ec = exception_state.Code();
diff --git a/third_party/blink/renderer/modules/mediarecorder/vea_encoder.cc b/third_party/blink/renderer/modules/mediarecorder/vea_encoder.cc index 8da2d01..38d5b42 100644 --- a/third_party/blink/renderer/modules/mediarecorder/vea_encoder.cc +++ b/third_party/blink/renderer/modules/mediarecorder/vea_encoder.cc
@@ -41,6 +41,7 @@ int32_t bits_per_second, media::VideoCodecProfile codec, const gfx::Size& size, + bool use_native_input, scoped_refptr<base::SingleThreadTaskRunner> task_runner) { auto encoder = base::AdoptRef( new VEAEncoder(on_encoded_video_callback, on_error_callback, @@ -48,7 +49,7 @@ PostCrossThreadTask( *encoder->encoding_task_runner_.get(), FROM_HERE, CrossThreadBindOnce(&VEAEncoder::ConfigureEncoderOnEncodingTaskRunner, - encoder, size)); + encoder, size, use_native_input)); return encoder; } @@ -186,8 +187,12 @@ if (input_visible_size_ != frame->visible_rect().size() && video_encoder_) video_encoder_.reset(); - if (!video_encoder_) - ConfigureEncoderOnEncodingTaskRunner(frame->visible_rect().size()); + if (!video_encoder_) { + bool use_native_input = + frame->storage_type() == media::VideoFrame::STORAGE_GPU_MEMORY_BUFFER; + ConfigureEncoderOnEncodingTaskRunner(frame->visible_rect().size(), + use_native_input); + } if (error_notified_) { DVLOG(3) << "An error occurred in VEA encoder"; @@ -214,13 +219,16 @@ // Therefore, a copy is necessary to release the current frame. // Only STORAGE_SHMEM backed frames can be shared with GPU process, therefore // a copy is required for other storage types. + // With STORAGE_GPU_MEMORY_BUFFER we delay the scaling of the frame to the end + // of the encoding pipeline. scoped_refptr<media::VideoFrame> video_frame = frame; bool can_share_frame = (video_frame->storage_type() == media::VideoFrame::STORAGE_SHMEM); - if (!can_share_frame || - vea_requested_input_coded_size_ != frame->coded_size() || - input_visible_size_.width() < kVEAEncoderMinResolutionWidth || - input_visible_size_.height() < kVEAEncoderMinResolutionHeight) { + if (frame->storage_type() != media::VideoFrame::STORAGE_GPU_MEMORY_BUFFER && + (!can_share_frame || + vea_requested_input_coded_size_ != frame->coded_size() || + input_visible_size_.width() < kVEAEncoderMinResolutionWidth || + input_visible_size_.height() < kVEAEncoderMinResolutionHeight)) { // Create SharedMemory backed input buffers as necessary. These SharedMemory // instances will be shared with GPU process. const size_t desired_mapped_size = media::VideoFrame::AllocationSize( @@ -274,7 +282,8 @@ force_next_frame_to_be_keyframe_ = false; } -void VEAEncoder::ConfigureEncoderOnEncodingTaskRunner(const gfx::Size& size) { +void VEAEncoder::ConfigureEncoderOnEncodingTaskRunner(const gfx::Size& size, + bool use_native_input) { DVLOG(3) << __func__; DCHECK(encoding_task_runner_->BelongsToCurrentThread()); DCHECK(gpu_factories_->GetTaskRunner()->BelongsToCurrentThread()); @@ -283,8 +292,20 @@ input_visible_size_ = size; vea_requested_input_coded_size_ = gfx::Size(); video_encoder_ = gpu_factories_->CreateVideoEncodeAccelerator(); + + auto pixel_format = media::VideoPixelFormat::PIXEL_FORMAT_I420; + auto storage_type = + media::VideoEncodeAccelerator::Config::StorageType::kShmem; + if (use_native_input) { + // Currently the VAAPI and V4L2 VEA support only native input mode with NV12 + // DMA-buf buffers. + pixel_format = media::PIXEL_FORMAT_NV12; + storage_type = media::VideoEncodeAccelerator::Config::StorageType::kDmabuf; + } const media::VideoEncodeAccelerator::Config config( - media::PIXEL_FORMAT_I420, input_visible_size_, codec_, bits_per_second_); + pixel_format, input_visible_size_, codec_, bits_per_second_, + base::nullopt, base::nullopt, base::nullopt, storage_type, + media::VideoEncodeAccelerator::Config::ContentType::kCamera); if (!video_encoder_ || !video_encoder_->Initialize(config, this)) NotifyError(media::VideoEncodeAccelerator::kPlatformFailureError); }
diff --git a/third_party/blink/renderer/modules/mediarecorder/vea_encoder.h b/third_party/blink/renderer/modules/mediarecorder/vea_encoder.h index 743ebe0..e7f63b7 100644 --- a/third_party/blink/renderer/modules/mediarecorder/vea_encoder.h +++ b/third_party/blink/renderer/modules/mediarecorder/vea_encoder.h
@@ -35,6 +35,7 @@ int32_t bits_per_second, media::VideoCodecProfile codec, const gfx::Size& size, + bool use_native_input, scoped_refptr<base::SingleThreadTaskRunner> task_runner); // media::VideoEncodeAccelerator::Client implementation. @@ -73,7 +74,8 @@ void EncodeOnEncodingTaskRunner(scoped_refptr<media::VideoFrame> frame, base::TimeTicks capture_timestamp) override; - void ConfigureEncoderOnEncodingTaskRunner(const gfx::Size& size); + void ConfigureEncoderOnEncodingTaskRunner(const gfx::Size& size, + bool use_native_input); void DestroyOnEncodingTaskRunner(base::WaitableEvent* async_waiter = nullptr);
diff --git a/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc b/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc index c84797f9..69e9535 100644 --- a/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc +++ b/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc
@@ -243,7 +243,9 @@ return; } - if (video_frame->HasTextures()) { + if (video_frame->HasTextures() && + video_frame->storage_type() != + media::VideoFrame::STORAGE_GPU_MEMORY_BUFFER) { PostCrossThreadTask( *main_task_runner_.get(), FROM_HERE, CrossThreadBindOnce(&Encoder::RetrieveFrameOnMainThread, @@ -253,28 +255,29 @@ return; } - scoped_refptr<media::VideoFrame> wrapped_frame; - // Drop alpha channel if the encoder does not support it yet. - if (!CanEncodeAlphaChannel() && - video_frame->format() == media::PIXEL_FORMAT_I420A) { - wrapped_frame = media::WrapAsI420VideoFrame(video_frame); - } else { - wrapped_frame = media::VideoFrame::WrapVideoFrame( - *video_frame, video_frame->format(), video_frame->visible_rect(), - video_frame->natural_size()); + scoped_refptr<media::VideoFrame> frame = video_frame; + if (frame->storage_type() != media::VideoFrame::STORAGE_GPU_MEMORY_BUFFER) { + // Drop alpha channel if the encoder does not support it yet. + if (!CanEncodeAlphaChannel() && + video_frame->format() == media::PIXEL_FORMAT_I420A) { + frame = media::WrapAsI420VideoFrame(video_frame); + } else { + frame = media::VideoFrame::WrapVideoFrame( + *video_frame, video_frame->format(), video_frame->visible_rect(), + video_frame->natural_size()); + } + frame->AddDestructionObserver(ConvertToBaseOnceCallback(CrossThreadBindOnce( + [](scoped_refptr<VideoFrame> video_frame) {}, std::move(video_frame)))); } - wrapped_frame->AddDestructionObserver(media::BindToCurrentLoop( + frame->AddDestructionObserver(media::BindToCurrentLoop( WTF::Bind(&VideoTrackRecorder::Counter::DecreaseCount, num_frames_in_encode_->GetWeakPtr()))); - wrapped_frame->AddDestructionObserver(ConvertToBaseOnceCallback( - CrossThreadBindOnce([](scoped_refptr<VideoFrame> video_frame) {}, - std::move(video_frame)))); num_frames_in_encode_->IncreaseCount(); - PostCrossThreadTask(*encoding_task_runner_.get(), FROM_HERE, - CrossThreadBindOnce(&Encoder::EncodeOnEncodingTaskRunner, - WrapRefCounted(this), wrapped_frame, - capture_timestamp)); + PostCrossThreadTask( + *encoding_task_runner_.get(), FROM_HERE, + CrossThreadBindOnce(&Encoder::EncodeOnEncodingTaskRunner, + WrapRefCounted(this), frame, capture_timestamp)); } void VideoTrackRecorder::Encoder::RetrieveFrameOnMainThread( @@ -505,11 +508,14 @@ UMA_HISTOGRAM_BOOLEAN("Media.MediaRecorder.VEAUsed", true); const auto vea_profile = GetCodecEnumerator()->GetFirstSupportedVideoCodecProfile(codec); + bool use_import_mode = + frame->storage_type() == media::VideoFrame::STORAGE_GPU_MEMORY_BUFFER; encoder_ = VEAEncoder::Create( on_encoded_video_callback, media::BindToCurrentLoop(WTF::BindRepeating( &VideoTrackRecorder::OnError, WrapWeakPersistent(this))), - bits_per_second, vea_profile, input_size, main_task_runner_); + bits_per_second, vea_profile, input_size, use_import_mode, + main_task_runner_); } else { UMA_HISTOGRAM_BOOLEAN("Media.MediaRecorder.VEAUsed", false); switch (codec) {
diff --git a/third_party/blink/renderer/modules/nfc/ndef_record.cc b/third_party/blink/renderer/modules/nfc/ndef_record.cc index a4cedf4..4b2f74c 100644 --- a/third_party/blink/renderer/modules/nfc/ndef_record.cc +++ b/third_party/blink/renderer/modules/nfc/ndef_record.cc
@@ -238,7 +238,7 @@ ScriptValue NDEFRecord::toJSON(ScriptState* script_state, ExceptionState& exception_state) const { if (record_type_ != "json" && record_type_ != "opaque") { - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } ScriptState::Scope scope(script_state); @@ -247,7 +247,7 @@ String::FromUTF8WithLatin1Fallback(data_.data(), data_.size()), exception_state); if (exception_state.HadException()) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); return ScriptValue(script_state, json_object); }
diff --git a/third_party/blink/renderer/modules/payments/payment_method_change_event.cc b/third_party/blink/renderer/modules/payments/payment_method_change_event.cc index 1a3b8e6..633b3c7 100644 --- a/third_party/blink/renderer/modules/payments/payment_method_change_event.cc +++ b/third_party/blink/renderer/modules/payments/payment_method_change_event.cc
@@ -28,7 +28,7 @@ const ScriptValue PaymentMethodChangeEvent::methodDetails( ScriptState* script_state) const { if (method_details_.IsEmpty()) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); return ScriptValue(script_state, method_details_.GetAcrossWorld(script_state)); }
diff --git a/third_party/blink/renderer/modules/payments/payment_request_event.cc b/third_party/blink/renderer/modules/payments/payment_request_event.cc index af4854a..d189e77 100644 --- a/third_party/blink/renderer/modules/payments/payment_request_event.cc +++ b/third_party/blink/renderer/modules/payments/payment_request_event.cc
@@ -115,7 +115,7 @@ const ScriptValue PaymentRequestEvent::paymentOptions( ScriptState* script_state) const { if (!payment_options_) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); return ScriptValue::From(script_state, payment_options_); }
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_test.cc b/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_test.cc index b0c1661..c7a6438 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_test.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_test.cc
@@ -10,6 +10,7 @@ #include "base/memory/ptr_util.h" #include "base/memory/scoped_refptr.h" +#include "base/run_loop.h" #include "base/test/test_simple_task_runner.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/core/dom/events/event.h"
diff --git a/third_party/blink/renderer/modules/service_worker/web_embedded_worker_impl_test.cc b/third_party/blink/renderer/modules/service_worker/web_embedded_worker_impl_test.cc index 90bc453..ed2e17c 100644 --- a/third_party/blink/renderer/modules/service_worker/web_embedded_worker_impl_test.cc +++ b/third_party/blink/renderer/modules/service_worker/web_embedded_worker_impl_test.cc
@@ -30,6 +30,7 @@ #include "third_party/blink/public/web/web_settings.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_error.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread.h" #include "third_party/blink/renderer/platform/scheduler/test/fake_task_runner.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" #include "third_party/blink/renderer/platform/testing/url_test_helpers.h" @@ -124,7 +125,6 @@ MOCK_METHOD2(WorkerReadyForInspectionOnInitiatorThread, void(mojo::ScopedMessagePipeHandle, mojo::ScopedMessagePipeHandle)); - MOCK_METHOD0(WorkerContextFailedToStartOnInitiatorThread, void()); void WorkerContextStarted(WebServiceWorkerContextProxy* proxy, scoped_refptr<base::SequencedTaskRunner>) override {
diff --git a/third_party/blink/renderer/modules/wake_lock/wake_lock_test_utils.cc b/third_party/blink/renderer/modules/wake_lock/wake_lock_test_utils.cc index 35274834..b0099b16 100644 --- a/third_party/blink/renderer/modules/wake_lock/wake_lock_test_utils.cc +++ b/third_party/blink/renderer/modules/wake_lock/wake_lock_test_utils.cc
@@ -315,8 +315,7 @@ if (v8_promise->State() == v8::Promise::kPending) { return g_empty_string; } - ScriptValue promise_result(promise.GetScriptValue().GetScriptState(), - v8_promise->Result()); + ScriptValue promise_result(promise.GetIsolate(), v8_promise->Result()); String value; if (!promise_result.ToString(value)) { return g_empty_string;
diff --git a/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query.cc b/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query.cc index c671a2a..aa45e44 100644 --- a/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query.cc +++ b/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query.cc
@@ -143,7 +143,7 @@ GLenum pname) { WebGLExtensionScopedContext scoped(this); if (scoped.IsLost()) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); if (pname == GL_QUERY_COUNTER_BITS_EXT) { if (target == GL_TIMESTAMP_EXT || target == GL_TIME_ELAPSED_EXT) { @@ -153,22 +153,22 @@ } scoped.Context()->SynthesizeGLError(GL_INVALID_ENUM, "getQuery", "invalid target/pname combination"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } if (target == GL_TIME_ELAPSED_EXT && pname == GL_CURRENT_QUERY) { return current_elapsed_query_ ? WebGLAny(script_state, current_elapsed_query_) - : ScriptValue::CreateNull(script_state); + : ScriptValue::CreateNull(script_state->GetIsolate()); } if (target == GL_TIMESTAMP_EXT && pname == GL_CURRENT_QUERY) { - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } scoped.Context()->SynthesizeGLError(GL_INVALID_ENUM, "getQuery", "invalid target/pname combination"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } ScriptValue EXTDisjointTimerQuery::getQueryObjectEXT(ScriptState* script_state, @@ -176,15 +176,15 @@ GLenum pname) { WebGLExtensionScopedContext scoped(this); if (scoped.IsLost()) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); if (!scoped.Context()->ValidateWebGLObject("getQueryObjectEXT", query)) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); if (current_elapsed_query_ == query) { scoped.Context()->SynthesizeGLError( GL_INVALID_OPERATION, "getQueryObjectEXT", "query is currently active"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } switch (pname) { @@ -202,7 +202,7 @@ break; } - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } void EXTDisjointTimerQuery::Trace(blink::Visitor* visitor) {
diff --git a/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.cc index f6533df..0e4c2a1 100644 --- a/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.cc +++ b/third_party/blink/renderer/modules/webgl/webgl2_compute_rendering_context_base.cc
@@ -75,15 +75,15 @@ GLenum program_interface, GLenum pname) { if (!ValidateWebGLProgramOrShader("getProgramInterfaceParameter", program)) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); if (!ValidateProgramInterface( "getProgramInterfaceParameter", program_interface)) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); if (program_interface == GL_ATOMIC_COUNTER_BUFFER && pname == GL_MAX_NAME_LENGTH) { SynthesizeGLError(GL_INVALID_OPERATION, "getProgramInterfaceParameter", "atomic counter resources are not assigned name strings"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } if (program_interface != GL_ATOMIC_COUNTER_BUFFER && program_interface != GL_SHADER_STORAGE_BLOCK && @@ -92,7 +92,7 @@ SynthesizeGLError( GL_INVALID_OPERATION, "getProgramInterfaceParameter", "invalid parameter name for the specified program interface"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } switch (pname) { @@ -107,7 +107,7 @@ default: SynthesizeGLError(GL_INVALID_ENUM, "getProgramInterfaceParameter", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } @@ -346,7 +346,7 @@ ScriptState* script_state, GLenum pname) { if (isContextLost()) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); switch (pname) { case GL_SHADING_LANGUAGE_VERSION: { return WebGLAny( @@ -397,14 +397,14 @@ GLenum target, GLuint index) { if (isContextLost()) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); switch (target) { case GL_ATOMIC_COUNTER_BUFFER_BINDING: if (index >= bound_indexed_atomic_counter_buffers_.size()) { SynthesizeGLError(GL_INVALID_VALUE, "getIndexedParameter", "index out of range"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } return WebGLAny(script_state, bound_indexed_atomic_counter_buffers_[index].Get()); @@ -412,7 +412,7 @@ if (index >= bound_indexed_shader_storage_buffers_.size()) { SynthesizeGLError(GL_INVALID_VALUE, "getIndexedParameter", "index out of range"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } return WebGLAny(script_state, bound_indexed_shader_storage_buffers_[index].Get()); @@ -620,7 +620,7 @@ } case GL_UNIFORM: { if (location == -1) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); DCHECK_GE(location, 0); WebGLUniformLocation* uniform_location = WebGLUniformLocation::Create(program, location);
diff --git a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc index 309a458..04915cb 100644 --- a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc +++ b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc
@@ -487,12 +487,12 @@ GLenum internalformat, GLenum pname) { if (isContextLost()) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); if (target != GL_RENDERBUFFER) { SynthesizeGLError(GL_INVALID_ENUM, "getInternalformatParameter", "invalid target"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } switch (internalformat) { @@ -549,13 +549,13 @@ SynthesizeGLError(GL_INVALID_ENUM, "getInternalformatParameter", "invalid internalformat when EXT_color_buffer_float " "is not enabled"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } break; default: SynthesizeGLError(GL_INVALID_ENUM, "getInternalformatParameter", "invalid internalformat"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } switch (pname) { @@ -577,7 +577,7 @@ default: SynthesizeGLError(GL_INVALID_ENUM, "getInternalformatParameter", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } @@ -3935,7 +3935,7 @@ GLenum target, GLenum pname) { if (isContextLost()) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); if (ExtensionEnabled(kEXTDisjointTimerQueryWebGL2Name)) { if (pname == GL_QUERY_COUNTER_BITS_EXT) { @@ -3946,23 +3946,23 @@ } SynthesizeGLError(GL_INVALID_ENUM, "getQuery", "invalid target/pname combination"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } if (target == GL_TIME_ELAPSED_EXT && pname == GL_CURRENT_QUERY) { return current_elapsed_query_ ? WebGLAny(script_state, current_elapsed_query_) - : ScriptValue::CreateNull(script_state); + : ScriptValue::CreateNull(script_state->GetIsolate()); } if (target == GL_TIMESTAMP_EXT && pname == GL_CURRENT_QUERY) { - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } if (pname != GL_CURRENT_QUERY) { SynthesizeGLError(GL_INVALID_ENUM, "getQuery", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } switch (target) { @@ -3977,9 +3977,9 @@ current_transform_feedback_primitives_written_query_); default: SynthesizeGLError(GL_INVALID_ENUM, "getQuery", "invalid target"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } ScriptValue WebGL2RenderingContextBase::getQueryParameter( @@ -3987,21 +3987,21 @@ WebGLQuery* query, GLenum pname) { if (!ValidateWebGLObject("getQueryParameter", query)) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); // Query is non-null at this point. if (!query->GetTarget()) { SynthesizeGLError(GL_INVALID_OPERATION, "getQueryParameter", "'query' is not a query object yet, since it has't been " "used by beginQuery"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } if (query == current_boolean_occlusion_query_ || query == current_transform_feedback_primitives_written_query_ || query == current_elapsed_query_) { SynthesizeGLError(GL_INVALID_OPERATION, "getQueryParameter", "query is currently active"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } switch (pname) { @@ -4016,7 +4016,7 @@ default: SynthesizeGLError(GL_INVALID_ENUM, "getQueryParameter", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } @@ -4189,7 +4189,7 @@ WebGLSampler* sampler, GLenum pname) { if (!ValidateWebGLObject("getSamplerParameter", sampler)) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); switch (pname) { case GL_TEXTURE_COMPARE_FUNC: @@ -4213,7 +4213,7 @@ if (!ExtensionEnabled(kEXTTextureFilterAnisotropicName)) { SynthesizeGLError(GL_INVALID_ENUM, "samplerParameter", "EXT_texture_filter_anisotropic not enabled"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } GLfloat value = 0.f; ContextGL()->GetSamplerParameterfv(ObjectOrZero(sampler), pname, &value); @@ -4222,7 +4222,7 @@ default: SynthesizeGLError(GL_INVALID_ENUM, "getSamplerParameter", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } @@ -4314,7 +4314,7 @@ WebGLSync* sync, GLenum pname) { if (!ValidateWebGLObject("getSyncParameter", sync)) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); switch (pname) { case GL_OBJECT_TYPE: @@ -4327,7 +4327,7 @@ default: SynthesizeGLError(GL_INVALID_ENUM, "getSyncParameter", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } @@ -4661,7 +4661,7 @@ GLenum target, GLuint index) { if (isContextLost()) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); switch (target) { case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: { @@ -4670,7 +4670,7 @@ index, &buffer)) { SynthesizeGLError(GL_INVALID_VALUE, "getIndexedParameter", "index out of range"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } return WebGLAny(script_state, buffer); } @@ -4678,7 +4678,7 @@ if (index >= bound_indexed_uniform_buffers_.size()) { SynthesizeGLError(GL_INVALID_VALUE, "getIndexedParameter", "index out of range"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } return WebGLAny(script_state, bound_indexed_uniform_buffers_[index].Get()); @@ -4693,7 +4693,7 @@ default: SynthesizeGLError(GL_INVALID_ENUM, "getIndexedParameter", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } @@ -4718,7 +4718,7 @@ const Vector<GLuint>& uniform_indices, GLenum pname) { if (!ValidateWebGLProgramOrShader("getActiveUniforms", program)) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); enum ReturnType { kEnumType, kUnsignedIntType, kIntType, kBoolType }; @@ -4742,7 +4742,7 @@ default: SynthesizeGLError(GL_INVALID_ENUM, "getActiveUniforms", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } GLint active_uniforms = -1; @@ -4755,7 +4755,7 @@ if (index >= active_uniforms_unsigned) { SynthesizeGLError(GL_INVALID_VALUE, "getActiveUniforms", "uniform index greater than ACTIVE_UNIFORMS"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } @@ -4787,7 +4787,7 @@ } default: NOTREACHED(); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } @@ -4830,11 +4830,11 @@ GLuint uniform_block_index, GLenum pname) { if (!ValidateWebGLProgramOrShader("getActiveUniformBlockParameter", program)) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); if (!ValidateUniformBlockIndex("getActiveUniformBlockParameter", program, uniform_block_index)) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); switch (pname) { case GL_UNIFORM_BLOCK_BINDING: @@ -4869,7 +4869,7 @@ default: SynthesizeGLError(GL_INVALID_ENUM, "getActiveUniformBlockParameter", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } @@ -5033,7 +5033,7 @@ ScriptValue WebGL2RenderingContextBase::getParameter(ScriptState* script_state, GLenum pname) { if (isContextLost()) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); switch (pname) { case GL_SHADING_LANGUAGE_VERSION: { return WebGLAny( @@ -5155,7 +5155,7 @@ if (!transform_feedback_binding_->IsDefaultObject()) { return WebGLAny(script_state, transform_feedback_binding_.Get()); } - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); case GL_TRANSFORM_FEEDBACK_PAUSED: return GetBooleanParameter(script_state, pname); case GL_UNIFORM_BUFFER_BINDING: @@ -5179,7 +5179,7 @@ SynthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, " "EXT_disjoint_timer_query_webgl2 not enabled"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); case GL_GPU_DISJOINT_EXT: if (ExtensionEnabled(kEXTDisjointTimerQueryWebGL2Name)) { return GetBooleanParameter(script_state, GL_GPU_DISJOINT_EXT); @@ -5187,7 +5187,7 @@ SynthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, " "EXT_disjoint_timer_query_webgl2 not enabled"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); default: return WebGLRenderingContextBase::getParameter(script_state, pname); @@ -5574,7 +5574,7 @@ const char kFunctionName[] = "getFramebufferAttachmentParameter"; if (isContextLost() || !ValidateGetFramebufferAttachmentParameterFunc( kFunctionName, target, attachment)) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); WebGLFramebuffer* framebuffer_binding = GetFramebufferBinding(target); DCHECK(!framebuffer_binding || framebuffer_binding->Object()); @@ -5595,7 +5595,7 @@ default: SynthesizeGLError(GL_INVALID_OPERATION, kFunctionName, "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } switch (pname) { @@ -5629,17 +5629,17 @@ return WebGLAny(script_state, 0); SynthesizeGLError(GL_INVALID_ENUM, kFunctionName, "invalid parameter name, OVR_multiview2 not enabled"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR: if (ExtensionEnabled(kOVRMultiview2Name)) return WebGLAny(script_state, 0); SynthesizeGLError(GL_INVALID_ENUM, kFunctionName, "invalid parameter name, OVR_multiview2 not enabled"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); default: SynthesizeGLError(GL_INVALID_ENUM, kFunctionName, "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } @@ -5653,7 +5653,7 @@ SynthesizeGLError( GL_INVALID_OPERATION, kFunctionName, "different objects bound to DEPTH_ATTACHMENT and STENCIL_ATTACHMENT"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } attachment_object = depth_attachment; } else { @@ -5665,11 +5665,11 @@ case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: return WebGLAny(script_state, GL_NONE); case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); default: SynthesizeGLError(GL_INVALID_OPERATION, kFunctionName, "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } DCHECK(attachment_object->IsTexture() || attachment_object->IsRenderbuffer()); @@ -5703,7 +5703,7 @@ SynthesizeGLError( GL_INVALID_OPERATION, kFunctionName, "COMPONENT_TYPE can't be queried for DEPTH_STENCIL_ATTACHMENT"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } FALLTHROUGH; case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING: { @@ -5717,7 +5717,7 @@ if (!ExtensionEnabled(kOVRMultiview2Name)) { SynthesizeGLError(GL_INVALID_ENUM, kFunctionName, "invalid parameter name, OVR_multiview2 not enabled"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } GLint value = 0; ContextGL()->GetFramebufferAttachmentParameteriv(target, attachment, @@ -5728,7 +5728,7 @@ break; } SynthesizeGLError(GL_INVALID_ENUM, kFunctionName, "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } void WebGL2RenderingContextBase::Trace(blink::Visitor* visitor) { @@ -5786,7 +5786,7 @@ GLenum target, GLenum pname) { if (isContextLost() || !ValidateTextureBinding("getTexParameter", target)) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); switch (pname) { case GL_TEXTURE_WRAP_R:
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc index 2acb5bf..2eea4dd 100644 --- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc +++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
@@ -2916,7 +2916,7 @@ GLenum target, GLenum pname) { if (isContextLost() || !ValidateBufferTarget("getBufferParameter", target)) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); switch (pname) { case GL_BUFFER_USAGE: { @@ -2934,7 +2934,7 @@ default: SynthesizeGLError(GL_INVALID_ENUM, "getBufferParameter", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } @@ -3049,18 +3049,18 @@ if (isContextLost() || !ValidateFramebufferFuncParameters("getFramebufferAttachmentParameter", target, attachment)) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); if (!framebuffer_binding_ || !framebuffer_binding_->Object()) { SynthesizeGLError(GL_INVALID_OPERATION, "getFramebufferAttachmentParameter", "no framebuffer bound"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } if (framebuffer_binding_ && framebuffer_binding_->Opaque()) { SynthesizeGLError(GL_INVALID_OPERATION, "getFramebufferAttachmentParameter", "cannot query parameters of an opaque framebuffer"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } WebGLSharedObject* attachment_object = @@ -3072,7 +3072,7 @@ // specifies INVALID_OPERATION. SynthesizeGLError(GL_INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } DCHECK(attachment_object->IsTexture() || attachment_object->IsRenderbuffer()); @@ -3098,11 +3098,11 @@ } SynthesizeGLError(GL_INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name for renderbuffer attachment"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); default: SynthesizeGLError(GL_INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name for texture attachment"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } else { switch (pname) { @@ -3119,11 +3119,11 @@ } SynthesizeGLError(GL_INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name for renderbuffer attachment"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); default: SynthesizeGLError(GL_INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name for renderbuffer attachment"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } } @@ -3131,7 +3131,7 @@ ScriptValue WebGLRenderingContextBase::getParameter(ScriptState* script_state, GLenum pname) { if (isContextLost()) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); const int kIntZero = 0; switch (pname) { case GL_ACTIVE_TEXTURE: @@ -3341,7 +3341,7 @@ SynthesizeGLError( GL_INVALID_ENUM, "getParameter", "invalid parameter name, OES_standard_derivatives not enabled"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); case WebGLDebugRendererInfo::kUnmaskedRendererWebgl: if (ExtensionEnabled(kWebGLDebugRendererInfoName)) return WebGLAny(script_state, @@ -3349,7 +3349,7 @@ SynthesizeGLError( GL_INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_debug_renderer_info not enabled"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); case WebGLDebugRendererInfo::kUnmaskedVendorWebgl: if (ExtensionEnabled(kWebGLDebugRendererInfoName)) return WebGLAny(script_state, @@ -3357,17 +3357,17 @@ SynthesizeGLError( GL_INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_debug_renderer_info not enabled"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); case GL_VERTEX_ARRAY_BINDING_OES: // OES_vertex_array_object if (ExtensionEnabled(kOESVertexArrayObjectName) || IsWebGL2OrHigher()) { if (!bound_vertex_array_object_->IsDefaultObject()) return WebGLAny(script_state, bound_vertex_array_object_.Get()); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } SynthesizeGLError( GL_INVALID_ENUM, "getParameter", "invalid parameter name, OES_vertex_array_object not enabled"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: // EXT_texture_filter_anisotropic if (ExtensionEnabled(kEXTTextureFilterAnisotropicName)) { return GetFloatParameter(script_state, @@ -3376,41 +3376,41 @@ SynthesizeGLError( GL_INVALID_ENUM, "getParameter", "invalid parameter name, EXT_texture_filter_anisotropic not enabled"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); case GL_MAX_COLOR_ATTACHMENTS_EXT: // EXT_draw_buffers BEGIN if (ExtensionEnabled(kWebGLDrawBuffersName) || IsWebGL2OrHigher()) return WebGLAny(script_state, MaxColorAttachments()); SynthesizeGLError( GL_INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_draw_buffers not enabled"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); case GL_MAX_DRAW_BUFFERS_EXT: if (ExtensionEnabled(kWebGLDrawBuffersName) || IsWebGL2OrHigher()) return WebGLAny(script_state, MaxDrawBuffers()); SynthesizeGLError( GL_INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_draw_buffers not enabled"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); case GL_TIMESTAMP_EXT: if (ExtensionEnabled(kEXTDisjointTimerQueryName)) return WebGLAny(script_state, 0); SynthesizeGLError( GL_INVALID_ENUM, "getParameter", "invalid parameter name, EXT_disjoint_timer_query not enabled"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); case GL_GPU_DISJOINT_EXT: if (ExtensionEnabled(kEXTDisjointTimerQueryName)) return GetBooleanParameter(script_state, GL_GPU_DISJOINT_EXT); SynthesizeGLError( GL_INVALID_ENUM, "getParameter", "invalid parameter name, EXT_disjoint_timer_query not enabled"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); case GL_MAX_VIEWS_OVR: if (ExtensionEnabled(kOVRMultiview2Name)) return GetIntParameter(script_state, pname); SynthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, OVR_multiview2 not enabled"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); default: if ((ExtensionEnabled(kWebGLDrawBuffersName) || IsWebGL2OrHigher()) && pname >= GL_DRAW_BUFFER0_EXT && @@ -3424,7 +3424,7 @@ } SynthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } @@ -3433,7 +3433,7 @@ WebGLProgram* program, GLenum pname) { if (!ValidateWebGLProgramOrShader("getProgramParamter", program)) { - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } GLint value = 0; @@ -3449,7 +3449,7 @@ if (!ExtensionEnabled(kKHRParallelShaderCompileName)) { SynthesizeGLError(GL_INVALID_ENUM, "getProgramParameter", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } bool completed; if (checkProgramCompletionQueryAvailable(program, &completed)) { @@ -3461,7 +3461,7 @@ if (!IsWebGL2OrHigher()) { SynthesizeGLError(GL_INVALID_ENUM, "getProgramParameter", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } FALLTHROUGH; case GL_ATTACHED_SHADERS: @@ -3473,7 +3473,7 @@ if (!IsWebGL2OrHigher()) { SynthesizeGLError(GL_INVALID_ENUM, "getProgramParameter", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } ContextGL()->GetProgramiv(ObjectOrZero(program), pname, &value); return WebGLAny(script_state, static_cast<unsigned>(value)); @@ -3486,7 +3486,7 @@ default: SynthesizeGLError(GL_INVALID_ENUM, "getProgramParameter", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } @@ -3502,16 +3502,16 @@ GLenum target, GLenum pname) { if (isContextLost()) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); if (target != GL_RENDERBUFFER) { SynthesizeGLError(GL_INVALID_ENUM, "getRenderbufferParameter", "invalid target"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } if (!renderbuffer_binding_ || !renderbuffer_binding_->Object()) { SynthesizeGLError(GL_INVALID_OPERATION, "getRenderbufferParameter", "no renderbuffer bound"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } GLint value = 0; @@ -3520,7 +3520,7 @@ if (!IsWebGL2OrHigher()) { SynthesizeGLError(GL_INVALID_ENUM, "getRenderbufferParameter", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } FALLTHROUGH; case GL_RENDERBUFFER_WIDTH: @@ -3540,7 +3540,7 @@ default: SynthesizeGLError(GL_INVALID_ENUM, "getRenderbufferParameter", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } @@ -3549,7 +3549,7 @@ WebGLShader* shader, GLenum pname) { if (!ValidateWebGLProgramOrShader("getShaderParameter", shader)) { - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } GLint value = 0; switch (pname) { @@ -3562,7 +3562,7 @@ if (!ExtensionEnabled(kKHRParallelShaderCompileName)) { SynthesizeGLError(GL_INVALID_ENUM, "getShaderParameter", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } ContextGL()->GetShaderiv(ObjectOrZero(shader), pname, &value); return WebGLAny(script_state, static_cast<bool>(value)); @@ -3572,7 +3572,7 @@ default: SynthesizeGLError(GL_INVALID_ENUM, "getShaderParameter", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } @@ -3643,9 +3643,9 @@ GLenum target, GLenum pname) { if (isContextLost()) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); if (!ValidateTextureBinding("getTexParameter", target)) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); switch (pname) { case GL_TEXTURE_MAG_FILTER: case GL_TEXTURE_MIN_FILTER: @@ -3664,11 +3664,11 @@ SynthesizeGLError( GL_INVALID_ENUM, "getTexParameter", "invalid parameter name, EXT_texture_filter_anisotropic not enabled"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); default: SynthesizeGLError(GL_INVALID_ENUM, "getTexParameter", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } @@ -3677,12 +3677,12 @@ WebGLProgram* program, const WebGLUniformLocation* uniform_location) { if (!ValidateWebGLProgramOrShader("getUniform", program)) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); DCHECK(uniform_location); if (uniform_location->Program() != program) { SynthesizeGLError(GL_INVALID_OPERATION, "getUniform", "no uniformlocation or not valid for this program"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } GLint location = uniform_location->Location(); @@ -3691,11 +3691,11 @@ ContextGL()->GetProgramiv(program_id, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_name_length); if (max_name_length < 0) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); if (max_name_length == 0) { SynthesizeGLError(GL_INVALID_VALUE, "getUniform", "no active uniforms exist"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } // FIXME: make this more efficient using WebGLUniformLocation and caching @@ -3713,7 +3713,7 @@ &size, &type, reinterpret_cast<GLchar*>(name_ptr)); if (size < 0) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); String name(name_impl->Substring(0, name_length)); StringBuilder name_builder; // Strip "[0]" from the name if it's an array. @@ -3808,7 +3808,7 @@ SynthesizeGLError( GL_INVALID_VALUE, "getUniform", "unhandled type, WEBGL_video_texture extension not enabled"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } base_type = GL_INT; length = 1; @@ -3818,7 +3818,7 @@ // Can't handle this type SynthesizeGLError(GL_INVALID_VALUE, "getUniform", "unhandled type"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } // handle GLenums for WebGL 2.0 or higher switch (type) { @@ -3893,7 +3893,7 @@ if (context_type_ != Platform::kWebGL2ComputeContextType) { SynthesizeGLError(GL_INVALID_VALUE, "getUniform", "unhandled type"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } base_type = GL_INT; length = 1; @@ -3903,7 +3903,7 @@ // Can't handle this type SynthesizeGLError(GL_INVALID_VALUE, "getUniform", "unhandled type"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } switch (base_type) { @@ -3950,7 +3950,7 @@ // If we get here, something went wrong in our unfortunately complex logic // above SynthesizeGLError(GL_INVALID_VALUE, "getUniform", "unknown error"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } WebGLUniformLocation* WebGLRenderingContextBase::getUniformLocation( @@ -3981,11 +3981,11 @@ GLuint index, GLenum pname) { if (isContextLost()) - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); if (index >= max_vertex_attribs_) { SynthesizeGLError(GL_INVALID_VALUE, "getVertexAttrib", "index out of range"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } if ((ExtensionEnabled(kANGLEInstancedArraysName) || IsWebGL2OrHigher()) && @@ -4039,7 +4039,7 @@ NOTREACHED(); break; } - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } case GL_VERTEX_ATTRIB_ARRAY_INTEGER: if (IsWebGL2OrHigher()) { @@ -4051,7 +4051,7 @@ default: SynthesizeGLError(GL_INVALID_ENUM, "getVertexAttrib", "invalid parameter name"); - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } } @@ -6813,7 +6813,7 @@ if (value == 0) { // This indicates read framebuffer is incomplete and an // INVALID_OPERATION has been generated. - return ScriptValue::CreateNull(script_state); + return ScriptValue::CreateNull(script_state->GetIsolate()); } break; default:
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout.cc b/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout.cc index 93252552..d2065677 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout.cc
@@ -23,7 +23,7 @@ dawn_binding.textureComponentType = AsDawnEnum<DawnTextureComponentType>( webgpu_binding->textureComponentType()); dawn_binding.multisampled = webgpu_binding->multisampled(); - dawn_binding.dynamic = webgpu_binding->dynamic(); + dawn_binding.hasDynamicOffset = webgpu_binding->hasDynamicOffset(); return dawn_binding; }
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout_binding.idl b/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout_binding.idl index df5acb6..c13851c3 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout_binding.idl +++ b/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout_binding.idl
@@ -11,7 +11,7 @@ GPUTextureViewDimension textureDimension = "2d"; GPUTextureComponentType textureComponentType = "float"; boolean multisampled = false; - boolean dynamic = false; + boolean hasDynamicOffset = false; }; enum GPUBindingType {
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc b/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc index 5c5f063..773faf3 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc
@@ -80,4 +80,17 @@ return swapchain_; } +ScriptPromise GPUCanvasContext::getSwapChainPreferredFormat( + ScriptState* script_state, + const GPUDevice* device) { + ScriptPromiseResolver* resolver = + MakeGarbageCollected<ScriptPromiseResolver>(script_state); + ScriptPromise promise = resolver->Promise(); + + // TODO(crbug.com/1007166): Return actual preferred format for the swap chain. + resolver->Resolve("bgra8unorm"); + + return promise; +} + } // namespace blink
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.h b/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.h index 0360222..5e357b5 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.h +++ b/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.h
@@ -62,6 +62,8 @@ // gpu_canvas_context.idl GPUSwapChain* configureSwapChain(const GPUSwapChainDescriptor* descriptor); + ScriptPromise getSwapChainPreferredFormat(ScriptState* script_state, + const GPUDevice* device); private: DISALLOW_COPY_AND_ASSIGN(GPUCanvasContext);
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.idl b/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.idl index 5e4ac97..feb476c 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.idl +++ b/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.idl
@@ -8,4 +8,6 @@ RuntimeEnabled=WebGPU ] interface GPUCanvasContext { GPUSwapChain configureSwapChain(GPUSwapChainDescriptor descriptor); + + [CallWith=ScriptState] Promise<GPUTextureFormat> getSwapChainPreferredFormat(GPUDevice device); };
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc b/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc index b3494aa..0060aaab 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.cc
@@ -82,9 +82,10 @@ dawn_desc.stencilLoadOp = AsDawnEnum<DawnLoadOp>(gpuLoadOp); dawn_desc.clearStencil = 0; - } else if (webgpu_desc->stencilLoadValue().IsLong()) { + } else if (webgpu_desc->stencilLoadValue().IsUnsignedLong()) { dawn_desc.stencilLoadOp = DAWN_LOAD_OP_CLEAR; - dawn_desc.clearStencil = webgpu_desc->stencilLoadValue().GetAsLong(); + dawn_desc.clearStencil = + webgpu_desc->stencilLoadValue().GetAsUnsignedLong(); } else { NOTREACHED();
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_device.cc b/third_party/blink/renderer/modules/webgpu/gpu_device.cc index 87bfcf4..bedd1100 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_device.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_device.cc
@@ -244,10 +244,10 @@ void GPUDevice::OnPopErrorScopeCallback(ScriptPromiseResolver* resolver, DawnErrorType type, const char* message) { - ScriptState* script_state = resolver->GetScriptState(); + v8::Isolate* isolate = resolver->GetScriptState()->GetIsolate(); switch (type) { case DAWN_ERROR_TYPE_NO_ERROR: - resolver->Resolve(ScriptValue::CreateNull(script_state)); + resolver->Resolve(ScriptValue::CreateNull(isolate)); break; case DAWN_ERROR_TYPE_OUT_OF_MEMORY: resolver->Resolve(GPUOutOfMemoryError::Create());
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_pipeline_descriptor_base.idl b/third_party/blink/renderer/modules/webgpu/gpu_pipeline_descriptor_base.idl index 417592f8..4557d05 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_pipeline_descriptor_base.idl +++ b/third_party/blink/renderer/modules/webgpu/gpu_pipeline_descriptor_base.idl
@@ -5,6 +5,5 @@ // https://gpuweb.github.io/gpuweb/ dictionary GPUPipelineDescriptorBase { - DOMString label; required GPUPipelineLayout layout; };
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_render_pass_depth_stencil_attachment_descriptor.idl b/third_party/blink/renderer/modules/webgpu/gpu_render_pass_depth_stencil_attachment_descriptor.idl index 63c9b326..3d32541 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_render_pass_depth_stencil_attachment_descriptor.idl +++ b/third_party/blink/renderer/modules/webgpu/gpu_render_pass_depth_stencil_attachment_descriptor.idl
@@ -10,6 +10,6 @@ required (GPULoadOp or float) depthLoadValue; required GPUStoreOp depthStoreOp; - required (GPULoadOp or long) stencilLoadValue; + required (GPULoadOp or unsigned long) stencilLoadValue; required GPUStoreOp stencilStoreOp; };
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_sampler.cc b/third_party/blink/renderer/modules/webgpu/gpu_sampler.cc index 0b21805..e221ebb 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_sampler.cc +++ b/third_party/blink/renderer/modules/webgpu/gpu_sampler.cc
@@ -29,8 +29,7 @@ AsDawnEnum<DawnFilterMode>(webgpu_desc->mipmapFilter()); dawn_desc.lodMinClamp = webgpu_desc->lodMinClamp(); dawn_desc.lodMaxClamp = webgpu_desc->lodMaxClamp(); - dawn_desc.compare = - AsDawnEnum<DawnCompareFunction>(webgpu_desc->compareFunction()); + dawn_desc.compare = AsDawnEnum<DawnCompareFunction>(webgpu_desc->compare()); return dawn_desc; }
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_sampler_descriptor.idl b/third_party/blink/renderer/modules/webgpu/gpu_sampler_descriptor.idl index 4eb8b2b..c987d631 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_sampler_descriptor.idl +++ b/third_party/blink/renderer/modules/webgpu/gpu_sampler_descriptor.idl
@@ -13,7 +13,7 @@ GPUFilterMode mipmapFilter = "nearest"; float lodMinClamp = 0; float lodMaxClamp = 0xffffffff; - GPUCompareFunction compareFunction = "never"; + GPUCompareFunction compare = "never"; }; enum GPUAddressMode {
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_shader_module_descriptor.idl b/third_party/blink/renderer/modules/webgpu/gpu_shader_module_descriptor.idl index 640d875..af9f707 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_shader_module_descriptor.idl +++ b/third_party/blink/renderer/modules/webgpu/gpu_shader_module_descriptor.idl
@@ -5,7 +5,6 @@ // https://gpuweb.github.io/gpuweb/ dictionary GPUShaderModuleDescriptor { - DOMString label; // TODO(kainino): should be: // [AllowShared, FlexibleArrayBufferView] required ArrayBufferView code; // (or BufferSource?)
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_vertex_attribute_descriptor.idl b/third_party/blink/renderer/modules/webgpu/gpu_vertex_attribute_descriptor.idl index 297b7f9e..bd18f3c5 100644 --- a/third_party/blink/renderer/modules/webgpu/gpu_vertex_attribute_descriptor.idl +++ b/third_party/blink/renderer/modules/webgpu/gpu_vertex_attribute_descriptor.idl
@@ -4,12 +4,10 @@ // https://gpuweb.github.io/gpuweb/ -typedef unsigned long GPUShaderAttributeIndex; - dictionary GPUVertexAttributeDescriptor { unsigned long long offset = 0; required GPUVertexFormat format; - required GPUShaderAttributeIndex shaderLocation; + required unsigned long shaderLocation; }; enum GPUVertexFormat {
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn index f72614d..decd2fd 100644 --- a/third_party/blink/renderer/platform/BUILD.gn +++ b/third_party/blink/renderer/platform/BUILD.gn
@@ -1467,6 +1467,7 @@ "//third_party/ced", "//third_party/emoji-segmenter", "//third_party/icu", + "//third_party/libyuv", "//third_party/webrtc/api:libjingle_logging_api", "//third_party/webrtc/api:packet_socket_factory", "//third_party/webrtc/api/audio_codecs/L16:audio_decoder_L16",
diff --git a/third_party/blink/renderer/platform/exported/web_runtime_features.cc b/third_party/blink/renderer/platform/exported/web_runtime_features.cc index bd433b1..66cbb2e 100644 --- a/third_party/blink/renderer/platform/exported/web_runtime_features.cc +++ b/third_party/blink/renderer/platform/exported/web_runtime_features.cc
@@ -668,10 +668,6 @@ RuntimeEnabledFeatures::SetSkipTouchEventFilterEnabled(enable); } -void WebRuntimeFeatures::EnableStaleWhileRevalidate(bool enable) { - RuntimeEnabledFeatures::SetStaleWhileRevalidateEnabled(enable); -} - void WebRuntimeFeatures::EnableSmsReceiver(bool enable) { RuntimeEnabledFeatures::SetSmsReceiverEnabled(enable); }
diff --git a/third_party/blink/renderer/platform/graphics/animation_worklet_mutator_dispatcher_impl_test.cc b/third_party/blink/renderer/platform/graphics/animation_worklet_mutator_dispatcher_impl_test.cc index 6537e49..a93063f7 100644 --- a/third_party/blink/renderer/platform/graphics/animation_worklet_mutator_dispatcher_impl_test.cc +++ b/third_party/blink/renderer/platform/graphics/animation_worklet_mutator_dispatcher_impl_test.cc
@@ -4,6 +4,7 @@ #include "third_party/blink/renderer/platform/graphics/animation_worklet_mutator_dispatcher_impl.h" +#include "base/run_loop.h" #include "base/single_thread_task_runner.h" #include "base/test/metrics/histogram_tester.h" #include "base/test/simple_test_tick_clock.h"
diff --git a/third_party/blink/renderer/platform/graphics/image_decoding_store_test.cc b/third_party/blink/renderer/platform/graphics/image_decoding_store_test.cc index bd064bbc..65787e1 100644 --- a/third_party/blink/renderer/platform/graphics/image_decoding_store_test.cc +++ b/third_party/blink/renderer/platform/graphics/image_decoding_store_test.cc
@@ -27,6 +27,7 @@ #include <memory> #include "base/memory/memory_pressure_listener.h" +#include "base/run_loop.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/platform/graphics/image_frame_generator.h" #include "third_party/blink/renderer/platform/graphics/test/mock_image_decoder.h"
diff --git a/third_party/blink/renderer/platform/instrumentation/memory_pressure_listener.h b/third_party/blink/renderer/platform/instrumentation/memory_pressure_listener.h index c6cbeea..de9f8d5 100644 --- a/third_party/blink/renderer/platform/instrumentation/memory_pressure_listener.h +++ b/third_party/blink/renderer/platform/instrumentation/memory_pressure_listener.h
@@ -9,11 +9,12 @@ #include "third_party/blink/public/platform/web_memory_pressure_level.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/platform_export.h" -#include "third_party/blink/renderer/platform/scheduler/public/thread.h" #include "third_party/blink/renderer/platform/wtf/threading_primitives.h" namespace blink { +class Thread; + class PLATFORM_EXPORT MemoryPressureListener : public GarbageCollectedMixin { public: virtual ~MemoryPressureListener() = default;
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource.h b/third_party/blink/renderer/platform/loader/fetch/resource.h index c5f00ea..ea72b29 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource.h +++ b/third_party/blink/renderer/platform/loader/fetch/resource.h
@@ -31,7 +31,7 @@ #include "base/single_thread_task_runner.h" #include "base/time/time.h" #include "mojo/public/cpp/base/big_buffer.h" -#include "third_party/blink/public/mojom/loader/code_cache.mojom-blink.h" +#include "third_party/blink/public/mojom/loader/code_cache.mojom-blink-forward.h" #include "third_party/blink/public/platform/scheduler/web_scoped_virtual_time_pauser.h" #include "third_party/blink/renderer/platform/instrumentation/memory_pressure_listener.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/web_process_memory_dump.h"
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_error.h b/third_party/blink/renderer/platform/loader/fetch/resource_error.h index 61cbc35..592174ea 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_error.h +++ b/third_party/blink/renderer/platform/loader/fetch/resource_error.h
@@ -30,7 +30,6 @@ #include <iosfwd> #include "base/optional.h" #include "services/network/public/cpp/cors/cors_error_status.h" -#include "third_party/blink/public/platform/web_url_error.h" #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" @@ -38,6 +37,7 @@ namespace blink { +struct WebURLError; enum class ResourceRequestBlockedReason; // ResourceError represents an error for loading a resource. There is no
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc index add32bc..ac8cbb11 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
@@ -573,8 +573,6 @@ allow_stale_resources_(false), image_fetched_(false), should_log_request_as_invalid_in_imported_document_(false) { - stale_while_revalidate_enabled_ = - RuntimeEnabledFeatures::StaleWhileRevalidateEnabledByRuntimeFlag(); InstanceCounters::IncrementCounter(InstanceCounters::kResourceFetcherCounter); if (IsMainThread()) MainThreadFetchersSet().insert(this); @@ -871,8 +869,7 @@ // stale resource is returned a StaleRevalidation request will be scheduled. // Explicitly disallow stale responses for fetchers that don't have SWR // enabled (via origin trial), and non-GET requests. - resource_request.SetAllowStaleResponse(stale_while_revalidate_enabled_ && - resource_request.HttpMethod() == + resource_request.SetAllowStaleResponse(resource_request.HttpMethod() == http_names::kGET && !params.IsStaleRevalidation()); @@ -2075,10 +2072,6 @@ StopFetchingIncludingKeepaliveLoaders(); } -void ResourceFetcher::SetStaleWhileRevalidateEnabled(bool enabled) { - stale_while_revalidate_enabled_ = enabled; -} - void ResourceFetcher::StopFetchingInternal(StopFetchingTarget target) { // TODO(toyoshim): May want to suspend scheduler while canceling loaders so // that the cancellations below do not awake unnecessary scheduling.
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h index cd2a647..e627b88 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h +++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h
@@ -244,8 +244,6 @@ // counting. void PrepareForLeakDetection(); - void SetStaleWhileRevalidateEnabled(bool enabled); - using ResourceFetcherSet = HeapHashSet<WeakMember<ResourceFetcher>>; static const ResourceFetcherSet& MainThreadFetchers();
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc index 58f00ce..f705847 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher_test.cc
@@ -945,7 +945,6 @@ EXPECT_TRUE(resource->IsLoaded()); EXPECT_TRUE(GetMemoryCache()->Contains(resource)); - fetcher->SetStaleWhileRevalidateEnabled(true); ResourceRequest resource_request(url); resource_request.SetRequestContext(mojom::RequestContextType::INTERNAL); fetch_params = FetchParameters(resource_request);
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 88c9d2b..cc8669b1 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -285,10 +285,6 @@ status: "experimental", }, { - name: "ClientHintsFeaturePolicy", - status: "experimental", - }, - { name: "ClientPlaceholdersForServerLoFi", }, { @@ -1569,11 +1565,6 @@ status: "experimental", }, { - name: "StaleWhileRevalidate", - origin_trial_feature_name: "StaleWhileRevalidate", - status: "stable", - }, - { // Enabled when blink::features::kStorageAccessAPI is enabled. name: "StorageAccessAPI", status: "test",
diff --git a/third_party/blink/renderer/platform/scheduler/common/cooperative_scheduling_manager.cc b/third_party/blink/renderer/platform/scheduler/common/cooperative_scheduling_manager.cc index 74cd66d..0413fe7 100644 --- a/third_party/blink/renderer/platform/scheduler/common/cooperative_scheduling_manager.cc +++ b/third_party/blink/renderer/platform/scheduler/common/cooperative_scheduling_manager.cc
@@ -5,6 +5,7 @@ #include "third_party/blink/renderer/platform/scheduler/public/cooperative_scheduling_manager.h" #include "base/auto_reset.h" +#include "base/run_loop.h" #include "base/time/default_tick_clock.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
diff --git a/third_party/blink/renderer/platform/scheduler/public/DEPS b/third_party/blink/renderer/platform/scheduler/public/DEPS new file mode 100644 index 0000000..1361ae43 --- /dev/null +++ b/third_party/blink/renderer/platform/scheduler/public/DEPS
@@ -0,0 +1,5 @@ +specific_include_rules = { + "thread.h": [ + "+base/task/task_observer.h", + ] +} \ No newline at end of file
diff --git a/third_party/blink/renderer/platform/scheduler/public/thread.h b/third_party/blink/renderer/platform/scheduler/public/thread.h index 9926c72..d02598f 100644 --- a/third_party/blink/renderer/platform/scheduler/public/thread.h +++ b/third_party/blink/renderer/platform/scheduler/public/thread.h
@@ -29,6 +29,7 @@ #include "base/callback_forward.h" #include "base/macros.h" #include "base/memory/scoped_refptr.h" +#include "base/task/task_observer.h" #include "base/threading/thread.h" #include "third_party/blink/public/platform/web_thread_type.h" #include "third_party/blink/renderer/platform/platform_export.h"
diff --git a/third_party/blink/renderer/platform/webrtc/webrtc_video_frame_adapter.cc b/third_party/blink/renderer/platform/webrtc/webrtc_video_frame_adapter.cc index f7708a9..11b6746 100644 --- a/third_party/blink/renderer/platform/webrtc/webrtc_video_frame_adapter.cc +++ b/third_party/blink/renderer/platform/webrtc/webrtc_video_frame_adapter.cc
@@ -4,9 +4,12 @@ #include "third_party/blink/renderer/platform/webrtc/webrtc_video_frame_adapter.h" +#include "base/bind_helpers.h" #include "base/logging.h" +#include "third_party/libyuv/include/libyuv.h" #include "third_party/webrtc/common_video/include/video_frame_buffer.h" #include "third_party/webrtc/rtc_base/ref_counted_object.h" +#include "ui/gfx/gpu_memory_buffer.h" namespace { @@ -78,6 +81,37 @@ CHECK(frame.stride(media::VideoFrame::kVPlane)); } +scoped_refptr<media::VideoFrame> ConstructI420VideoFrame( + const media::VideoFrame& source_frame) { + // NV12 is the only supported format. + DCHECK_EQ(source_frame.format(), media::PIXEL_FORMAT_NV12); + gfx::GpuMemoryBuffer* gmb = source_frame.GetGpuMemoryBuffer(); + if (!gmb || !gmb->Map()) { + return nullptr; + } + scoped_refptr<media::VideoFrame> i420_frame = media::VideoFrame::CreateFrame( + media::PIXEL_FORMAT_I420, source_frame.coded_size(), + source_frame.visible_rect(), source_frame.natural_size(), + source_frame.timestamp()); + i420_frame->metadata()->MergeMetadataFrom(source_frame.metadata()); + const auto& i420_planes = i420_frame->layout().planes(); + int ret = libyuv::NV12ToI420( + reinterpret_cast<const uint8_t*>(gmb->memory(0)), gmb->stride(0), + reinterpret_cast<const uint8_t*>(gmb->memory(1)), gmb->stride(1), + i420_frame->data(media::VideoFrame::kYPlane), + i420_planes[media::VideoFrame::kYPlane].stride, + i420_frame->data(media::VideoFrame::kUPlane), + i420_planes[media::VideoFrame::kUPlane].stride, + i420_frame->data(media::VideoFrame::kVPlane), + i420_planes[media::VideoFrame::kVPlane].stride, + i420_frame->coded_size().width(), i420_frame->coded_size().height()); + gmb->Unmap(); + if (ret) { + return nullptr; + } + return i420_frame; +} + } // anonymous namespace namespace blink { @@ -102,6 +136,25 @@ rtc::scoped_refptr<webrtc::I420BufferInterface> WebRtcVideoFrameAdapter::CreateFrameAdapter() const { + if (frame_->storage_type() == + media::VideoFrame::StorageType::STORAGE_GPU_MEMORY_BUFFER) { + auto i420_frame = ConstructI420VideoFrame(*frame_); + if (!i420_frame) { + return new rtc::RefCountedObject< + FrameAdapter<webrtc::I420BufferInterface>>( + media::VideoFrame::CreateColorFrame(frame_->visible_rect().size(), 0u, + 0x80, 0x80, frame_->timestamp())); + } + + // Keep |frame_| alive until |i420_frame| is destroyed. + i420_frame->AddDestructionObserver(base::BindOnce( + base::DoNothing::Once<scoped_refptr<media::VideoFrame>>(), frame_)); + + IsValidFrame(*i420_frame); + return new rtc::RefCountedObject<FrameAdapter<webrtc::I420BufferInterface>>( + i420_frame); + } + // We cant convert texture synchronously due to threading issues, see // https://crbug.com/663452. Instead, return a black frame (yuv = {0, 0x80, // 0x80}).
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 996ba8c..8b0e003 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -84,6 +84,8 @@ crbug.com/906879 http/tests/inspector-protocol/network/navigation-blocking-xorigin-iframe.js [ Pass Failure ] crbug.com/949003 http/tests/printing/cross-site-frame-scrolled.html [ Pass Failure ] crbug.com/949003 http/tests/printing/cross-site-frame.html [ Pass Failure ] +crbug.com/1007228 external/wpt/fullscreen/api/element-request-fullscreen-and-move-to-iframe-manual.html [ Pass Failure ] +crbug.com/1007229 external/wpt/intersection-observer/same-origin-grand-child-iframe.sub.html [ Pass Failure ] # ====== Site Isolation failures until here ====== # ====== Oilpan-only failures from here ====== @@ -3225,6 +3227,7 @@ crbug.com/618969 external/wpt/css/css-grid/subgrid/ [ Skip ] # ====== New tests from wpt-importer added here ====== +crbug.com/626703 [ Win10 ] external/wpt/payment-request/payment-request-hasenrolledinstrument-method.tentative.https.html [ Failure Timeout ] crbug.com/626703 [ Linux ] external/wpt/css/motion/offset-path-ray-contain-003.html [ Failure ] crbug.com/626703 [ Mac ] external/wpt/css/motion/offset-path-ray-contain-003.html [ Failure ] crbug.com/626703 [ Win ] external/wpt/css/motion/offset-path-ray-contain-003.html [ Failure ] @@ -5790,9 +5793,6 @@ # Sheriff 2019-04-18 crbug.com/954297 [ Linux Win ] http/tests/devtools/oopif/oopif-presentation-console-messages.js [ Pass Crash Timeout ] -# Sheriff 2019-04-19 -crbug.com/954628 [ Win ] external/wpt/payment-request/payment-request-canmakepayment-method.https.html [ Pass Timeout ] - # Sheriff 2019-04-22 crbug.com/954319 [ Linux ] http/tests/devtools/sources/debugger-breakpoints/breakpoints-ui-in-multiple-workers.js [ Pass Timeout ] crbug.com/954998 [ Mac ] http/tests/devtools/tracing/timeline-js/timeline-js-line-level-profile-end-to-end.js [ Pass Timeout ]
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json index 7907bfa..afb1ae3 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json
@@ -2059,369 +2059,333 @@ {} ] ], - "css/css-transitions/transition-delay-000.html": [ + "css/css-transitions/transition-delay-000-manual.html": [ [ - "css/css-transitions/transition-delay-000.html", + "css/css-transitions/transition-delay-000-manual.html", {} ] ], - "css/css-transitions/transition-delay-002.html": [ + "css/css-transitions/transition-delay-002-manual.html": [ [ - "css/css-transitions/transition-delay-002.html", + "css/css-transitions/transition-delay-002-manual.html", {} ] ], - "css/css-transitions/transition-delay-003.html": [ + "css/css-transitions/transition-delay-003-manual.html": [ [ - "css/css-transitions/transition-delay-003.html", + "css/css-transitions/transition-delay-003-manual.html", {} ] ], - "css/css-transitions/transition-duration-002.html": [ + "css/css-transitions/transition-duration-002-manual.html": [ [ - "css/css-transitions/transition-duration-002.html", + "css/css-transitions/transition-duration-002-manual.html", {} ] ], - "css/css-transitions/transition-duration-003.html": [ + "css/css-transitions/transition-duration-003-manual.html": [ [ - "css/css-transitions/transition-duration-003.html", + "css/css-transitions/transition-duration-003-manual.html", {} ] ], - "css/css-transitions/transition-duration-004.html": [ + "css/css-transitions/transition-duration-004-manual.html": [ [ - "css/css-transitions/transition-duration-004.html", + "css/css-transitions/transition-duration-004-manual.html", {} ] ], - "css/css-transitions/transition-property-003.html": [ + "css/css-transitions/transition-property-003-manual.html": [ [ - "css/css-transitions/transition-property-003.html", + "css/css-transitions/transition-property-003-manual.html", {} ] ], - "css/css-transitions/transition-property-004.html": [ + "css/css-transitions/transition-property-004-manual.html": [ [ - "css/css-transitions/transition-property-004.html", + "css/css-transitions/transition-property-004-manual.html", {} ] ], - "css/css-transitions/transition-property-005.html": [ + "css/css-transitions/transition-property-005-manual.html": [ [ - "css/css-transitions/transition-property-005.html", + "css/css-transitions/transition-property-005-manual.html", {} ] ], - "css/css-transitions/transition-property-006.html": [ + "css/css-transitions/transition-property-006-manual.html": [ [ - "css/css-transitions/transition-property-006.html", + "css/css-transitions/transition-property-006-manual.html", {} ] ], - "css/css-transitions/transition-property-007.html": [ + "css/css-transitions/transition-property-007-manual.html": [ [ - "css/css-transitions/transition-property-007.html", + "css/css-transitions/transition-property-007-manual.html", {} ] ], - "css/css-transitions/transition-property-008.html": [ + "css/css-transitions/transition-property-008-manual.html": [ [ - "css/css-transitions/transition-property-008.html", + "css/css-transitions/transition-property-008-manual.html", {} ] ], - "css/css-transitions/transition-property-009.html": [ + "css/css-transitions/transition-property-009-manual.html": [ [ - "css/css-transitions/transition-property-009.html", + "css/css-transitions/transition-property-009-manual.html", {} ] ], - "css/css-transitions/transition-property-010.html": [ + "css/css-transitions/transition-property-010-manual.html": [ [ - "css/css-transitions/transition-property-010.html", + "css/css-transitions/transition-property-010-manual.html", {} ] ], - "css/css-transitions/transition-property-011.html": [ + "css/css-transitions/transition-property-011-manual.html": [ [ - "css/css-transitions/transition-property-011.html", + "css/css-transitions/transition-property-011-manual.html", {} ] ], - "css/css-transitions/transition-property-012.html": [ + "css/css-transitions/transition-property-012-manual.html": [ [ - "css/css-transitions/transition-property-012.html", + "css/css-transitions/transition-property-012-manual.html", {} ] ], - "css/css-transitions/transition-property-013.html": [ + "css/css-transitions/transition-property-013-manual.html": [ [ - "css/css-transitions/transition-property-013.html", + "css/css-transitions/transition-property-013-manual.html", {} ] ], - "css/css-transitions/transition-property-014.html": [ + "css/css-transitions/transition-property-014-manual.html": [ [ - "css/css-transitions/transition-property-014.html", + "css/css-transitions/transition-property-014-manual.html", {} ] ], - "css/css-transitions/transition-property-015.html": [ + "css/css-transitions/transition-property-015-manual.html": [ [ - "css/css-transitions/transition-property-015.html", + "css/css-transitions/transition-property-015-manual.html", {} ] ], - "css/css-transitions/transition-property-016.html": [ + "css/css-transitions/transition-property-016-manual.html": [ [ - "css/css-transitions/transition-property-016.html", + "css/css-transitions/transition-property-016-manual.html", {} ] ], - "css/css-transitions/transition-property-017.html": [ + "css/css-transitions/transition-property-017-manual.html": [ [ - "css/css-transitions/transition-property-017.html", + "css/css-transitions/transition-property-017-manual.html", {} ] ], - "css/css-transitions/transition-property-018.html": [ + "css/css-transitions/transition-property-018-manual.html": [ [ - "css/css-transitions/transition-property-018.html", + "css/css-transitions/transition-property-018-manual.html", {} ] ], - "css/css-transitions/transition-property-019.html": [ + "css/css-transitions/transition-property-019-manual.html": [ [ - "css/css-transitions/transition-property-019.html", + "css/css-transitions/transition-property-019-manual.html", {} ] ], - "css/css-transitions/transition-property-020.html": [ + "css/css-transitions/transition-property-020-manual.html": [ [ - "css/css-transitions/transition-property-020.html", + "css/css-transitions/transition-property-020-manual.html", {} ] ], - "css/css-transitions/transition-property-021.html": [ + "css/css-transitions/transition-property-021-manual.html": [ [ - "css/css-transitions/transition-property-021.html", + "css/css-transitions/transition-property-021-manual.html", {} ] ], - "css/css-transitions/transition-property-022.html": [ + "css/css-transitions/transition-property-022-manual.html": [ [ - "css/css-transitions/transition-property-022.html", + "css/css-transitions/transition-property-022-manual.html", {} ] ], - "css/css-transitions/transition-property-023.html": [ + "css/css-transitions/transition-property-023-manual.html": [ [ - "css/css-transitions/transition-property-023.html", + "css/css-transitions/transition-property-023-manual.html", {} ] ], - "css/css-transitions/transition-property-024.html": [ + "css/css-transitions/transition-property-024-manual.html": [ [ - "css/css-transitions/transition-property-024.html", + "css/css-transitions/transition-property-024-manual.html", {} ] ], - "css/css-transitions/transition-property-025.html": [ + "css/css-transitions/transition-property-025-manual.html": [ [ - "css/css-transitions/transition-property-025.html", + "css/css-transitions/transition-property-025-manual.html", {} ] ], - "css/css-transitions/transition-property-026.html": [ + "css/css-transitions/transition-property-026-manual.html": [ [ - "css/css-transitions/transition-property-026.html", + "css/css-transitions/transition-property-026-manual.html", {} ] ], - "css/css-transitions/transition-property-027.html": [ + "css/css-transitions/transition-property-027-manual.html": [ [ - "css/css-transitions/transition-property-027.html", + "css/css-transitions/transition-property-027-manual.html", {} ] ], - "css/css-transitions/transition-property-028.html": [ + "css/css-transitions/transition-property-028-manual.html": [ [ - "css/css-transitions/transition-property-028.html", + "css/css-transitions/transition-property-028-manual.html", {} ] ], - "css/css-transitions/transition-property-029.html": [ + "css/css-transitions/transition-property-029-manual.html": [ [ - "css/css-transitions/transition-property-029.html", + "css/css-transitions/transition-property-029-manual.html", {} ] ], - "css/css-transitions/transition-property-030.html": [ + "css/css-transitions/transition-property-030-manual.html": [ [ - "css/css-transitions/transition-property-030.html", + "css/css-transitions/transition-property-030-manual.html", {} ] ], - "css/css-transitions/transition-property-031.html": [ + "css/css-transitions/transition-property-031-manual.html": [ [ - "css/css-transitions/transition-property-031.html", + "css/css-transitions/transition-property-031-manual.html", {} ] ], - "css/css-transitions/transition-property-032.html": [ + "css/css-transitions/transition-property-032-manual.html": [ [ - "css/css-transitions/transition-property-032.html", + "css/css-transitions/transition-property-032-manual.html", {} ] ], - "css/css-transitions/transition-property-033.html": [ + "css/css-transitions/transition-property-033-manual.html": [ [ - "css/css-transitions/transition-property-033.html", + "css/css-transitions/transition-property-033-manual.html", {} ] ], - "css/css-transitions/transition-property-034.html": [ + "css/css-transitions/transition-property-034-manual.html": [ [ - "css/css-transitions/transition-property-034.html", + "css/css-transitions/transition-property-034-manual.html", {} ] ], - "css/css-transitions/transition-property-035.html": [ + "css/css-transitions/transition-property-035-manual.html": [ [ - "css/css-transitions/transition-property-035.html", + "css/css-transitions/transition-property-035-manual.html", {} ] ], - "css/css-transitions/transition-property-036.html": [ + "css/css-transitions/transition-property-036-manual.html": [ [ - "css/css-transitions/transition-property-036.html", + "css/css-transitions/transition-property-036-manual.html", {} ] ], - "css/css-transitions/transition-property-037.html": [ + "css/css-transitions/transition-property-037-manual.html": [ [ - "css/css-transitions/transition-property-037.html", + "css/css-transitions/transition-property-037-manual.html", {} ] ], - "css/css-transitions/transition-property-038.html": [ + "css/css-transitions/transition-property-038-manual.html": [ [ - "css/css-transitions/transition-property-038.html", + "css/css-transitions/transition-property-038-manual.html", {} ] ], - "css/css-transitions/transition-property-039.html": [ + "css/css-transitions/transition-property-039-manual.html": [ [ - "css/css-transitions/transition-property-039.html", + "css/css-transitions/transition-property-039-manual.html", {} ] ], - "css/css-transitions/transition-property-040.html": [ + "css/css-transitions/transition-property-040-manual.html": [ [ - "css/css-transitions/transition-property-040.html", + "css/css-transitions/transition-property-040-manual.html", {} ] ], - "css/css-transitions/transition-property-041.html": [ + "css/css-transitions/transition-property-041-manual.html": [ [ - "css/css-transitions/transition-property-041.html", + "css/css-transitions/transition-property-041-manual.html", {} ] ], - "css/css-transitions/transition-property-042.html": [ + "css/css-transitions/transition-property-042-manual.html": [ [ - "css/css-transitions/transition-property-042.html", + "css/css-transitions/transition-property-042-manual.html", {} ] ], - "css/css-transitions/transition-property-043.html": [ + "css/css-transitions/transition-property-043-manual.html": [ [ - "css/css-transitions/transition-property-043.html", + "css/css-transitions/transition-property-043-manual.html", {} ] ], - "css/css-transitions/transition-property-044.html": [ + "css/css-transitions/transition-property-044-manual.html": [ [ - "css/css-transitions/transition-property-044.html", + "css/css-transitions/transition-property-044-manual.html", {} ] ], - "css/css-transitions/transition-property-045.html": [ + "css/css-transitions/transition-property-045-manual.html": [ [ - "css/css-transitions/transition-property-045.html", + "css/css-transitions/transition-property-045-manual.html", {} ] ], - "css/css-transitions/transition-timing-function-002.html": [ + "css/css-transitions/transition-timing-function-002-manual.html": [ [ - "css/css-transitions/transition-timing-function-002.html", + "css/css-transitions/transition-timing-function-002-manual.html", {} ] ], - "css/css-transitions/transition-timing-function-003.html": [ + "css/css-transitions/transition-timing-function-003-manual.html": [ [ - "css/css-transitions/transition-timing-function-003.html", + "css/css-transitions/transition-timing-function-003-manual.html", {} ] ], - "css/css-transitions/transition-timing-function-004.html": [ + "css/css-transitions/transition-timing-function-004-manual.html": [ [ - "css/css-transitions/transition-timing-function-004.html", + "css/css-transitions/transition-timing-function-004-manual.html", {} ] ], - "css/css-transitions/transition-timing-function-005.html": [ + "css/css-transitions/transition-timing-function-005-manual.html": [ [ - "css/css-transitions/transition-timing-function-005.html", + "css/css-transitions/transition-timing-function-005-manual.html", {} ] ], - "css/css-transitions/transition-timing-function-006.html": [ + "css/css-transitions/transition-timing-function-006-manual.html": [ [ - "css/css-transitions/transition-timing-function-006.html", + "css/css-transitions/transition-timing-function-006-manual.html", {} ] ], - "css/css-transitions/transition-timing-function-007.html": [ + "css/css-transitions/transition-timing-function-010-manual.html": [ [ - "css/css-transitions/transition-timing-function-007.html", - {} - ] - ], - "css/css-transitions/transition-timing-function-008.html": [ - [ - "css/css-transitions/transition-timing-function-008.html", - {} - ] - ], - "css/css-transitions/transition-timing-function-009.html": [ - [ - "css/css-transitions/transition-timing-function-009.html", - {} - ] - ], - "css/css-transitions/transition-timing-function-010.html": [ - [ - "css/css-transitions/transition-timing-function-010.html", - {} - ] - ], - "css/css-transitions/transition-timing-function-011.html": [ - [ - "css/css-transitions/transition-timing-function-011.html", - {} - ] - ], - "css/css-transitions/transition-timing-function-012.html": [ - [ - "css/css-transitions/transition-timing-function-012.html", - {} - ] - ], - "css/css-transitions/transition-timing-function-013.html": [ - [ - "css/css-transitions/transition-timing-function-013.html", + "css/css-transitions/transition-timing-function-010-manual.html", {} ] ], @@ -11485,6 +11449,30 @@ {} ] ], + "css/CSS2/floats/new-fc-beside-float-with-margin-rtl.html": [ + [ + "css/CSS2/floats/new-fc-beside-float-with-margin-rtl.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "css/CSS2/floats/new-fc-beside-float-with-margin.html": [ + [ + "css/CSS2/floats/new-fc-beside-float-with-margin.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], "css/CSS2/floats/new-fc-relayout.html": [ [ "css/CSS2/floats/new-fc-relayout.html", @@ -11569,9 +11557,9 @@ {} ] ], - "css/CSS2/floats/zero-width-floats-positioning.html": [ + "css/CSS2/floats/zero-width-floats-positioning.tentative.html": [ [ - "css/CSS2/floats/zero-width-floats-positioning.html", + "css/CSS2/floats/zero-width-floats-positioning.tentative.html", [ [ "/css/reference/ref-filled-green-100px-square-only.html", @@ -36289,6 +36277,18 @@ {} ] ], + "css/css-cascade/all-prop-initial-visited.html": [ + [ + "css/css-cascade/all-prop-initial-visited.html", + [ + [ + "/css/css-cascade/all-prop-initial-visited-ref.html", + "==" + ] + ], + {} + ] + ], "css/css-cascade/important-prop.html": [ [ "css/css-cascade/important-prop.html", @@ -50507,6 +50507,294 @@ {} ] ], + "css/css-grid/grid-items/grid-items-percentage-margins-003.html": [ + [ + "css/css-grid/grid-items/grid-items-percentage-margins-003.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "css/css-grid/grid-items/grid-items-percentage-margins-004.html": [ + [ + "css/css-grid/grid-items/grid-items-percentage-margins-004.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "css/css-grid/grid-items/grid-items-percentage-margins-005.html": [ + [ + "css/css-grid/grid-items/grid-items-percentage-margins-005.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "css/css-grid/grid-items/grid-items-percentage-margins-006.html": [ + [ + "css/css-grid/grid-items/grid-items-percentage-margins-006.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "css/css-grid/grid-items/grid-items-percentage-margins-007.html": [ + [ + "css/css-grid/grid-items/grid-items-percentage-margins-007.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "css/css-grid/grid-items/grid-items-percentage-margins-008.html": [ + [ + "css/css-grid/grid-items/grid-items-percentage-margins-008.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "css/css-grid/grid-items/grid-items-percentage-margins-009.html": [ + [ + "css/css-grid/grid-items/grid-items-percentage-margins-009.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "css/css-grid/grid-items/grid-items-percentage-margins-010.html": [ + [ + "css/css-grid/grid-items/grid-items-percentage-margins-010.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "css/css-grid/grid-items/grid-items-percentage-margins-011.html": [ + [ + "css/css-grid/grid-items/grid-items-percentage-margins-011.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "css/css-grid/grid-items/grid-items-percentage-margins-012.html": [ + [ + "css/css-grid/grid-items/grid-items-percentage-margins-012.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "css/css-grid/grid-items/grid-items-percentage-margins-013.html": [ + [ + "css/css-grid/grid-items/grid-items-percentage-margins-013.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "css/css-grid/grid-items/grid-items-percentage-margins-014.html": [ + [ + "css/css-grid/grid-items/grid-items-percentage-margins-014.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "css/css-grid/grid-items/grid-items-percentage-paddings-003.html": [ + [ + "css/css-grid/grid-items/grid-items-percentage-paddings-003.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "css/css-grid/grid-items/grid-items-percentage-paddings-004.html": [ + [ + "css/css-grid/grid-items/grid-items-percentage-paddings-004.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "css/css-grid/grid-items/grid-items-percentage-paddings-005.html": [ + [ + "css/css-grid/grid-items/grid-items-percentage-paddings-005.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "css/css-grid/grid-items/grid-items-percentage-paddings-006.html": [ + [ + "css/css-grid/grid-items/grid-items-percentage-paddings-006.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "css/css-grid/grid-items/grid-items-percentage-paddings-007.html": [ + [ + "css/css-grid/grid-items/grid-items-percentage-paddings-007.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "css/css-grid/grid-items/grid-items-percentage-paddings-008.html": [ + [ + "css/css-grid/grid-items/grid-items-percentage-paddings-008.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "css/css-grid/grid-items/grid-items-percentage-paddings-009.html": [ + [ + "css/css-grid/grid-items/grid-items-percentage-paddings-009.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "css/css-grid/grid-items/grid-items-percentage-paddings-010.html": [ + [ + "css/css-grid/grid-items/grid-items-percentage-paddings-010.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "css/css-grid/grid-items/grid-items-percentage-paddings-011.html": [ + [ + "css/css-grid/grid-items/grid-items-percentage-paddings-011.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "css/css-grid/grid-items/grid-items-percentage-paddings-012.html": [ + [ + "css/css-grid/grid-items/grid-items-percentage-paddings-012.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "css/css-grid/grid-items/grid-items-percentage-paddings-013.html": [ + [ + "css/css-grid/grid-items/grid-items-percentage-paddings-013.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "css/css-grid/grid-items/grid-items-percentage-paddings-014.html": [ + [ + "css/css-grid/grid-items/grid-items-percentage-paddings-014.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], "css/css-grid/grid-items/grid-items-sizing-alignment-001.html": [ [ "css/css-grid/grid-items/grid-items-sizing-alignment-001.html", @@ -86671,6 +86959,18 @@ {} ] ], + "css/css-values/min-max-percentage-length-interpolation.html": [ + [ + "css/css-values/min-max-percentage-length-interpolation.html", + [ + [ + "/css/reference/ref-filled-green-100px-square-only.html", + "==" + ] + ], + {} + ] + ], "css/css-values/q-unit-case-insensitivity-001.html": [ [ "css/css-values/q-unit-case-insensitivity-001.html", @@ -112389,6 +112689,18 @@ {} ] ], + "html/rendering/non-replaced-elements/tables/table-column-width.html": [ + [ + "html/rendering/non-replaced-elements/tables/table-column-width.html", + [ + [ + "/html/rendering/non-replaced-elements/tables/table-column-width-ref.html", + "==" + ] + ], + {} + ] + ], "html/rendering/non-replaced-elements/tables/table-direction.html": [ [ "html/rendering/non-replaced-elements/tables/table-direction.html", @@ -129547,6 +129859,9 @@ "css/css-backgrounds/OWNERS": [ [] ], + "css/css-backgrounds/animations/border-image-outset-interpolation-expected.txt": [ + [] + ], "css/css-backgrounds/animations/border-image-source-interpolation-expected.txt": [ [] ], @@ -129961,9 +130276,6 @@ "css/css-backgrounds/parsing/background-image-computed.sub-expected.txt": [ [] ], - "css/css-backgrounds/parsing/background-invalid-expected.txt": [ - [] - ], "css/css-backgrounds/parsing/background-position-computed-expected.txt": [ [] ], @@ -130483,6 +130795,9 @@ "css/css-cascade/all-prop-001-ref.html": [ [] ], + "css/css-cascade/all-prop-initial-visited-ref.html": [ + [] + ], "css/css-cascade/important-prop-ref.html": [ [] ], @@ -130975,6 +131290,9 @@ "css/css-content/element-replacement-ref.html": [ [] ], + "css/css-content/inheritance-expected.txt": [ + [] + ], "css/css-content/pseudo-element-inline-box-ref.html": [ [] ], @@ -143530,9 +143848,15 @@ "css/css-transitions/event-dispatch.tentative-expected.txt": [ [] ], + "css/css-transitions/idlharness-expected.txt": [ + [] + ], "css/css-transitions/no-transition-from-ua-to-blocking-stylesheet-ref.html": [ [] ], + "css/css-transitions/parsing/transition-timing-function-valid-expected.txt": [ + [] + ], "css/css-transitions/properties-value-001-expected.txt": [ [] ], @@ -147694,6 +148018,9 @@ "css/mediaqueries/OWNERS": [ [] ], + "css/mediaqueries/aspect-ratio-serialization-expected.txt": [ + [] + ], "css/mediaqueries/forced-colors-expected.txt": [ [] ], @@ -147772,6 +148099,9 @@ "css/motion/offset-rotate-ref.html": [ [] ], + "css/motion/parsing/offset-parsing-valid-expected.txt": [ + [] + ], "css/motion/parsing/offset-path-computed-expected.txt": [ [] ], @@ -157741,6 +158071,9 @@ "html/rendering/non-replaced-elements/tables/table-cell-width-ref.html": [ [] ], + "html/rendering/non-replaced-elements/tables/table-column-width-ref.html": [ + [] + ], "html/rendering/non-replaced-elements/tables/table-direction-ref.html": [ [] ], @@ -160966,6 +161299,9 @@ "infrastructure/expected-fail/uncaught-exception-expected.txt": [ [] ], + "infrastructure/expected-fail/unhandled-rejection-expected.txt": [ + [] + ], "infrastructure/metadata/infrastructure/assumptions/allowed-to-play.html.ini": [ [] ], @@ -160984,6 +161320,9 @@ "infrastructure/metadata/infrastructure/expected-fail/uncaught-exception.html.ini": [ [] ], + "infrastructure/metadata/infrastructure/expected-fail/unhandled-rejection.html.ini": [ + [] + ], "infrastructure/metadata/infrastructure/reftest/reftest_and_fail.html.ini": [ [] ], @@ -161554,6 +161893,12 @@ "interfaces/webvtt.idl": [ [] ], + "interfaces/webxr-ar-module.idl": [ + [] + ], + "interfaces/webxr-gamepads-module.idl": [ + [] + ], "interfaces/webxr.idl": [ [] ], @@ -161581,6 +161926,9 @@ "intersection-observer/observer-in-iframe.html": [ [] ], + "intersection-observer/resources/cross-origin-child-iframe.sub.html": [ + [] + ], "intersection-observer/resources/cross-origin-subframe.html": [ [] ], @@ -161593,6 +161941,9 @@ "intersection-observer/resources/observer-in-iframe-subframe.html": [ [] ], + "intersection-observer/resources/same-origin-grand-child-iframe.html": [ + [] + ], "intersection-observer/resources/scaled-target-subframe.html": [ [] ], @@ -163603,6 +163954,9 @@ "payment-handler/can-make-payment-event.https-expected.txt": [ [] ], + "payment-handler/change-payment-method-manual.https-expected.txt": [ + [] + ], "payment-handler/idlharness.https.any.serviceworker-expected.txt": [ [] ], @@ -163696,9 +164050,6 @@ "payment-request/payment-request-hasenrolledinstrument-method-protection.tentative.https-expected.txt": [ [] ], - "payment-request/payment-request-hasenrolledinstrument-method.tentative.https-expected.txt": [ - [] - ], "payment-request/payment-request-show-method.https-expected.txt": [ [] ], @@ -163741,6 +164092,12 @@ "permissions/META.yml": [ [] ], + "permissions/feature-policy-permissions-query.html": [ + [] + ], + "permissions/permissions-query-feature-policy-attribute.https.sub-expected.txt": [ + [] + ], "picture-in-picture/META.yml": [ [] ], @@ -163876,6 +164233,9 @@ "portals/resources/portal-post-message-portal.html": [ [] ], + "portals/resources/portal-repeated-activate-window.html": [ + [] + ], "portals/resources/portals-adopt-predecessor-portal.html": [ [] ], @@ -163891,6 +164251,9 @@ "portals/resources/postmessage-referrer.sub.html": [ [] ], + "portals/resources/simple-portal-adopts-and-activates-predecessor.html": [ + [] + ], "portals/resources/simple-portal-adopts-predecessor.html": [ [] ], @@ -168553,6 +168916,9 @@ "shadow-dom/directionality-002-ref.html": [ [] ], + "shadow-dom/focus/focus-selector-delegatesFocus-expected.txt": [ + [] + ], "shadow-dom/focus/resources/shadow-utils.js": [ [] ], @@ -174286,6 +174652,9 @@ "web-animations/interfaces/KeyframeEffect/iterationComposite-expected.txt": [ [] ], + "web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-001-expected.txt": [ + [] + ], "web-animations/interfaces/KeyframeEffect/style-change-events-expected.txt": [ [] ], @@ -177004,6 +177373,9 @@ "webxr/resources/webxr_util.js": [ [] ], + "webxr/xrWebGLLayer_constructor.https-expected.txt": [ + [] + ], "workers/META.yml": [ [] ], @@ -201624,6 +201996,12 @@ {} ] ], + "css/css-animations/parsing/animation-invalid.html": [ + [ + "css/css-animations/parsing/animation-invalid.html", + {} + ] + ], "css/css-animations/parsing/animation-iteration-count-computed.html": [ [ "css/css-animations/parsing/animation-iteration-count-computed.html", @@ -201678,6 +202056,12 @@ {} ] ], + "css/css-animations/parsing/animation-shorthand.html": [ + [ + "css/css-animations/parsing/animation-shorthand.html", + {} + ] + ], "css/css-animations/parsing/animation-timing-function-computed.html": [ [ "css/css-animations/parsing/animation-timing-function-computed.html", @@ -201696,6 +202080,12 @@ {} ] ], + "css/css-animations/parsing/animation-valid.html": [ + [ + "css/css-animations/parsing/animation-valid.html", + {} + ] + ], "css/css-animations/pending-style-changes-001.html": [ [ "css/css-animations/pending-style-changes-001.html", @@ -202332,6 +202722,12 @@ {} ] ], + "css/css-box/parsing/margin-shorthand.html": [ + [ + "css/css-box/parsing/margin-shorthand.html", + {} + ] + ], "css/css-box/parsing/margin-valid.html": [ [ "css/css-box/parsing/margin-valid.html", @@ -202410,6 +202806,12 @@ {} ] ], + "css/css-box/parsing/padding-shorthand.html": [ + [ + "css/css-box/parsing/padding-shorthand.html", + {} + ] + ], "css/css-box/parsing/padding-valid.html": [ [ "css/css-box/parsing/padding-valid.html", @@ -202790,6 +203192,12 @@ {} ] ], + "css/css-content/inheritance.html": [ + [ + "css/css-content/inheritance.html", + {} + ] + ], "css/css-device-adapt/documentElement-clientWidth-on-minimum-scale-size.tentative.html": [ [ "css/css-device-adapt/documentElement-clientWidth-on-minimum-scale-size.tentative.html", @@ -203534,6 +203942,12 @@ {} ] ], + "css/css-flexbox/parsing/flex-flow-shorthand.html": [ + [ + "css/css-flexbox/parsing/flex-flow-shorthand.html", + {} + ] + ], "css/css-flexbox/parsing/flex-flow-valid.html": [ [ "css/css-flexbox/parsing/flex-flow-valid.html", @@ -203564,6 +203978,12 @@ {} ] ], + "css/css-flexbox/parsing/flex-shorthand.html": [ + [ + "css/css-flexbox/parsing/flex-shorthand.html", + {} + ] + ], "css/css-flexbox/parsing/flex-shrink-computed.html": [ [ "css/css-flexbox/parsing/flex-shrink-computed.html", @@ -205872,6 +206292,12 @@ {} ] ], + "css/css-grid/grid-items/grid-item-dynamic-min-contribution-001.html": [ + [ + "css/css-grid/grid-items/grid-item-dynamic-min-contribution-001.html", + {} + ] + ], "css/css-grid/grid-items/grid-item-min-auto-size-001.html": [ [ "css/css-grid/grid-items/grid-item-min-auto-size-001.html", @@ -206184,6 +206610,12 @@ {} ] ], + "css/css-grid/parsing/grid-area-shorthand.html": [ + [ + "css/css-grid/parsing/grid-area-shorthand.html", + {} + ] + ], "css/css-grid/parsing/grid-area-valid.html": [ [ "css/css-grid/parsing/grid-area-valid.html", @@ -206286,6 +206718,12 @@ {} ] ], + "css/css-grid/parsing/grid-template-shorthand.html": [ + [ + "css/css-grid/parsing/grid-template-shorthand.html", + {} + ] + ], "css/css-grid/placement/grid-auto-placement-implicit-tracks-001.html": [ [ "css/css-grid/placement/grid-auto-placement-implicit-tracks-001.html", @@ -206688,6 +207126,12 @@ {} ] ], + "css/css-lists/parsing/list-style-shorthand.sub.html": [ + [ + "css/css-lists/parsing/list-style-shorthand.sub.html", + {} + ] + ], "css/css-lists/parsing/list-style-type-computed.html": [ [ "css/css-lists/parsing/list-style-type-computed.html", @@ -207024,6 +207468,12 @@ {} ] ], + "css/css-logical/parsing/inset-shorthand.html": [ + [ + "css/css-logical/parsing/inset-shorthand.html", + {} + ] + ], "css/css-logical/parsing/inset-valid.html": [ [ "css/css-logical/parsing/inset-valid.html", @@ -210798,6 +211248,12 @@ {} ] ], + "css/css-text-decor/parsing/text-decoration-shorthand.html": [ + [ + "css/css-text-decor/parsing/text-decoration-shorthand.html", + {} + ] + ], "css/css-text-decor/parsing/text-decoration-skip-ink-computed.html": [ [ "css/css-text-decor/parsing/text-decoration-skip-ink-computed.html", @@ -213192,6 +213648,12 @@ {} ] ], + "css/css-transitions/parsing/transition-invalid.html": [ + [ + "css/css-transitions/parsing/transition-invalid.html", + {} + ] + ], "css/css-transitions/parsing/transition-property-computed.html": [ [ "css/css-transitions/parsing/transition-property-computed.html", @@ -213210,6 +213672,12 @@ {} ] ], + "css/css-transitions/parsing/transition-shorthand.html": [ + [ + "css/css-transitions/parsing/transition-shorthand.html", + {} + ] + ], "css/css-transitions/parsing/transition-timing-function-computed.html": [ [ "css/css-transitions/parsing/transition-timing-function-computed.html", @@ -213228,6 +213696,12 @@ {} ] ], + "css/css-transitions/parsing/transition-valid.html": [ + [ + "css/css-transitions/parsing/transition-valid.html", + {} + ] + ], "css/css-transitions/properties-value-001.html": [ [ "css/css-transitions/properties-value-001.html", @@ -213346,12 +213820,6 @@ {} ] ], - "css/css-transitions/transition-timing-function-001.html": [ - [ - "css/css-transitions/transition-timing-function-001.html", - {} - ] - ], "css/css-transitions/transitioncancel-001.html": [ [ "css/css-transitions/transitioncancel-001.html", @@ -215586,6 +216054,12 @@ {} ] ], + "css/css-ui/parsing/outline-shorthand.html": [ + [ + "css/css-ui/parsing/outline-shorthand.html", + {} + ] + ], "css/css-ui/parsing/outline-style-computed.html": [ [ "css/css-ui/parsing/outline-style-computed.html", @@ -215832,6 +216306,24 @@ {} ] ], + "css/css-values/clamp-length-computed.html": [ + [ + "css/css-values/clamp-length-computed.html", + {} + ] + ], + "css/css-values/clamp-length-invalid.html": [ + [ + "css/css-values/clamp-length-invalid.html", + {} + ] + ], + "css/css-values/clamp-length-serialize.html": [ + [ + "css/css-values/clamp-length-serialize.html", + {} + ] + ], "css/css-values/getComputedStyle-border-radius-001.html": [ [ "css/css-values/getComputedStyle-border-radius-001.html", @@ -218260,6 +218752,12 @@ {} ] ], + "css/mediaqueries/aspect-ratio-serialization.html": [ + [ + "css/mediaqueries/aspect-ratio-serialization.html", + {} + ] + ], "css/mediaqueries/forced-colors.html": [ [ "css/mediaqueries/forced-colors.html", @@ -220917,6 +221415,12 @@ {} ] ], + "dom/nodes/MutationObserver-sanity.html": [ + [ + "dom/nodes/MutationObserver-sanity.html", + {} + ] + ], "dom/nodes/MutationObserver-takeRecords.html": [ [ "dom/nodes/MutationObserver-takeRecords.html", @@ -242302,6 +242806,12 @@ {} ] ], + "html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-remove-from-document-different-load.html": [ + [ + "html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-remove-from-document-different-load.html", + {} + ] + ], "html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-remove-from-document-networkState.html": [ [ "html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-remove-from-document-networkState.html", @@ -251929,6 +252439,12 @@ {} ] ], + "infrastructure/expected-fail/unhandled-rejection.html": [ + [ + "infrastructure/expected-fail/unhandled-rejection.html", + {} + ] + ], "infrastructure/server/context.any.js": [ [ "infrastructure/server/context.any.html", @@ -252517,6 +253033,12 @@ {} ] ], + "intersection-observer/same-origin-grand-child-iframe.sub.html": [ + [ + "intersection-observer/same-origin-grand-child-iframe.sub.html", + {} + ] + ], "intersection-observer/shadow-content.html": [ [ "intersection-observer/shadow-content.html", @@ -268840,6 +269362,12 @@ } ] ], + "permissions/permissions-query-feature-policy-attribute.https.sub.html": [ + [ + "permissions/permissions-query-feature-policy-attribute.https.sub.html", + {} + ] + ], "permissions/test-background-fetch-permission.html": [ [ "permissions/test-background-fetch-permission.html", @@ -269843,6 +270371,12 @@ {} ] ], + "portals/portals-repeated-activate.html": [ + [ + "portals/portals-repeated-activate.html", + {} + ] + ], "portals/portals-set-src-after-activate.html": [ [ "portals/portals-set-src-after-activate.html", @@ -284908,6 +285442,14 @@ } ] ], + "shadow-dom/focus/focus-selector-delegatesFocus.html": [ + [ + "shadow-dom/focus/focus-selector-delegatesFocus.html", + { + "testdriver": true + } + ] + ], "shadow-dom/focus/focus-tabindex-order-shadow-negative.html": [ [ "shadow-dom/focus/focus-tabindex-order-shadow-negative.html", @@ -306855,6 +307397,23 @@ {} ] ], + "webxr/ar-module/idlharness.https.window.js": [ + [ + "webxr/ar-module/idlharness.https.window.html", + { + "script_metadata": [ + [ + "script", + "/resources/WebIDLParser.js" + ], + [ + "script", + "/resources/idlharness.js" + ] + ] + } + ] + ], "webxr/events_input_source_recreation.https.html": [ [ "webxr/events_input_source_recreation.https.html", @@ -306891,6 +307450,23 @@ {} ] ], + "webxr/gamepads-module/idlharness.https.window.js": [ + [ + "webxr/gamepads-module/idlharness.https.window.html", + { + "script_metadata": [ + [ + "script", + "/resources/WebIDLParser.js" + ], + [ + "script", + "/resources/idlharness.js" + ] + ] + } + ] + ], "webxr/getInputPose_handedness.https.html": [ [ "webxr/getInputPose_handedness.https.html", @@ -321931,7 +322507,7 @@ "testharness" ], "2dcontext/imagebitmap/createImageBitmap-invalid-args.html": [ - "004b3ca6bf39eb7613d2621c8a431df5ab52278b", + "c64371eaa8c7940a78ff064b5cffac575607d230", "testharness" ], "2dcontext/imagebitmap/createImageBitmap-origin.sub.html": [ @@ -324259,15 +324835,15 @@ "testharness" ], "IndexedDB/fire-error-event-exception.html": [ - "fe0dc182567af2a48b4be82d809b97baf469fb3e", + "0a3f12265894f03adfb2b6577e5d35dbf0c89c5d", "testharness" ], "IndexedDB/fire-success-event-exception.html": [ - "c4e55066bbab9069e744c089f81df0714ad4db19", + "ab0ac44eb7c33ba5f62caa6dca49935c8296cf26", "testharness" ], "IndexedDB/fire-upgradeneeded-event-exception.html": [ - "5db452ebafe68a095f083b65a713ba3e0ad40cf5", + "1a8163a58b15606e2f00bc6439238c03267ce83b", "testharness" ], "IndexedDB/get-databases.any.js": [ @@ -325663,7 +326239,7 @@ "testharness" ], "IndexedDB/transaction-relaxed-durability.tentative.any.js": [ - "c6a6f37ba9e0b29dc17fe66e487920acf2c4ecc6", + "2ba96ec08edd3e35c85bef4712a94a9a75174624", "testharness" ], "IndexedDB/transaction-requestqueue.htm": [ @@ -337290,6 +337866,14 @@ "91adbfce2d32ec1f46853b4af60b14c74468a842", "reftest" ], + "css/CSS2/floats/new-fc-beside-float-with-margin-rtl.html": [ + "5a564f7831c9c19ff7c464c676981c62a53c9a88", + "reftest" + ], + "css/CSS2/floats/new-fc-beside-float-with-margin.html": [ + "ead8e548be95df87220881a8e66e5f3a47c93f9b", + "reftest" + ], "css/CSS2/floats/new-fc-relayout.html": [ "97d8b9a2ff1f3be8aeab2c26817e7542511c59cb", "reftest" @@ -337338,8 +337922,8 @@ "4ac426fe6bee576a9a54c2ed2143c7829e901f23", "testharness" ], - "css/CSS2/floats/zero-width-floats-positioning.html": [ - "7f8e34daaef68356aa7b9fc4216cf918d93cc6cf", + "css/CSS2/floats/zero-width-floats-positioning.tentative.html": [ + "18f8f6e2046693faf5b46e107a2dd3fa3aca8558", "reftest" ], "css/CSS2/floats/zero-width-floats.html": [ @@ -349779,7 +350363,7 @@ "testharness" ], "css/css-animations/parsing/animation-delay-invalid.html": [ - "a58d2cd11bc572d3a7899fb70b8b04adbd76a713", + "52e42a2e2b67a0593f264b57d99b6e9034a835a3", "testharness" ], "css/css-animations/parsing/animation-delay-valid.html": [ @@ -349791,7 +350375,7 @@ "testharness" ], "css/css-animations/parsing/animation-direction-invalid.html": [ - "0b48d97f0a1bb670daec7335049aa486810a2cde", + "5c96216d045c665f2005feb2cae642aad5d7f6f6", "testharness" ], "css/css-animations/parsing/animation-direction-valid.html": [ @@ -349803,7 +350387,7 @@ "testharness" ], "css/css-animations/parsing/animation-duration-invalid.html": [ - "5edacd3735e4f3ac0c0724415b3ca0052f10d33b", + "bd8cf2adfe98954d43f3e4d3b7f839d6f59b0e96", "testharness" ], "css/css-animations/parsing/animation-duration-valid.html": [ @@ -349815,19 +350399,23 @@ "testharness" ], "css/css-animations/parsing/animation-fill-mode-invalid.html": [ - "dda2221f4746a64778ea4c5a82fa42c35243a342", + "2a82f2354639feb9abbba32b7159a0de1f1a18c4", "testharness" ], "css/css-animations/parsing/animation-fill-mode-valid.html": [ "1f73a821d15119d6a8fc2720d53f6cefdd29fb5d", "testharness" ], + "css/css-animations/parsing/animation-invalid.html": [ + "c5790a3fafa4cbdb73126c98596506e3ed796310", + "testharness" + ], "css/css-animations/parsing/animation-iteration-count-computed.html": [ "0ac53aa65184020b65669807c699ef6c55362af2", "testharness" ], "css/css-animations/parsing/animation-iteration-count-invalid.html": [ - "ff1e8e23a08cf58c08922eb40145e916852c0562", + "621340f7c3d87b7edb19a3db94e9dc759014d7c8", "testharness" ], "css/css-animations/parsing/animation-iteration-count-valid.html": [ @@ -349859,25 +350447,33 @@ "testharness" ], "css/css-animations/parsing/animation-play-state-invalid.html": [ - "f47a2f75ddfc35a279037ada8df34077bd1308ab", + "91a6f017370a7cf6089d610e2666f64c61a8c98f", "testharness" ], "css/css-animations/parsing/animation-play-state-valid.html": [ "ce6d053ec2736ec8d5e8420b3d1a1e4f07fd04ed", "testharness" ], + "css/css-animations/parsing/animation-shorthand.html": [ + "2e3053e7afcc6eaa7cd2b3912b37b80295ea426d", + "testharness" + ], "css/css-animations/parsing/animation-timing-function-computed.html": [ "99bc12ccaa8f24ae5db06cfd0d78d3bd0c015bef", "testharness" ], "css/css-animations/parsing/animation-timing-function-invalid.html": [ - "adc1cc10e39d09df78c4398ffca008739d751076", + "621145b0e004c583d4a0131eb10d4875fe17da3b", "testharness" ], "css/css-animations/parsing/animation-timing-function-valid.html": [ "7ab823ea1da1535606ac4aad30fb21f423ba6703", "testharness" ], + "css/css-animations/parsing/animation-valid.html": [ + "65de3c6fcfed3f69fa798fa19425bdc054e0700b", + "testharness" + ], "css/css-animations/pending-style-changes-001.html": [ "fb74d7fa7d062d60153d47913df9eb2b0c7267c8", "testharness" @@ -349926,8 +350522,12 @@ "3e7843b8a07577970279ef9a4e14bfb83c1816f0", "testharness" ], + "css/css-backgrounds/animations/border-image-outset-interpolation-expected.txt": [ + "6ca6cb7701110980a1adbf8f5e1cde9edda2cba6", + "support" + ], "css/css-backgrounds/animations/border-image-outset-interpolation.html": [ - "d4726e87d119462a703cc7ac504e8025f3874680", + "aebadbbafb236a090aa543ecf82e5661bee7de74", "testharness" ], "css/css-backgrounds/animations/border-image-slice-interpolation.html": [ @@ -352786,10 +353386,6 @@ "51c67b96ccb52ac09ef6d78e598506317ff784ab", "testharness" ], - "css/css-backgrounds/parsing/background-invalid-expected.txt": [ - "4e890e2d1a745f42c8feed70f21e1be0d617182f", - "support" - ], "css/css-backgrounds/parsing/background-invalid.html": [ "76ff18f35d1f7471f165c61d731f8838a8563059", "testharness" @@ -352959,7 +353555,7 @@ "testharness" ], "css/css-backgrounds/parsing/border-image-width-computed.html": [ - "98e5616a22847c0536b25d8a96393aafa9c0a913", + "2c36eda8c785337eae8f3f3eefb2bf92e29b82a0", "testharness" ], "css/css-backgrounds/parsing/border-image-width-invalid.html": [ @@ -353726,6 +354322,10 @@ "77009170938d9634497f73bc21501ced502c7008", "testharness" ], + "css/css-box/parsing/margin-shorthand.html": [ + "293927983e504a3227335944ab05f966d51cccd6", + "testharness" + ], "css/css-box/parsing/margin-valid.html": [ "154aa2de7cb16ca0845f8368e731ec5c941108cb", "testharness" @@ -353786,6 +354386,10 @@ "3e3a560c2f71877494577f9dbc5c2eecfbab8a62", "testharness" ], + "css/css-box/parsing/padding-shorthand.html": [ + "dc0139dc47a70688cd8667e6069b4ba5654b7b1c", + "testharness" + ], "css/css-box/parsing/padding-valid.html": [ "0d3d51e86bb015dd5720041cdae671a29a74c77b", "testharness" @@ -354034,6 +354638,14 @@ "f68b7c046d9d22994dbc78c722b5004f1253027f", "reftest" ], + "css/css-cascade/all-prop-initial-visited-ref.html": [ + "f596b559b0e26b9c03d47b7dcab966a4d091308b", + "support" + ], + "css/css-cascade/all-prop-initial-visited.html": [ + "6fb7936652a77dade7d5e72032064b67d2886637", + "reftest" + ], "css/css-cascade/all-prop-initial-xml.html": [ "a04956a52d1f120583c26a462356ba8e47ac1277", "testharness" @@ -356218,6 +356830,14 @@ "a78e9f713b2428763ed4244aae1b6269a15d6637", "reftest" ], + "css/css-content/inheritance-expected.txt": [ + "a75fca4057ea2537d7cfdae56699339451ba0109", + "support" + ], + "css/css-content/inheritance.html": [ + "a3242556fdcb4d5fea0d4d28fba6067ed02b340c", + "testharness" + ], "css/css-content/pseudo-element-inline-box-ref.html": [ "8294ae672d15643b1d8eeb8c9914fa93fe4e879a", "support" @@ -359898,6 +360518,10 @@ "e82c284632dd5b3babbd3979958874013bf3b9aa", "testharness" ], + "css/css-flexbox/parsing/flex-flow-shorthand.html": [ + "6ae19bdc044dd31b11448e407204accfb0340632", + "testharness" + ], "css/css-flexbox/parsing/flex-flow-valid.html": [ "01acd435096db60d214a0b07cb24fccdfded9c93", "testharness" @@ -359918,6 +360542,10 @@ "ae010d7b4b4540f6591c1ad42f1c89753a71afc6", "testharness" ], + "css/css-flexbox/parsing/flex-shorthand.html": [ + "51e01794154edbe475e57d2ca6fb93de65dea8bd", + "testharness" + ], "css/css-flexbox/parsing/flex-shrink-computed.html": [ "69a6d8c52b61f162f9c7333f53ed44145e51913f", "testharness" @@ -359975,7 +360603,7 @@ "reftest" ], "css/css-flexbox/percentage-heights-003.html": [ - "9d434cf7cb8ba2023c126391032985d3d3b7c5d9", + "c27af532169a349be42379ab9949afec15b47ae2", "testharness" ], "css/css-flexbox/percentage-heights-004-ref.html": [ @@ -370538,6 +371166,10 @@ "b36fbb2bbc8ce403632769e1a098f9560e910221", "reftest" ], + "css/css-grid/grid-items/grid-item-dynamic-min-contribution-001.html": [ + "c4ced6b2a12e0f080d6df2fccc8f74270f45683c", + "testharness" + ], "css/css-grid/grid-items/grid-item-min-auto-size-001.html": [ "f50e9ef312418f4d3b737bd55b4a7e5c75f09230", "testharness" @@ -370646,6 +371278,54 @@ "e45530b2fd4a380ba62c3b42ba52157cec098a00", "testharness" ], + "css/css-grid/grid-items/grid-items-percentage-margins-003.html": [ + "03d5d7f2c499b00cda96b8235a11852998900259", + "reftest" + ], + "css/css-grid/grid-items/grid-items-percentage-margins-004.html": [ + "52e6f3bf1a688af98bd28d68f8d7e0ddde3ebee5", + "reftest" + ], + "css/css-grid/grid-items/grid-items-percentage-margins-005.html": [ + "9cff92d1aa0ccdf2aa2dd0c89b4bd626778d1214", + "reftest" + ], + "css/css-grid/grid-items/grid-items-percentage-margins-006.html": [ + "04d30e3edfc9920fb22f645549b00497ba0241fb", + "reftest" + ], + "css/css-grid/grid-items/grid-items-percentage-margins-007.html": [ + "2906fe0608704a1b8413fa7a24db140667254283", + "reftest" + ], + "css/css-grid/grid-items/grid-items-percentage-margins-008.html": [ + "7bd2e0fc5f4f24b35ff37c61c0b20c1b2ab61571", + "reftest" + ], + "css/css-grid/grid-items/grid-items-percentage-margins-009.html": [ + "70a6c231dc91b1b2f866e9cd4463860ce9f58c4f", + "reftest" + ], + "css/css-grid/grid-items/grid-items-percentage-margins-010.html": [ + "34352f60020ec44e4d5f27344818bdb476de694e", + "reftest" + ], + "css/css-grid/grid-items/grid-items-percentage-margins-011.html": [ + "36bd208df007332656acbb4b3ffb5aac86675c82", + "reftest" + ], + "css/css-grid/grid-items/grid-items-percentage-margins-012.html": [ + "9cdc15337a936724b8ce157638544f4f9e35b65c", + "reftest" + ], + "css/css-grid/grid-items/grid-items-percentage-margins-013.html": [ + "581415b828e6d54056fe94e5145e276e7e428352", + "reftest" + ], + "css/css-grid/grid-items/grid-items-percentage-margins-014.html": [ + "5766e60339a0d83568c93a7f750976dbb9955e6a", + "reftest" + ], "css/css-grid/grid-items/grid-items-percentage-margins-vertical-lr-001.html": [ "aa0ff96985878c5f21d7e7a8175b1351e9841656", "testharness" @@ -370670,6 +371350,54 @@ "3175469fb08361398658ebcfabb553909aa9c080", "testharness" ], + "css/css-grid/grid-items/grid-items-percentage-paddings-003.html": [ + "d85a6c1abcfac6c2ecf6bfc1251ba41b58fbab89", + "reftest" + ], + "css/css-grid/grid-items/grid-items-percentage-paddings-004.html": [ + "26302daf2d606637930ea41971f3d6066f782a2b", + "reftest" + ], + "css/css-grid/grid-items/grid-items-percentage-paddings-005.html": [ + "151b604f9bb7c7defdb5edf558ed207777cc0903", + "reftest" + ], + "css/css-grid/grid-items/grid-items-percentage-paddings-006.html": [ + "bcbc7ced73a77ebfb1e2aa027383f868bf38fe87", + "reftest" + ], + "css/css-grid/grid-items/grid-items-percentage-paddings-007.html": [ + "d4cf80c18df05bf06406eccf8aefe7050ed4025f", + "reftest" + ], + "css/css-grid/grid-items/grid-items-percentage-paddings-008.html": [ + "38f766b5cfffcca21906203c8c3472dd1230b197", + "reftest" + ], + "css/css-grid/grid-items/grid-items-percentage-paddings-009.html": [ + "eb1d1f47f28c3daefd78e9e98881459f91c2046d", + "reftest" + ], + "css/css-grid/grid-items/grid-items-percentage-paddings-010.html": [ + "ecd430c68d41698b328341eb9d9e2daba2a7848c", + "reftest" + ], + "css/css-grid/grid-items/grid-items-percentage-paddings-011.html": [ + "e394ced4e6e52f3379428d3ad854bcab0b3cb38d", + "reftest" + ], + "css/css-grid/grid-items/grid-items-percentage-paddings-012.html": [ + "07b2d27b58173a84851c4836c85281efa818c2e4", + "reftest" + ], + "css/css-grid/grid-items/grid-items-percentage-paddings-013.html": [ + "9b6c2bfe0ad261358ff7657752bd3bc3dff0896d", + "reftest" + ], + "css/css-grid/grid-items/grid-items-percentage-paddings-014.html": [ + "9e67960913a25f0fe1cfe137ceca5d11ebf0b43f", + "reftest" + ], "css/css-grid/grid-items/grid-items-percentage-paddings-vertical-lr-001.html": [ "6ad624a0a262067eb6e3b0724989ab01ca04f6a1", "testharness" @@ -371290,6 +372018,10 @@ "b989322775eb7dbf273a3dc3fbb3d1af31f524ba", "testharness" ], + "css/css-grid/parsing/grid-area-shorthand.html": [ + "9a265502d5c0dfd1b2ebb7ed54b81514216af826", + "testharness" + ], "css/css-grid/parsing/grid-area-valid.html": [ "8e7d0d43d1cfac44935593892b67fdb40b179791", "testharness" @@ -371299,7 +372031,7 @@ "testharness" ], "css/css-grid/parsing/grid-auto-columns-invalid.html": [ - "40b6059a7e8b564a4aef5393a7be77cbaa1ff4a2", + "04e0fadf0df2824a499bede7f2fe80e410a29e1a", "testharness" ], "css/css-grid/parsing/grid-auto-columns-valid.html": [ @@ -371331,7 +372063,7 @@ "testharness" ], "css/css-grid/parsing/grid-auto-rows-invalid.html": [ - "4111e2563365579b3810c701a782df54dce3c61e", + "1b61479f3c2f51c23a3be59a7d90b179de1407ca", "testharness" ], "css/css-grid/parsing/grid-auto-rows-valid.html": [ @@ -371355,7 +372087,7 @@ "testharness" ], "css/css-grid/parsing/grid-template-columns-valid.html": [ - "85ac76a999aab5adf628a8e38f626fcae299d12f", + "6bf2e7bce63c88d028f5dea1bf3e7be8cab7775c", "testharness" ], "css/css-grid/parsing/grid-template-rows-invalid.html": [ @@ -371363,7 +372095,11 @@ "testharness" ], "css/css-grid/parsing/grid-template-rows-valid.html": [ - "ec8d64f79bacc1d7831e415768c2a76bf05607e0", + "2d3a1ed8045c3eef9982cffc3f95415518f560cb", + "testharness" + ], + "css/css-grid/parsing/grid-template-shorthand.html": [ + "b9165359a7250afab60463878b9beb8592424f58", "testharness" ], "css/css-grid/placement/grid-auto-placement-implicit-tracks-001.html": [ @@ -373270,6 +374006,10 @@ "ff0c8366bb988fafe72746837a330801ae2fe34b", "testharness" ], + "css/css-lists/parsing/list-style-shorthand.sub.html": [ + "140df208aab9e8c7811de14bd96b99bad7d89752", + "testharness" + ], "css/css-lists/parsing/list-style-type-computed-expected.txt": [ "eabf33a193d5bbb194bcaa708f13b2f2e474d216", "support" @@ -373594,6 +374334,10 @@ "604b801c76040a5058612fd19c75ee66107081ed", "testharness" ], + "css/css-logical/parsing/inset-shorthand.html": [ + "4557879129e006980d2775658aadece56458ba35", + "testharness" + ], "css/css-logical/parsing/inset-valid.html": [ "2d8f937f075b0d0fbde677e15266f47af5fec3f8", "testharness" @@ -379735,7 +380479,7 @@ "testharness" ], "css/css-scroll-snap/scroll-margin.html": [ - "c85232edf23876a1ab37d858c4d59940b183e01e", + "e6ce4ac49c01ff65823fd83ee6866a6019701f6e", "testharness" ], "css/css-scroll-snap/scroll-padding.html": [ @@ -383078,6 +383822,10 @@ "3dd2d0c834ec8c7340b093a4c7a1272fb35a8a26", "testharness" ], + "css/css-text-decor/parsing/text-decoration-shorthand.html": [ + "904313f0528de50541d88b3db89902bdbf721cfe", + "testharness" + ], "css/css-text-decor/parsing/text-decoration-skip-ink-computed.html": [ "0b4807cec08a818c07a3d3bcaefc2092ecca9c14", "testharness" @@ -395346,6 +396094,10 @@ "8d0360a8ecf7a37b81acb10917b63abc7c9543cc", "testharness" ], + "css/css-transitions/idlharness-expected.txt": [ + "3c9dbb02792fda31a8d3d92cda284d39e8876fa4", + "support" + ], "css/css-transitions/idlharness.html": [ "4cc7ee50eb4915fcf95843f7eeee266abfa7b81a", "testharness" @@ -395379,7 +396131,7 @@ "testharness" ], "css/css-transitions/parsing/transition-delay-invalid.html": [ - "b34d50551ce433ebe672c7fddb4a549582c754db", + "4b7a14328601ebf6f38e016d5844744bac1a3839", "testharness" ], "css/css-transitions/parsing/transition-delay-valid.html": [ @@ -395391,35 +396143,51 @@ "testharness" ], "css/css-transitions/parsing/transition-duration-invalid.html": [ - "fd0f341f4071b53561cf8b072bb105d3bd1a4563", + "4474089bbb0f89fdfc83a8436c7d5926e046256f", "testharness" ], "css/css-transitions/parsing/transition-duration-valid.html": [ "311ca086695151747559a0995b61c7fe4c755592", "testharness" ], + "css/css-transitions/parsing/transition-invalid.html": [ + "64310b13a15e982402e1d8c3b3d6daad5be67676", + "testharness" + ], "css/css-transitions/parsing/transition-property-computed.html": [ "1e8cfeb22ddfbba2225494e16fdb0b27732a3ed0", "testharness" ], "css/css-transitions/parsing/transition-property-invalid.html": [ - "903a206eac13688a51ff2ba88552de67efa2e9cb", + "715e13d7a249d8762350070c7c47aa8043297b54", "testharness" ], "css/css-transitions/parsing/transition-property-valid.html": [ "4e3894f5aa94e00aa59406ee1aab92b9226483af", "testharness" ], + "css/css-transitions/parsing/transition-shorthand.html": [ + "caffb3978cf0162cb8616c6723c6cb93e33750b4", + "testharness" + ], "css/css-transitions/parsing/transition-timing-function-computed.html": [ - "9834dfdbf0dde78d0d2c1b468c5badddc2460ac9", + "fa03b2295b9c2f92ab4e520cc75153d9eaa6e672", "testharness" ], "css/css-transitions/parsing/transition-timing-function-invalid.html": [ - "00bd2131e0927ba38e633ad7be404b8ec26e51a9", + "c69b7e75d3d3ef31df4f6ec927b8fbf2032484d6", "testharness" ], + "css/css-transitions/parsing/transition-timing-function-valid-expected.txt": [ + "0d8cfd02f6de0911b4d3437540aabb51aa41c606", + "support" + ], "css/css-transitions/parsing/transition-timing-function-valid.html": [ - "2e2c1827bfbef9d4cc58e32ec88da3c7fd614225", + "5402fdac195b2dc2d68553d593e1924f5c3be695", + "testharness" + ], + "css/css-transitions/parsing/transition-valid.html": [ + "c4651f5f125f40c0ec75f6d58b2641fa78b47cf0", "testharness" ], "css/css-transitions/properties-value-001-expected.txt": [ @@ -395714,36 +396482,36 @@ "9a74bebfb7a45765cac3693b1461953ea75cef92", "testharness" ], - "css/css-transitions/transition-delay-000.html": [ - "2b4cedbb52405903e367ea6ca7a39dcca3b167b6", + "css/css-transitions/transition-delay-000-manual.html": [ + "b205085997ced154dd81e5085dbc6a0cfce19045", "manual" ], "css/css-transitions/transition-delay-001.html": [ "921525ea72d2e1e28d2321c1594085deaf2330f0", "testharness" ], - "css/css-transitions/transition-delay-002.html": [ - "70e952b308c35affc5f7bdfbc66326df49ba6397", + "css/css-transitions/transition-delay-002-manual.html": [ + "168f94b9c054b481df7ccea0c5e07b8643715c8c", "manual" ], - "css/css-transitions/transition-delay-003.html": [ - "3062e9a4842dcb5ecfd3b59c26260b412cd3b573", + "css/css-transitions/transition-delay-003-manual.html": [ + "e3680ca2615ab3d490467101c047a42153a46d61", "manual" ], "css/css-transitions/transition-duration-001.html": [ "b5c095f001efb373934850db67527ace118e10cd", "testharness" ], - "css/css-transitions/transition-duration-002.html": [ - "e9ba5760c605e28e698411f73f3280cc453b9637", + "css/css-transitions/transition-duration-002-manual.html": [ + "03f514d365d165d777e43f83142e801f4f9833d9", "manual" ], - "css/css-transitions/transition-duration-003.html": [ - "bb68b5f51c1a5c6dc84de7499599472bc286ad39", + "css/css-transitions/transition-duration-003-manual.html": [ + "cb561008836236752f0ed37ad68159481e71596f", "manual" ], - "css/css-transitions/transition-duration-004.html": [ - "01c42473319d90130f9aec5df39a28a287aff7ed", + "css/css-transitions/transition-duration-004-manual.html": [ + "b93904bb7667b7c5afa7f9fdcd3dad524e2f9f41", "manual" ], "css/css-transitions/transition-property-001.html": [ @@ -395758,176 +396526,176 @@ "99196b6d1d4ec86be77930d578602110b6a7deb6", "testharness" ], - "css/css-transitions/transition-property-003.html": [ - "17668b053e83e102565e341dd337ffc2b4544cf4", + "css/css-transitions/transition-property-003-manual.html": [ + "291204d5752e5fcb9c7b8fb8ef32a95d7d4b1813", "manual" ], - "css/css-transitions/transition-property-004.html": [ - "6393c6e3d54f59e8ae9cde42eda248d0c891f68d", + "css/css-transitions/transition-property-004-manual.html": [ + "d2e84c99d69003d46c439ce6c623594390701a2a", "manual" ], - "css/css-transitions/transition-property-005.html": [ - "a10ff4a3c1acd4cf31d18bc510f228ed416085ae", + "css/css-transitions/transition-property-005-manual.html": [ + "e69941001bca8c441cdb66aaf4582d7e3c336afc", "manual" ], - "css/css-transitions/transition-property-006.html": [ - "e7d8c5e39462d526b4ee60f97046fe14f5e904a1", + "css/css-transitions/transition-property-006-manual.html": [ + "6032a401d0cfea4a717a3c07ebaca841857aef72", "manual" ], - "css/css-transitions/transition-property-007.html": [ - "0d006fe9b0b1101a03528aa085ceda850deb621c", + "css/css-transitions/transition-property-007-manual.html": [ + "898aea5b2079caa0d66a94b673feb8e42ee69dfc", "manual" ], - "css/css-transitions/transition-property-008.html": [ - "47ca1eee1053ca272eb72f3b6e5eaaa1a9343807", + "css/css-transitions/transition-property-008-manual.html": [ + "53caa1028a47fafec6b2d07a3aa58e7c709cd2d8", "manual" ], - "css/css-transitions/transition-property-009.html": [ - "b45948b9dd6040af8dd3f2e7dfdcec1c6002cd58", + "css/css-transitions/transition-property-009-manual.html": [ + "5f272854eb2e3f3ebf1dcd8f5130ef100218ec28", "manual" ], - "css/css-transitions/transition-property-010.html": [ - "f05f6aa133e2852aa75b7fa43dc3637964ad1741", + "css/css-transitions/transition-property-010-manual.html": [ + "a7e06ef78072f6ea6944e35495e1be70b232c499", "manual" ], - "css/css-transitions/transition-property-011.html": [ - "7b3716dde8adfc3cab36d38115a83702388808d8", + "css/css-transitions/transition-property-011-manual.html": [ + "3799ad212aebddb60c3f1818129e7a4d71e5bfb7", "manual" ], - "css/css-transitions/transition-property-012.html": [ - "0e19e52d62abcfd5d4f3852000ce99634a860b3d", + "css/css-transitions/transition-property-012-manual.html": [ + "8587e264119c455f1d7bb8d882c3a290e3248124", "manual" ], - "css/css-transitions/transition-property-013.html": [ - "9fb075b09d2b0f04556916cbb4afcbf29e0a021b", + "css/css-transitions/transition-property-013-manual.html": [ + "3b13c038161e1a2037f838c8133330425a42e700", "manual" ], - "css/css-transitions/transition-property-014.html": [ - "91075ff638f32d1b6f958019c7862fdf171f0475", + "css/css-transitions/transition-property-014-manual.html": [ + "d4aca3805b3b983bc1e3363abd8ba5b33ea71ef7", "manual" ], - "css/css-transitions/transition-property-015.html": [ - "b37d4fc9a7beae894eb63fb98aa3fe9d6dcc039f", + "css/css-transitions/transition-property-015-manual.html": [ + "e5805bc4ba6882394c1b45932ce97eaab71afc43", "manual" ], - "css/css-transitions/transition-property-016.html": [ - "2670cd7385222e0959553c376193ea94e76ade39", + "css/css-transitions/transition-property-016-manual.html": [ + "d2cc57cd9796d819aa914dcad7ff0525266cb64e", "manual" ], - "css/css-transitions/transition-property-017.html": [ - "3b94ecde0c51b82d4650834181c25718576fd327", + "css/css-transitions/transition-property-017-manual.html": [ + "f24c51a7383b76c2dd56db5e1d69eb6c3808cc0c", "manual" ], - "css/css-transitions/transition-property-018.html": [ - "593e3ff71944fde48c84ae99191242a9078ea5ee", + "css/css-transitions/transition-property-018-manual.html": [ + "e0b6bd955b5e2b65b131d21f5ea5a646c00afed0", "manual" ], - "css/css-transitions/transition-property-019.html": [ - "83f900005469647bd05cf7080e41fd59c1b641ef", + "css/css-transitions/transition-property-019-manual.html": [ + "24751292c2886a761e90ed009543768747ffff29", "manual" ], - "css/css-transitions/transition-property-020.html": [ - "af0aea41bcd4615825a961778ab499f61a718f8a", + "css/css-transitions/transition-property-020-manual.html": [ + "e4f7b577920f321453e5a25aadc1d814c4e3ac91", "manual" ], - "css/css-transitions/transition-property-021.html": [ - "f499c9aee43f50bb0a74acfba1fa412976a994ad", + "css/css-transitions/transition-property-021-manual.html": [ + "c0492223bbf6043cd5b93f9290640bceaf53f338", "manual" ], - "css/css-transitions/transition-property-022.html": [ - "f36954902e3667eb305340075d5952344cc62bbd", + "css/css-transitions/transition-property-022-manual.html": [ + "ece1a32eb09ee3baf7f38ca39da5530774af81c8", "manual" ], - "css/css-transitions/transition-property-023.html": [ - "81c8cadac422bcbb48b88a053ae0df564a0a0242", + "css/css-transitions/transition-property-023-manual.html": [ + "267be61aa1560646ffcb12693f4783942242a51c", "manual" ], - "css/css-transitions/transition-property-024.html": [ - "b0e9d41dbc0dd0628adf9894fb6811f559efa45a", + "css/css-transitions/transition-property-024-manual.html": [ + "fad3d7ac239ceb28f26d6ae40a2eff88af7690aa", "manual" ], - "css/css-transitions/transition-property-025.html": [ - "bfa6f698930d13412d6c19a424aefb2c566c27a7", + "css/css-transitions/transition-property-025-manual.html": [ + "c0f276184894a29f1abd5eb46322f6b0a4a5ffe5", "manual" ], - "css/css-transitions/transition-property-026.html": [ - "d6f0481bea7ad1b54ba2d44efd62513ec834b221", + "css/css-transitions/transition-property-026-manual.html": [ + "35846e3fb5334cf049f1031e6c542e46105ba5f8", "manual" ], - "css/css-transitions/transition-property-027.html": [ - "01f50dc475ab5fd3ad0f7094d7efa1db0ad362b9", + "css/css-transitions/transition-property-027-manual.html": [ + "5ad5f5d5bd5187593a421b261758227e464f5204", "manual" ], - "css/css-transitions/transition-property-028.html": [ - "83d8751109b1e29e76aaa98fedce03f205b68a63", + "css/css-transitions/transition-property-028-manual.html": [ + "be319d2c21204d6ba6bbdb1e6be454782a49203a", "manual" ], - "css/css-transitions/transition-property-029.html": [ - "fb435c91249d691862b24a63f5f5b9c35166afb8", + "css/css-transitions/transition-property-029-manual.html": [ + "84c55326fe8ab2c5f3b20d07939a15de60ba42d0", "manual" ], - "css/css-transitions/transition-property-030.html": [ - "286af42e12cc2c8249d1bc1e2ca14f3aedba0293", + "css/css-transitions/transition-property-030-manual.html": [ + "ba75f7ce725f320cf4d478273adfa22e47f5ff6a", "manual" ], - "css/css-transitions/transition-property-031.html": [ - "d5bf23276f7e594f77f86f9b292fe134a57aabed", + "css/css-transitions/transition-property-031-manual.html": [ + "14cf23c6bdc649f09862f2a573008171177a882f", "manual" ], - "css/css-transitions/transition-property-032.html": [ - "020a8573c8729efeb49e1bde33d7942c8f89f70f", + "css/css-transitions/transition-property-032-manual.html": [ + "c6596608ed13fd93ce60c1ca5d05f5dabd8e6157", "manual" ], - "css/css-transitions/transition-property-033.html": [ - "fcb999fa079be9df7569e57af8019d93b8b9905b", + "css/css-transitions/transition-property-033-manual.html": [ + "fd7646c66bc47827794ebd0792b7586216dbe2af", "manual" ], - "css/css-transitions/transition-property-034.html": [ - "b4da3a9bca07ba24040e1723baa4662c1d83af95", + "css/css-transitions/transition-property-034-manual.html": [ + "07804121c9c862b4bcc2e1babf9c65c17d71e206", "manual" ], - "css/css-transitions/transition-property-035.html": [ - "27c9ea9e1d8e8721224bd3bbe46405dffbcab90f", + "css/css-transitions/transition-property-035-manual.html": [ + "4a9e9b128fd5402c97bb64fdbaaa1706814c18c5", "manual" ], - "css/css-transitions/transition-property-036.html": [ - "326e615398c5905e92bdacec50b22effa23b3572", + "css/css-transitions/transition-property-036-manual.html": [ + "746bc409ee0e92d6e0588079dff63e4a0e89a68d", "manual" ], - "css/css-transitions/transition-property-037.html": [ - "79ce16fb961c9f3bfceda7bf996afb7aef05381f", + "css/css-transitions/transition-property-037-manual.html": [ + "d031caaaa405fcf57b44890ee97159f28d88fc42", "manual" ], - "css/css-transitions/transition-property-038.html": [ - "5b16e41f578b70217b2ca1b406fb1a9d1f571248", + "css/css-transitions/transition-property-038-manual.html": [ + "2f9302bad7593a24a6617a91d388202afed979ef", "manual" ], - "css/css-transitions/transition-property-039.html": [ - "0ef6da528cb81c746c799ec2fb84c0c6f0f1d872", + "css/css-transitions/transition-property-039-manual.html": [ + "bf0b209bdad43712bb42fdf41d14328b4d4ac5f8", "manual" ], - "css/css-transitions/transition-property-040.html": [ - "b333f371f3f974467c745d4cbfa4165077c1aa61", + "css/css-transitions/transition-property-040-manual.html": [ + "83a3cf802b3e00fc717d01de51f8824a15af71ed", "manual" ], - "css/css-transitions/transition-property-041.html": [ - "b3386a0534f190d15e5251c31e59c05a779dc4af", + "css/css-transitions/transition-property-041-manual.html": [ + "04f8351a0309f5b4e10c610a6c07325944492220", "manual" ], - "css/css-transitions/transition-property-042.html": [ - "fbb3e2d8b1ad7208b40d669e70b5f41e75601c6a", + "css/css-transitions/transition-property-042-manual.html": [ + "15977497fbb81be0a86f24ce52a7e6359e18bf98", "manual" ], - "css/css-transitions/transition-property-043.html": [ - "b87dc84a85636d4c1cc32a4a2716b33ecf28b370", + "css/css-transitions/transition-property-043-manual.html": [ + "3b939bcf0ab8d5800ac2e0088da0774f56e28028", "manual" ], - "css/css-transitions/transition-property-044.html": [ - "f1d584fcf25396db414078066302ce2f7bb979f2", + "css/css-transitions/transition-property-044-manual.html": [ + "d7c2f467492d9e234467956e3409b9665cee9e9d", "manual" ], - "css/css-transitions/transition-property-045.html": [ - "3fa82c16d1f9e7f01760003c07bdfbc38afa060d", + "css/css-transitions/transition-property-045-manual.html": [ + "912ed4df50ccc545c0a7c77f4cc43c0b75104c4a", "manual" ], "css/css-transitions/transition-reparented.html": [ @@ -395938,56 +396706,28 @@ "10700abf9bc48d0938fd3f5b77b031ecc0c05e4a", "reftest" ], - "css/css-transitions/transition-timing-function-001.html": [ - "4c9598f3919b84dc79d7c92c76b74b7f950423aa", - "testharness" - ], - "css/css-transitions/transition-timing-function-002.html": [ - "527eb9e85ad4dc4944b39e83c1a0d79b8f515ddb", + "css/css-transitions/transition-timing-function-002-manual.html": [ + "abd729bdedeff531c08279f1b4c4a7399b69d0c2", "manual" ], - "css/css-transitions/transition-timing-function-003.html": [ - "353b94e7eca1e3f837d5c0e0ec02c1c0167b19a3", + "css/css-transitions/transition-timing-function-003-manual.html": [ + "9fee35a972ed2f1790dd6c58140e92248044bfa7", "manual" ], - "css/css-transitions/transition-timing-function-004.html": [ - "0601b4bd148a113ef0f5e0b5f6b3c33cf40c38b5", + "css/css-transitions/transition-timing-function-004-manual.html": [ + "f57d49aeabb305bfea5281d159382c334f37ac8c", "manual" ], - "css/css-transitions/transition-timing-function-005.html": [ - "eb46ece6044fe5d204b8dde056e655179732ef90", + "css/css-transitions/transition-timing-function-005-manual.html": [ + "27726cd6d5b3bd4bc9532d64e2062318dd019574", "manual" ], - "css/css-transitions/transition-timing-function-006.html": [ - "d8640d9304778f2ad41f56a90ba23486e8d59f34", + "css/css-transitions/transition-timing-function-006-manual.html": [ + "d97e6bb07694d5b19dffba48a3890f0c07f15d03", "manual" ], - "css/css-transitions/transition-timing-function-007.html": [ - "72ffbf6a1302c1858bf7880bfa033793c72b40d1", - "manual" - ], - "css/css-transitions/transition-timing-function-008.html": [ - "2e20f7ee5f2a9ff9602222635a7723850fbd9e51", - "manual" - ], - "css/css-transitions/transition-timing-function-009.html": [ - "a3e2f1a6bd2226a24484899c2a1f3126967989dc", - "manual" - ], - "css/css-transitions/transition-timing-function-010.html": [ - "16af80655189fe64a1be1612910eca3f2aa449d4", - "manual" - ], - "css/css-transitions/transition-timing-function-011.html": [ - "5d0f5a25b25aae82fc73e8a52a419f92350b5e3c", - "manual" - ], - "css/css-transitions/transition-timing-function-012.html": [ - "f3bc812217e4a31153187ab33478f461571e089e", - "manual" - ], - "css/css-transitions/transition-timing-function-013.html": [ - "5d89c45e0245ba4fedcd84905a59e3e8580319a8", + "css/css-transitions/transition-timing-function-010-manual.html": [ + "953d7210b6d725cc668887ff592cc630ced88aec", "manual" ], "css/css-transitions/transitioncancel-001.html": [ @@ -398946,6 +399686,10 @@ "75fc7e60bd9dc3f249b8340cf342b68fa45b7d68", "testharness" ], + "css/css-ui/parsing/outline-shorthand.html": [ + "01239e199e651ff53237c19c4a76a500338e8514", + "testharness" + ], "css/css-ui/parsing/outline-style-computed.html": [ "3824b8d59815b20206a90e428644942ac220c68c", "testharness" @@ -400746,6 +401490,18 @@ "fee5e92a9312f80b6d36966b721d01269f1ad30b", "reftest" ], + "css/css-values/clamp-length-computed.html": [ + "67dc19a99f4d687745f27b7548d44e2795981d42", + "testharness" + ], + "css/css-values/clamp-length-invalid.html": [ + "68c298b7ffc431d58025c0c9c5c2163db3742334", + "testharness" + ], + "css/css-values/clamp-length-serialize.html": [ + "4719e4c0254902bb1c2234c4cfc1c4003a8df0d4", + "testharness" + ], "css/css-values/ex-calc-expression-001-ref.html": [ "888a51ea9b6ac04fb065ee5d84a18be8fe765aca", "support" @@ -400842,6 +401598,10 @@ "73069ecfe1e6d5b198f6e01df48facbe117d6828", "reftest" ], + "css/css-values/min-max-percentage-length-interpolation.html": [ + "14af1352d1740d32cd52ab069ab1799f87803f5d", + "reftest" + ], "css/css-values/minmax-angle-computed.html": [ "84e598a8147e123285d54876f942a0df0a5bf57f", "testharness" @@ -410854,6 +411614,14 @@ "188a65b715291b33d93d8a6af88c2a7f6e25858c", "reftest" ], + "css/mediaqueries/aspect-ratio-serialization-expected.txt": [ + "551aadd174919857cae83cc3b8e5803b271dda2f", + "support" + ], + "css/mediaqueries/aspect-ratio-serialization.html": [ + "cce35592885f29eafd2c5c1b94a0da173217fc2a", + "testharness" + ], "css/mediaqueries/device-aspect-ratio-001.html": [ "60f49b9b3cfedaf8136dcb568570ef71124cba8b", "reftest" @@ -411027,7 +411795,7 @@ "testharness" ], "css/motion/animation/offset-interpolation.html": [ - "04f4d4b3bd78f95939c34aa098b85a7947d4fcbd", + "2ee011bd77a975e9b566d24658995693c574f620", "testharness" ], "css/motion/animation/offset-path-interpolation-001.html": [ @@ -411310,8 +412078,12 @@ "cc2eb500eb88d24055dfe84e0c052546d90e9a29", "testharness" ], + "css/motion/parsing/offset-parsing-valid-expected.txt": [ + "2a043073fa24db4efb3d4de7d5436a830a7be478", + "support" + ], "css/motion/parsing/offset-parsing-valid.html": [ - "3fe8a5b20d805ae3d330b8c653593b6b0c0e0d9e", + "7f8a0fd34c329178e42908edd27858d577cdbad1", "testharness" ], "css/motion/parsing/offset-path-computed-expected.txt": [ @@ -413459,7 +414231,7 @@ "support" ], "css/support/interpolation-testcommon.js": [ - "e7ee011cdb470ee228a8a32442d6a717ef6ffd0a", + "24c47e136c8d98603238a09dbb64bd79cd6751d2", "support" ], "css/support/parsing-testcommon.js": [ @@ -413507,7 +414279,7 @@ "support" ], "css/support/shorthand-testcommon.js": [ - "1fd603c290c14d4672fc8f63f2d964da9867be78", + "3298113513fb1e34311a6e7f34dd2d20cfe0c870", "support" ], "css/support/square-purple.png": [ @@ -417327,7 +418099,7 @@ "reftest" ], "css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/shape-outside-margin-box-border-radius-008-ref.html": [ - "f5edbedfb74e763fdcdc1451d538caeda5c023c0", + "7cf8fafc933623c8a7912e8912a96d2fb178f8b5", "support" ], "css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/shape-outside-margin-box-border-radius-008.html": [ @@ -420082,6 +420854,10 @@ "9f6d871417dcb006380f6e59bd0c0a031fd7e78e", "testharness" ], + "dom/nodes/MutationObserver-sanity.html": [ + "a4f6382b944db4b2734ea54c9990dd4135c52557", + "testharness" + ], "dom/nodes/MutationObserver-takeRecords.html": [ "6a27ef77ecacf55a7eaaae18cdd007e017e42cd9", "testharness" @@ -437095,7 +437871,7 @@ "support" ], "html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window-expected.txt": [ - "d86c1db7d01d34ca2bc784ea7afafcee08508890", + "61e4b6f14a93fb8972cd9794f2323167d0c8bae9", "support" ], "html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js": [ @@ -437810,6 +438586,14 @@ "f66244ab10ffbfeb5ef64ca7564fdd37794288af", "reftest" ], + "html/rendering/non-replaced-elements/tables/table-column-width-ref.html": [ + "1eb7c00d21413292ffb47e956cf341338d6e26ff", + "support" + ], + "html/rendering/non-replaced-elements/tables/table-column-width.html": [ + "6358e14a3926b4f6b97d32832c45c0ef9237f24d", + "reftest" + ], "html/rendering/non-replaced-elements/tables/table-direction-ref.html": [ "2bbd6c04772fd538426d516d2a2d1b301d05ff3f", "support" @@ -439762,6 +440546,10 @@ "911aa7b5c96333f78da5ea315e1ca1b8381dcd74", "testharness" ], + "html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-remove-from-document-different-load.html": [ + "4802665cdda09d7d8763b133aed301d43cdce08d", + "testharness" + ], "html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-remove-from-document-networkState.html": [ "df0985d6fb435c25dce510f924b1470878c5602f", "testharness" @@ -449742,6 +450530,14 @@ "4442d513753112fac2e35855268d0b246f01fa09", "testharness" ], + "infrastructure/expected-fail/unhandled-rejection-expected.txt": [ + "3a828c8d0a58d7faedb6b89ef5e60c57599efad9", + "support" + ], + "infrastructure/expected-fail/unhandled-rejection.html": [ + "f25f6e088fa06fbcd38b62929309e761b0060988", + "testharness" + ], "infrastructure/metadata/infrastructure/assumptions/allowed-to-play.html.ini": [ "c9fbabede6d695cd3795e4390b35da0454ffcc34", "support" @@ -449766,6 +450562,10 @@ "0bcdd374f2521b6534208ab750a1c0d36e7dd7ca", "support" ], + "infrastructure/metadata/infrastructure/expected-fail/unhandled-rejection.html.ini": [ + "39773dfe714a6b5754bfe73c64294bcb38f2afa3", + "support" + ], "infrastructure/metadata/infrastructure/reftest/reftest_and_fail.html.ini": [ "81aef049cd122f7332c66f5a087947e512a59d0e", "support" @@ -450395,7 +451195,7 @@ "support" ], "interfaces/gamepad.idl": [ - "b7497c276f1610139ef14c1cc4d0c34c1f2c406b", + "27541bf2553520dcf7f2ce52386014c9a4363377", "support" ], "interfaces/generic-sensor.idl": [ @@ -450531,7 +451331,7 @@ "support" ], "interfaces/payment-handler.idl": [ - "b5d79decb06530001cd9d63e6fcba43995d27ba1", + "c87c855d439609adee24d2f49fc77879f9c8352b", "support" ], "interfaces/payment-method-basic-card.idl": [ @@ -450742,6 +451542,14 @@ "81a23a35be6f857e49253d47cb9c64d24677b56d", "support" ], + "interfaces/webxr-ar-module.idl": [ + "61fcd6a730f7c3846a8639075a0b2c2a3b755e0c", + "support" + ], + "interfaces/webxr-gamepads-module.idl": [ + "3aa17a7fe0c8020f6101c0fee29107ce7b24cb37", + "support" + ], "interfaces/webxr.idl": [ "b03aa556bb815127203e79c7b4bbc864d539314b", "support" @@ -450866,6 +451674,10 @@ "a093b22028c11c3e54db4a6f8fcccaad6a309bfb", "testharness" ], + "intersection-observer/resources/cross-origin-child-iframe.sub.html": [ + "8e2c36ed56072ad9fd2e82d43b609f5719d78a55", + "support" + ], "intersection-observer/resources/cross-origin-subframe.html": [ "4305ed1719b68f227192e005c9696fec5fe58f83", "support" @@ -450882,6 +451694,10 @@ "9d0769ae44a1bb4a6195c006999b0959f706330c", "support" ], + "intersection-observer/resources/same-origin-grand-child-iframe.html": [ + "25db5a29d8a917916d0b2012f8f790ea9178e681", + "support" + ], "intersection-observer/resources/scaled-target-subframe.html": [ "8f6f930e00915417fcba592df5520999c427ed91", "support" @@ -450922,6 +451738,10 @@ "20bd11d4beb1e8bdd623eaad96f11788747f0d15", "testharness" ], + "intersection-observer/same-origin-grand-child-iframe.sub.html": [ + "57c0347ddc8ec748e3ff025a0ef7f11342f32a1d", + "testharness" + ], "intersection-observer/shadow-content.html": [ "ce9473cb79258fca90321ee26240612c387ac9b9", "testharness" @@ -450963,7 +451783,7 @@ "testharness" ], "intersection-observer/v2/delay-test.html": [ - "231df32c31df0458a4d5de09da55f0244854e0a6", + "e3906ea2c2975cbe678f55e34ead09527bc2bbfc", "testharness" ], "intersection-observer/v2/drop-shadow-filter-vertical-rl.html": [ @@ -451371,7 +452191,7 @@ "testharness" ], "lint.whitelist": [ - "be87d27864059b94b79f74a7f671f119cc40c0f9", + "d9ea5c17c7cf66a47199faba54d4793e8236f6cb", "support" ], "loading/lazyload/common.js": [ @@ -452579,7 +453399,7 @@ "testharness" ], "mathml/relations/html5-tree/clipboard-event-handlers.tentative.html": [ - "82fda880887839b72ac8c683d076ea07a8525d80", + "9816f5126a030de083ce4a6ca020976d9bb3beeb", "testharness" ], "mathml/relations/html5-tree/color-attributes-1-ref.html": [ @@ -452675,7 +453495,7 @@ "testharness" ], "mathml/relations/html5-tree/math-global-event-handlers.tentative.html": [ - "e96feeaf0960641e4413b7b43b93e46490460ee7", + "be9bee9c6c68fc2ec8caf5043242c45711ed0ed1", "testharness" ], "mathml/relations/html5-tree/required-extensions-2-ref.html": [ @@ -464122,6 +464942,10 @@ "7c09f5d407e890c0ed02df1217d85f2f36d722bc", "testharness" ], + "payment-handler/change-payment-method-manual.https-expected.txt": [ + "f30628bbf9f8c9b6b12d5f4d39ef73048709dcee", + "support" + ], "payment-handler/change-payment-method-manual.https.html": [ "56690d2b26ed671f773a16853463126e57735f77", "manual" @@ -464175,7 +464999,7 @@ "testharness" ], "payment-handler/payment-request-event-manual.https-expected.txt": [ - "b76179f0c74a04d903ba1911be97252db6552851", + "a00a329711ec8f8de1e7e7aeda6704564483c9d3", "support" ], "payment-handler/payment-request-event-manual.https.html": [ @@ -464191,7 +465015,7 @@ "testharness" ], "payment-handler/supports-shipping-contact-delegation-manual.https-expected.txt": [ - "3a76dbf89699c771bd62376c0307a48373262caf", + "149709f312a02ec55d70e564c13ac013e54bb947", "support" ], "payment-handler/supports-shipping-contact-delegation-manual.https.html": [ @@ -464463,7 +465287,7 @@ "testharness" ], "payment-request/payment-request-canmakepayment-method.https-expected.txt": [ - "5b7ee0ea3db4c800b85e24e6f7bce3f300c4fb98", + "f12b171c62a6d860027b12ada3d46078786df131", "support" ], "payment-request/payment-request-canmakepayment-method.https.html": [ @@ -464498,10 +465322,6 @@ "4da11304a21427040f72317e3746feebb251d12e", "testharness" ], - "payment-request/payment-request-hasenrolledinstrument-method.tentative.https-expected.txt": [ - "ad1d3ce1fbbd63a4ed8f306fb33bca7853b57427", - "support" - ], "payment-request/payment-request-hasenrolledinstrument-method.tentative.https.html": [ "c1f7b27a22b41fe64a7fb77e73336d3d0daec159", "testharness" @@ -464539,7 +465359,7 @@ "testharness" ], "payment-request/payment-request-show-method.https-expected.txt": [ - "b9ec0aea579037597a4270d3259e70c799dccd27", + "694a3c86b6bee483e820849119481fb231e7c9a1", "support" ], "payment-request/payment-request-show-method.https.html": [ @@ -464782,10 +465602,22 @@ "b055f50f636848ceb7b1750484cc12328a121398", "support" ], + "permissions/feature-policy-permissions-query.html": [ + "bd152e973e8fd520460a325d47beab8c25f45d31", + "support" + ], "permissions/idlharness.any.js": [ "ff0a969badace39c3c4466c4528e30c21355e132", "testharness" ], + "permissions/permissions-query-feature-policy-attribute.https.sub-expected.txt": [ + "b3a521320e8acb70c2f2199d608d4bd3379934e0", + "support" + ], + "permissions/permissions-query-feature-policy-attribute.https.sub.html": [ + "1d7333d9b5f67a405dc6979d5ddcfda444a04c39", + "testharness" + ], "permissions/test-background-fetch-permission.html": [ "c824ecf1d2b47630f8ebcef3ed42c8c908c8e9eb", "testharness" @@ -465454,6 +466286,10 @@ "0eae0ddfd6ef1e9de2251f50914a855f4142b9d5", "reftest" ], + "portals/portals-repeated-activate.html": [ + "a3843dddb47b55d920b249b01f47199b1202bda6", + "testharness" + ], "portals/portals-set-src-after-activate.html": [ "8da6b341840162dc7348b95cfed060c075a75135", "testharness" @@ -465542,6 +466378,10 @@ "26f62839af5ed8ea7a50535f411780bdf7fd6e03", "support" ], + "portals/resources/portal-repeated-activate-window.html": [ + "e716034eff860fe567bc373f4676d55f97a5a786", + "support" + ], "portals/resources/portals-adopt-predecessor-portal.html": [ "b7eb3b96779a561cacf11d6c7e9362ca1049be6c", "support" @@ -465562,6 +466402,10 @@ "92aef00380ae4a6180039ad0b10169c81a190441", "support" ], + "portals/resources/simple-portal-adopts-and-activates-predecessor.html": [ + "56bfd10f647fb63597dbc5ec902a8c2b90257b18", + "support" + ], "portals/resources/simple-portal-adopts-predecessor.html": [ "b199bdd93b3a03437ebde7abaef9b14ac61b1f76", "support" @@ -477259,7 +478103,7 @@ "support" ], "resources/chromium/contacts_manager_mock.js": [ - "618968ec18da930ad1d3180adb68f05064bb1807", + "ae4c33b073dfd2b156030b2cb6d045e133b57c23", "support" ], "resources/chromium/device.mojom.js": [ @@ -477319,7 +478163,7 @@ "support" ], "resources/chromium/mock-imagecapture.js": [ - "eec414bd032a2dd01f27e18de64df0bde4e4a459", + "9d46b57020f36277b8bece93588699cae2a82471", "support" ], "resources/chromium/mojo_bindings.js": [ @@ -477443,7 +478287,7 @@ "support" ], "resources/testharness.js": [ - "15591042aa4cb0fdd75fe3bf56b9bdfb63fd161d", + "9ef46ca77646c92044ffc9d515009fafc11ed7d1", "support" ], "resources/testharness.js.headers": [ @@ -479483,7 +480327,7 @@ "manual" ], "service-workers/service-worker/fetch-event-within-sw.https.html": [ - "8a567fd7a93f8552412cfff657789c5375eba971", + "f5a60c3060961a2b1674c8959c5d4a0af7b5452a", "testharness" ], "service-workers/service-worker/fetch-event.https-expected.txt": [ @@ -481578,6 +482422,14 @@ "20456b057e1e724cdac9bc656f3b3d6c7ac2f658", "testharness" ], + "shadow-dom/focus/focus-selector-delegatesFocus-expected.txt": [ + "8b0d0bfc2ae13879b9b6a1dfb9b27f413c9d4ef3", + "support" + ], + "shadow-dom/focus/focus-selector-delegatesFocus.html": [ + "386045258e043f7b0849aaa366d34bb645f2f73f", + "testharness" + ], "shadow-dom/focus/focus-tabindex-order-shadow-negative.html": [ "ab25ea829bd10952ad6e96898fc95a1a1ae25d8f", "testharness" @@ -481607,7 +482459,7 @@ "testharness" ], "shadow-dom/focus/resources/shadow-utils.js": [ - "6ea372afdf180a95d9fda632ebccd00a13df85bf", + "8033ce0169f4aa83b54c3567c68c4cc4f5b7a490", "support" ], "shadow-dom/form-control-form-attribute.html": [ @@ -483051,7 +483903,7 @@ "testharness" ], "streams/readable-byte-streams/construct-byob-request.any.serviceworker-expected.txt": [ - "39cb31bdc3c7514005ce8a501d37e9038da682e2", + "6e0da30f5ce6d430095664301cc4be4cb9beb850", "support" ], "streams/readable-byte-streams/construct-byob-request.any.sharedworker-expected.txt": [ @@ -483975,7 +484827,7 @@ "testharness" ], "svg/animations/scripted/onhover-syncbases.html": [ - "07726017a02f30958c72496ac1fcb5b3c40531dd", + "de757f369af36db7a072ffa4b4216faa56063ecd", "testharness" ], "svg/animations/scripted/paced-value-animation-overwrites-keyTimes.html": [ @@ -486491,7 +487343,7 @@ "support" ], "tools/ci/tcdownload.py": [ - "91c763a7acdd3416d7eff55407bf8f73b840d96a", + "46e9005740d39d3a9fcd136f5aeb7effcc3087e6", "support" ], "tools/ci/update_pr_preview.py": [ @@ -486559,7 +487411,7 @@ "support" ], "tools/lint/lint.py": [ - "48a275bcf29df6264258da3885e0e5f83a7ec85a", + "7689c359928d6be0f58384dfdc22d8eaa9f0d932", "support" ], "tools/lint/rules.py": [ @@ -490851,7 +491703,7 @@ "support" ], "tools/wptrunner/requirements.txt": [ - "d6c7a4ff3983663d088c64f6608e3fcf7de3bbfe", + "3584c93a199716d0b9809dc4180195647887d1a0", "support" ], "tools/wptrunner/requirements_android_webview.txt": [ @@ -491703,7 +492555,7 @@ "support" ], "trusted-types/trusted-types-eval-reporting.tentative.https.html": [ - "309873cb1f8028ecb071ec5db3dfda62337e6b43", + "4ec5db1adce7478cc3e97f942a9de68f1263d31d", "testharness" ], "trusted-types/trusted-types-eval-reporting.tentative.https.html.headers": [ @@ -493670,8 +494522,12 @@ "bbb8ee2a3261fcb98cda7a83056467bc0b20dac6", "testharness" ], + "web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-001-expected.txt": [ + "5b5ccfe7ac54eabbd45c5851d4ca12b77cdbb229", + "support" + ], "web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-001.html": [ - "5c9ec84e8db79f73ac1423258a84bf0d18d70a5f", + "5bd0ae2b1edbb508d45ac64258332fcaddf5434c", "testharness" ], "web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-002.html": [ @@ -494579,7 +495435,7 @@ "testharness" ], "webaudio/the-audio-api/the-audioworklet-interface/audioworklet-addmodule-resolution.https.html": [ - "e94621296a3114ddbc53f26d74c330d3496dac63", + "dc324b22d6539d5383ed53f68ab911f6e96fd0dd", "testharness" ], "webaudio/the-audio-api/the-audioworklet-interface/audioworklet-audioparam-size.https.html": [ @@ -494963,7 +495819,7 @@ "testharness" ], "webaudio/the-audio-api/the-mediaelementaudiosourcenode-interface/mediaElementAudioSourceToScriptProcessorTest.html": [ - "3e364eb7b359948402ef8ecdb287a5f55bb80fc3", + "b1f18d397d4fbcf3150e76aa478ce1a00a64e217", "testharness" ], "webaudio/the-audio-api/the-mediaelementaudiosourcenode-interface/no-cors.https.html": [ @@ -494979,7 +495835,7 @@ "testharness" ], "webaudio/the-audio-api/the-mediastreamaudiosourcenode-interface/mediastreamaudiosourcenode-routing.html": [ - "2e04ab6a3f248e69846cadbdc41c5369c406f519", + "816eba0b29ae616e09099544e839b85bb0a8bea5", "testharness" ], "webaudio/the-audio-api/the-offlineaudiocontext-interface/ctor-offlineaudiocontext.html": [ @@ -495083,7 +495939,7 @@ "testharness" ], "webaudio/the-audio-api/the-waveshapernode-interface/curve-tests.html": [ - "a2e40777d4285732622fe0776f5e862276bf41c9", + "81e64dc12e9c757b613ddd377c39ed313b3cea47", "testharness" ], "webaudio/the-audio-api/the-waveshapernode-interface/silent-inputs.html": [ @@ -502358,6 +503214,10 @@ "cb7f47252d5746f61f1c9df2d981d47ef35940c5", "support" ], + "webxr/ar-module/idlharness.https.window.js": [ + "1268f4ea2a5eb228fb49a6f06d8905f8d9480ae7", + "testharness" + ], "webxr/events_input_source_recreation.https.html": [ "ecb4b022bf09410cae44b4f5a3c71bc5c054181e", "testharness" @@ -502382,6 +503242,10 @@ "f76847a8769073bb4753702f32dd5c2ccc9d3532", "testharness" ], + "webxr/gamepads-module/idlharness.https.window.js": [ + "4509c67a847109f2fdaed5be49c87777e1927a12", + "testharness" + ], "webxr/getInputPose_handedness.https.html": [ "5a310c6dd77274631d0ef9e751c6f195def9c3d3", "testharness" @@ -502575,7 +503439,7 @@ "testharness" ], "webxr/xrSession_input_events_end.https.html": [ - "37e020605a7e88320c42e054f867f611955c5713", + "a932aad2fad78ceb2449928773da3ecfe237b8e7", "testharness" ], "webxr/xrSession_prevent_multiple_exclusive.https.html": [ @@ -502650,8 +503514,12 @@ "1b7d982d596187f1381bee73eac2990900a37f8f", "testharness" ], + "webxr/xrWebGLLayer_constructor.https-expected.txt": [ + "be0603a78356f77aa03542657046774d805ffde1", + "support" + ], "webxr/xrWebGLLayer_constructor.https.html": [ - "0584da79c12def757f951ec53c4c048f18c39b8c", + "7e57f4286c66ea9f8380791840dada3d82b611fe", "testharness" ], "webxr/xrWebGLLayer_framebuffer_draw.https.html": [ @@ -506579,7 +507447,7 @@ "testharness" ], "xhr/xmlhttprequest-sync-default-feature-policy.sub.html": [ - "5ad5557700d79cb0104a5a5db52afdfa0906533b", + "ab5b78b77c66ee5bdca8e7acb5fb61f18d9574c1", "testharness" ], "xhr/xmlhttprequest-sync-not-hang-scriptloader-subframe.html": [
diff --git a/third_party/blink/web_tests/external/wpt/2dcontext/imagebitmap/createImageBitmap-invalid-args.html b/third_party/blink/web_tests/external/wpt/2dcontext/imagebitmap/createImageBitmap-invalid-args.html index 004b3ca6..c64371e 100644 --- a/third_party/blink/web_tests/external/wpt/2dcontext/imagebitmap/createImageBitmap-invalid-args.html +++ b/third_party/blink/web_tests/external/wpt/2dcontext/imagebitmap/createImageBitmap-invalid-args.html
@@ -52,7 +52,7 @@ description: 'createImageBitmap with <sourceType> source and sw set to 0', promiseTestFunction: (source, t) => { - return promise_rejects(t, new RangeError(), + return promise_rejects_js(t, RangeError, createImageBitmap(source, 0, 0, 0, 10)); } }, @@ -60,7 +60,7 @@ description: 'createImageBitmap with <sourceType> source and sh set to 0', promiseTestFunction: (source, t) => { - return promise_rejects(t, new RangeError(), + return promise_rejects_js(t, RangeError, createImageBitmap(source, 0, 0, 10, 0)); } }, @@ -100,88 +100,88 @@ }); promise_test( t => { - return promise_rejects(t, new TypeError(), createImageBitmap(undefined)); + return promise_rejects_js(t, TypeError, createImageBitmap(undefined)); }, "createImageBitmap with undefined image source."); promise_test( t => { - return promise_rejects(t, new TypeError(), createImageBitmap(null)); + return promise_rejects_js(t, TypeError, createImageBitmap(null)); }, "createImageBitmap with null image source."); promise_test( t => { var context = document.createElement("canvas").getContext("2d"); - return promise_rejects(t, new TypeError(), createImageBitmap(context)); + return promise_rejects_js(t, TypeError, createImageBitmap(context)); }, "createImageBitmap with CanvasRenderingContext2D image source."); promise_test( t => { var context = document.createElement("canvas").getContext("webgl"); - return promise_rejects(t, new TypeError(), createImageBitmap(context)); + return promise_rejects_js(t, TypeError, createImageBitmap(context)); }, "createImageBitmap with WebGLRenderingContext image source."); promise_test( t => { var buffer = new Uint8Array(); - return promise_rejects(t, new TypeError(), createImageBitmap(buffer)); + return promise_rejects_js(t, TypeError, createImageBitmap(buffer)); }, "createImageBitmap with Uint8Array image source."); promise_test( t => { var buffer = new ArrayBuffer(8); - return promise_rejects(t, new TypeError(), createImageBitmap(buffer)); + return promise_rejects_js(t, TypeError, createImageBitmap(buffer)); }, "createImageBitmap with ArrayBuffer image source."); promise_test( t => { - return promise_rejects(t, "InvalidStateError", + return promise_rejects_dom(t, "InvalidStateError", createImageBitmap(new Image())); }, "createImageBitmap with empty image source."); promise_test( t => { - return promise_rejects(t, "InvalidStateError", + return promise_rejects_dom(t, "InvalidStateError", createImageBitmap(document.createElement('video'))); }, "createImageBitmap with empty video source."); promise_test( t => { return makeOversizedCanvas().then(canvas => { - return promise_rejects(t, "InvalidStateError", + return promise_rejects_dom(t, "InvalidStateError", createImageBitmap(canvas)); }); }, "createImageBitmap with an oversized canvas source."); promise_test( t => { return makeOversizedOffscreenCanvas().then(offscreenCanvas => { - return promise_rejects(t, "InvalidStateError", + return promise_rejects_dom(t, "InvalidStateError", createImageBitmap(offscreenCanvas)); }); }, "createImageBitmap with an invalid OffscreenCanvas source."); promise_test( t => { return makeInvalidBlob().then(blob => { - return promise_rejects(t, "InvalidStateError", + return promise_rejects_dom(t, "InvalidStateError", createImageBitmap(blob)); }); }, "createImageBitmap with an undecodable blob source."); promise_test( t => { return makeBrokenImage().then(image => { - return promise_rejects(t, "InvalidStateError", + return promise_rejects_dom(t, "InvalidStateError", createImageBitmap(image)); }); }, "createImageBitmap with a broken image source."); promise_test( t => { return makeAvailableButBrokenImage("/images/broken.png").then(image => { - return promise_rejects(t, "InvalidStateError", + return promise_rejects_dom(t, "InvalidStateError", createImageBitmap(image)); }); }, "createImageBitmap with an available but undecodable image source."); promise_test( t => { return makeAvailableButBrokenImage("/images/red-zeroheight.svg").then(image => { - return promise_rejects(t, "InvalidStateError", + return promise_rejects_dom(t, "InvalidStateError", createImageBitmap(image)); }); }, "createImageBitmap with an available but zero height image source."); promise_test( t => { return makeAvailableButBrokenImage("/images/red-zerowidth.svg").then(image => { - return promise_rejects(t, "InvalidStateError", + return promise_rejects_dom(t, "InvalidStateError", createImageBitmap(image)); }); }, "createImageBitmap with an available but zero width image source."); @@ -189,7 +189,8 @@ promise_test( t => { return makeImageBitmap().then(bitmap => { bitmap.close() - return promise_rejects(t, "InvalidStateError", createImageBitmap(bitmap)); + return promise_rejects_dom(t, "InvalidStateError", + createImageBitmap(bitmap)); }); }, "createImageBitmap with a closed ImageBitmap."); </script>
diff --git a/third_party/blink/web_tests/external/wpt/IndexedDB/fire-error-event-exception.html b/third_party/blink/web_tests/external/wpt/IndexedDB/fire-error-event-exception.html index fe0dc18..0a3f122 100644 --- a/third_party/blink/web_tests/external/wpt/IndexedDB/fire-error-event-exception.html +++ b/third_party/blink/web_tests/external/wpt/IndexedDB/fire-error-event-exception.html
@@ -21,6 +21,9 @@ const request = store.add(0, 0); request.onsuccess = t.unreached_func('request should fail'); func(t, db, tx, request); + tx.addEventListener('abort', t.step_func_done(() => { + assert_equals(tx.error.name, 'AbortError'); + })); }, description); } @@ -31,9 +34,6 @@ request.onerror = () => { throw Error(); }; - tx.onabort = t.step_func_done(() => { - assert_equals(tx.error.name, 'AbortError'); - }); }, 'Exception in error event handler on request'); fire_error_event_test((t, db, tx, request) => { @@ -41,30 +41,33 @@ e.preventDefault(); throw Error(); }; - tx.onabort = t.step_func_done(() => { - assert_equals(tx.error.name, 'AbortError'); - }); }, 'Exception in error event handler on request, with preventDefault'); fire_error_event_test((t, db, tx, request) => { request.addEventListener('error', () => { throw Error(); }); - tx.onabort = t.step_func_done(() => { - assert_equals(tx.error.name, 'AbortError'); - }); }, 'Exception in error event listener on request'); fire_error_event_test((t, db, tx, request) => { + request.addEventListener('error', { + get handleEvent() { + throw new Error(); + }, + }); +}, 'Exception in error event listener ("handleEvent" lookup) on request'); + +fire_error_event_test((t, db, tx, request) => { + request.addEventListener('error', {}); +}, 'Exception in error event listener (non-callable "handleEvent") on request'); + +fire_error_event_test((t, db, tx, request) => { request.addEventListener('error', () => { // no-op }); request.addEventListener('error', () => { throw Error(); }); - tx.onabort = t.step_func_done(() => { - assert_equals(tx.error.name, 'AbortError'); - }); }, 'Exception in second error event listener on request'); fire_error_event_test((t, db, tx, request) => { @@ -77,10 +80,9 @@ assert_true(is_transaction_active(tx, 's'), 'Transaction should be active until dispatch completes'); })); - tx.onabort = t.step_func_done(() => { + tx.addEventListener('abort', t.step_func(() => { assert_true(second_listener_called); - assert_equals(tx.error.name, 'AbortError'); - }); + })); }, 'Exception in first error event listener on request, ' + 'transaction active in second'); @@ -90,9 +92,6 @@ tx.onerror = () => { throw Error(); }; - tx.onabort = t.step_func_done(() => { - assert_equals(tx.error.name, 'AbortError'); - }); }, 'Exception in error event handler on transaction'); fire_error_event_test((t, db, tx, request) => { @@ -100,18 +99,12 @@ e.preventDefault(); throw Error(); }; - tx.onabort = t.step_func_done(() => { - assert_equals(tx.error.name, 'AbortError'); - }); }, 'Exception in error event handler on transaction, with preventDefault'); fire_error_event_test((t, db, tx, request) => { tx.addEventListener('error', () => { throw Error(); }); - tx.onabort = t.step_func_done(() => { - assert_equals(tx.error.name, 'AbortError'); - }); }, 'Exception in error event listener on transaction'); fire_error_event_test((t, db, tx, request) => { @@ -121,9 +114,6 @@ tx.addEventListener('error', () => { throw Error(); }); - tx.onabort = t.step_func_done(() => { - assert_equals(tx.error.name, 'AbortError'); - }); }, 'Exception in second error event listener on transaction'); fire_error_event_test((t, db, tx, request) => { @@ -136,10 +126,9 @@ assert_true(is_transaction_active(tx, 's'), 'Transaction should be active until dispatch completes'); })); - tx.onabort = t.step_func_done(() => { + tx.addEventListener('abort', t.step_func(() => { assert_true(second_listener_called); - assert_equals(tx.error.name, 'AbortError'); - }); + })); }, 'Exception in first error event listener on transaction, ' + 'transaction active in second'); @@ -149,9 +138,6 @@ db.onerror = () => { throw Error(); }; - tx.onabort = t.step_func_done(() => { - assert_equals(tx.error.name, 'AbortError'); - }); }, 'Exception in error event handler on connection'); fire_error_event_test((t, db, tx, request) => { @@ -159,18 +145,12 @@ e.preventDefault() throw Error(); }; - tx.onabort = t.step_func_done(() => { - assert_equals(tx.error.name, 'AbortError'); - }); }, 'Exception in error event handler on connection, with preventDefault'); fire_error_event_test((t, db, tx, request) => { db.addEventListener('error', () => { throw Error(); }); - tx.onabort = t.step_func_done(() => { - assert_equals(tx.error.name, 'AbortError'); - }); }, 'Exception in error event listener on connection'); fire_error_event_test((t, db, tx, request) => { @@ -180,9 +160,6 @@ db.addEventListener('error', () => { throw Error(); }); - tx.onabort = t.step_func_done(() => { - assert_equals(tx.error.name, 'AbortError'); - }); }, 'Exception in second error event listener on connection'); fire_error_event_test((t, db, tx, request) => { @@ -195,10 +172,9 @@ assert_true(is_transaction_active(tx, 's'), 'Transaction should be active until dispatch completes'); })); - tx.onabort = t.step_func_done(() => { + tx.addEventListener('abort', t.step_func(() => { assert_true(second_listener_called); - assert_equals(tx.error.name, 'AbortError'); - }); + })); }, 'Exception in first error event listener on connection, ' + 'transaction active in second');
diff --git a/third_party/blink/web_tests/external/wpt/IndexedDB/fire-success-event-exception.html b/third_party/blink/web_tests/external/wpt/IndexedDB/fire-success-event-exception.html index c4e55066..ab0ac44e 100644 --- a/third_party/blink/web_tests/external/wpt/IndexedDB/fire-success-event-exception.html +++ b/third_party/blink/web_tests/external/wpt/IndexedDB/fire-success-event-exception.html
@@ -19,6 +19,9 @@ const store = tx.objectStore('s'); const request = store.get(0); func(t, db, tx, request); + tx.addEventListener('abort', t.step_func_done(() => { + assert_equals(tx.error.name, 'AbortError'); + })); }, description); } @@ -27,30 +30,35 @@ request.onsuccess = () => { throw Error(); }; - tx.onabort = t.step_func_done(() => { - assert_equals(tx.error.name, 'AbortError'); - }); }, 'Exception in success event handler on request'); fire_success_event_test((t, db, tx, request) => { request.addEventListener('success', () => { throw Error(); }); - tx.onabort = t.step_func_done(() => { - assert_equals(tx.error.name, 'AbortError'); - }); }, 'Exception in success event listener on request'); fire_success_event_test((t, db, tx, request) => { + request.addEventListener('success', { + get handleEvent() { + throw new Error(); + }, + }); +}, 'Exception in success event listener ("handleEvent" lookup) on request'); + +fire_success_event_test((t, db, tx, request) => { + request.addEventListener('success', { + handleEvent: null, + }); +}, 'Exception in success event listener (non-callable "handleEvent") on request'); + +fire_success_event_test((t, db, tx, request) => { request.addEventListener('success', () => { // no-op }); request.addEventListener('success', () => { throw Error(); }); - tx.onabort = t.step_func_done(() => { - assert_equals(tx.error.name, 'AbortError'); - }); }, 'Exception in second success event listener on request'); fire_success_event_test((t, db, tx, request) => { @@ -63,10 +71,9 @@ assert_true(is_transaction_active(tx, 's'), 'Transaction should be active until dispatch completes'); })); - tx.onabort = t.step_func_done(() => { + tx.addEventListener('abort', t.step_func(() => { assert_true(second_listener_called); - assert_equals(tx.error.name, 'AbortError'); - }); + })); }, 'Exception in first success event listener, tx active in second'); </script>
diff --git a/third_party/blink/web_tests/external/wpt/IndexedDB/fire-upgradeneeded-event-exception.html b/third_party/blink/web_tests/external/wpt/IndexedDB/fire-upgradeneeded-event-exception.html index 5db452e..1a8163a 100644 --- a/third_party/blink/web_tests/external/wpt/IndexedDB/fire-upgradeneeded-event-exception.html +++ b/third_party/blink/web_tests/external/wpt/IndexedDB/fire-upgradeneeded-event-exception.html
@@ -15,48 +15,55 @@ del.onerror = t.unreached_func('deleteDatabase should succeed'); const open = indexedDB.open(dbname, 1); open.onsuccess = t.unreached_func('open should fail'); + let tx; + open.addEventListener('upgradeneeded', () => { + tx = open.transaction; + }); func(t, open); + open.addEventListener('error', t.step_func_done(() => { + assert_equals(tx.error.name, 'AbortError'); + })); }, description); } fire_upgradeneeded_event_test((t, open) => { - let tx; open.onupgradeneeded = () => { - tx = open.transaction; throw Error(); }; - open.onerror = t.step_func_done(() => { - assert_equals(tx.error.name, 'AbortError'); - }); }, 'Exception in upgradeneeded handler'); fire_upgradeneeded_event_test((t, open) => { - let tx; open.addEventListener('upgradeneeded', () => { - tx = open.transaction; throw Error(); }); - open.onerror = t.step_func_done(() => { - assert_equals(tx.error.name, 'AbortError'); - }); }, 'Exception in upgradeneeded listener'); fire_upgradeneeded_event_test((t, open) => { - let tx; + open.addEventListener('upgradeneeded', { + get handleEvent() { + throw new Error(); + }, + }); +}, 'Exception in upgradeneeded "handleEvent" lookup'); + +fire_upgradeneeded_event_test((t, open) => { + open.addEventListener('upgradeneeded', { + get handleEvent() { + return 10; + }, + }); +}, 'Exception in upgradeneeded due to non-callable "handleEvent"'); + +fire_upgradeneeded_event_test((t, open) => { open.addEventListener('upgradeneeded', () => { // No-op. }); open.addEventListener('upgradeneeded', () => { - tx = open.transaction; throw Error(); }); - open.onerror = t.step_func_done(() => { - assert_equals(tx.error.name, 'AbortError'); - }); }, 'Exception in second upgradeneeded listener'); fire_upgradeneeded_event_test((t, open) => { - let tx; let second_listener_called = false; open.addEventListener('upgradeneeded', () => { open.result.createObjectStore('s'); @@ -64,14 +71,12 @@ }); open.addEventListener('upgradeneeded', t.step_func(() => { second_listener_called = true; - tx = open.transaction; - assert_true(is_transaction_active(tx, 's'), + assert_true(is_transaction_active(open.transaction, 's'), 'Transaction should be active until dispatch completes'); })); - open.onerror = t.step_func_done(() => { + open.addEventListener('error', t.step_func(() => { assert_true(second_listener_called); - assert_equals(tx.error.name, 'AbortError'); - }); + })); }, 'Exception in first upgradeneeded listener, tx active in second'); </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-delay-invalid.html b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-delay-invalid.html index a58d2cd11b..52e42a2 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-delay-invalid.html +++ b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-delay-invalid.html
@@ -14,6 +14,9 @@ test_invalid_value("animation-delay", "infinite"); test_invalid_value("animation-delay", "0"); test_invalid_value("animation-delay", "1s 2s"); + +test_invalid_value("animation-delay", "initial, -3s"); +test_invalid_value("animation-delay", "-3s, initial"); </script> </body> </html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-direction-invalid.html b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-direction-invalid.html index 0b48d97f..5c96216 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-direction-invalid.html +++ b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-direction-invalid.html
@@ -13,6 +13,9 @@ <script> test_invalid_value("animation-direction", "auto"); test_invalid_value("animation-direction", "normal reverse"); + +test_invalid_value("animation-direction", "reverse, initial"); +test_invalid_value("animation-direction", "initial, reverse"); </script> </body> </html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-duration-invalid.html b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-duration-invalid.html index 5edacd3..bd8cf2a 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-duration-invalid.html +++ b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-duration-invalid.html
@@ -15,6 +15,9 @@ test_invalid_value("animation-duration", '0'); test_invalid_value("animation-duration", 'infinite'); test_invalid_value("animation-duration", '1s 2s'); + +test_invalid_value("animation-duration", 'initial, 1s'); +test_invalid_value("animation-duration", '1s, initial'); </script> </body> </html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-fill-mode-invalid.html b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-fill-mode-invalid.html index dda2221..2a82f235 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-fill-mode-invalid.html +++ b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-fill-mode-invalid.html
@@ -13,6 +13,9 @@ <script> test_invalid_value("animation-fill-mode", "auto"); test_invalid_value("animation-fill-mode", "forwards backwards"); + +test_invalid_value("animation-fill-mode", "both, initial"); +test_invalid_value("animation-fill-mode", "initial, both"); </script> </body> </html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-invalid.html b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-invalid.html new file mode 100644 index 0000000..c5790a3 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-invalid.html
@@ -0,0 +1,30 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Animations: parsing animation with invalid values</title> +<link rel="help" href="https://drafts.csswg.org/css-animations/#propdef-animation"> +<meta name="assert" content="animation supports only the grammar '<single-animation> #'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/parsing-testcommon.js"></script> +</head> +<body> +<script> +test_invalid_value("animation", "1s 2s 3s"); +test_invalid_value("animation", "-1s -2s"); + +test_invalid_value("animation", "steps(1) steps(2)"); + +test_invalid_value("animation", "1 2"); + +test_invalid_value("animation", "reverse alternate anim"); + +test_invalid_value("animation", "both backwards anim"); + +test_invalid_value("animation", "paused running anim"); + +test_invalid_value("animation", "anim1 anim2"); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-iteration-count-invalid.html b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-iteration-count-invalid.html index ff1e8e2..621340f 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-iteration-count-invalid.html +++ b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-iteration-count-invalid.html
@@ -14,6 +14,9 @@ test_invalid_value("animation-iteration-count", "auto"); test_invalid_value("animation-iteration-count", "-2"); test_invalid_value("animation-iteration-count", "3 4"); + +test_invalid_value("animation-iteration-count", "initial, 4"); +test_invalid_value("animation-iteration-count", "4, initial"); </script> </body> </html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-play-state-invalid.html b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-play-state-invalid.html index f47a2f7..91a6f017 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-play-state-invalid.html +++ b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-play-state-invalid.html
@@ -13,6 +13,9 @@ <script> test_invalid_value("animation-play-state", "auto"); test_invalid_value("animation-play-state", "paused running"); + +test_invalid_value("animation-play-state", "paused, initial"); +test_invalid_value("animation-play-state", "initial, paused"); </script> </body> </html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-shorthand.html b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-shorthand.html new file mode 100644 index 0000000..2e3053e --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-shorthand.html
@@ -0,0 +1,48 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Animations: animation sets longhands</title> +<link rel="help" href="https://drafts.csswg.org/css-animations/#propdef-animation"> +<meta name="assert" content="animation supports the full grammar '<single-animation> #'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/shorthand-testcommon.js"></script> +</head> +<body> +<script> +test_shorthand_value('animation', 'anim paused both reverse 4 1s -3s cubic-bezier(0, -2, 1, 3)', { + 'animation-duration': '1s', + 'animation-timing-function': 'cubic-bezier(0, -2, 1, 3)', + 'animation-delay': '-3s', + 'animation-iteration-count': '4', + 'animation-direction': 'reverse', + 'animation-fill-mode': 'both', + 'animation-play-state': 'paused', + 'animation-name': 'anim' +}); + +test_shorthand_value('animation', 'anim paused both reverse, 4 1s -3s cubic-bezier(0, -2, 1, 3)', { + 'animation-duration': '0s, 1s', + 'animation-timing-function': 'ease, cubic-bezier(0, -2, 1, 3)', + 'animation-delay': '0s, -3s', + 'animation-iteration-count': '1, 4', + 'animation-direction': 'reverse, normal', + 'animation-fill-mode': 'both, none', + 'animation-play-state': 'paused, running', + 'animation-name': 'anim, none' +}); + +test_shorthand_value('animation', '4 1s -3s cubic-bezier(0, -2, 1, 3), anim paused both reverse', { + 'animation-duration': '1s, 0s', + 'animation-timing-function': 'cubic-bezier(0, -2, 1, 3), ease', + 'animation-delay': '-3s, 0s', + 'animation-iteration-count': '4, 1', + 'animation-direction': 'normal, reverse', + 'animation-fill-mode': 'none, both', + 'animation-play-state': 'running, paused', + 'animation-name': 'none, anim' +}); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-timing-function-invalid.html b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-timing-function-invalid.html index adc1cc1..621145b 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-timing-function-invalid.html +++ b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-timing-function-invalid.html
@@ -18,6 +18,9 @@ test_invalid_value("animation-timing-function", "cubic-bezier(1, 2, 3, 4, 5)"); test_invalid_value("animation-timing-function", "cubic-bezier(-0.1, 0.1, 0.5, 0.9)"); test_invalid_value("animation-timing-function", "cubic-bezier(0.5, 0.1, 1.1, 0.9)"); + +test_invalid_value("animation-timing-function", "initial, cubic-bezier(0, -2, 1, 3)"); +test_invalid_value("animation-timing-function", "cubic-bezier(0, -2, 1, 3), initial"); </script> </body> </html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-valid.html b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-valid.html new file mode 100644 index 0000000..65de3c6 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-valid.html
@@ -0,0 +1,38 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Animations: parsing animation with valid values</title> +<link rel="help" href="https://drafts.csswg.org/css-animations/#propdef-animation"> +<meta name="assert" content="animation supports the full grammar '<single-animation> #'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/parsing-testcommon.js"></script> +</head> +<body> +<script> +// <single-animation> = <time> || <easing-function> || <time> || +// <single-animation-iteration-count> || <single-animation-direction> || +// <single-animation-fill-mode> || <single-animation-play-state> || +// [ none | <keyframes-name> ] +test_valid_value("animation", "1s", ["1s", "1s ease 0s 1 normal none running none"]); +test_valid_value("animation", "cubic-bezier(0, -2, 1, 3)", ["cubic-bezier(0, -2, 1, 3)", "0s cubic-bezier(0, -2, 1, 3) 0s 1 normal none running none"]); +test_valid_value("animation", "1s -3s", ["1s -3s", "1s ease -3s 1 normal none running none"]); +test_valid_value("animation", "4", ["4", "0s ease 0s 4 normal none running none"]); +test_valid_value("animation", "reverse", ["reverse", "0s ease 0s 1 reverse none running none"]); +test_valid_value("animation", "both", ["both", "0s ease 0s 1 normal both running none"]); +test_valid_value("animation", "paused", ["paused", "0s ease 0s 1 normal none paused none"]); +test_valid_value("animation", "none", ["none", "0s ease 0s 1 normal none running none"]); +test_valid_value("animation", "anim", ["anim", "0s ease 0s 1 normal none running anim"]); + +test_valid_value("animation", "anim paused both reverse 4 1s -3s cubic-bezier(0, -2, 1, 3)", + "1s cubic-bezier(0, -2, 1, 3) -3s 4 reverse both paused anim"); + +test_valid_value("animation", "anim paused both reverse, 4 1s -3s cubic-bezier(0, -2, 1, 3)", + "0s ease 0s 1 reverse both paused anim, 1s cubic-bezier(0, -2, 1, 3) -3s 4 normal none running none"); + +// TODO: Add test with a single negative time. +// TODO: Add test with a single timing-function keyword. +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-image-outset-interpolation-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-image-outset-interpolation-expected.txt new file mode 100644 index 0000000..6ca6cb7 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-image-outset-interpolation-expected.txt
@@ -0,0 +1,172 @@ +This is a testharness.js-based test. +Found 168 tests; 128 PASS, 40 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS CSS Transitions: property <border-image-outset> from neutral to [2px] at (-0.3) should be [0.7px] +PASS CSS Transitions: property <border-image-outset> from neutral to [2px] at (0) should be [1px] +PASS CSS Transitions: property <border-image-outset> from neutral to [2px] at (0.3) should be [1.3px] +PASS CSS Transitions: property <border-image-outset> from neutral to [2px] at (0.6) should be [1.6px] +PASS CSS Transitions: property <border-image-outset> from neutral to [2px] at (1) should be [2px] +PASS CSS Transitions: property <border-image-outset> from neutral to [2px] at (1.5) should be [2.5px] +PASS CSS Transitions with transition: all: property <border-image-outset> from neutral to [2px] at (-0.3) should be [0.7px] +PASS CSS Transitions with transition: all: property <border-image-outset> from neutral to [2px] at (0) should be [1px] +PASS CSS Transitions with transition: all: property <border-image-outset> from neutral to [2px] at (0.3) should be [1.3px] +PASS CSS Transitions with transition: all: property <border-image-outset> from neutral to [2px] at (0.6) should be [1.6px] +PASS CSS Transitions with transition: all: property <border-image-outset> from neutral to [2px] at (1) should be [2px] +PASS CSS Transitions with transition: all: property <border-image-outset> from neutral to [2px] at (1.5) should be [2.5px] +PASS CSS Animations: property <border-image-outset> from neutral to [2px] at (-0.3) should be [0.7px] +PASS CSS Animations: property <border-image-outset> from neutral to [2px] at (0) should be [1px] +PASS CSS Animations: property <border-image-outset> from neutral to [2px] at (0.3) should be [1.3px] +PASS CSS Animations: property <border-image-outset> from neutral to [2px] at (0.6) should be [1.6px] +PASS CSS Animations: property <border-image-outset> from neutral to [2px] at (1) should be [2px] +PASS CSS Animations: property <border-image-outset> from neutral to [2px] at (1.5) should be [2.5px] +PASS Web Animations: property <border-image-outset> from neutral to [2px] at (-0.3) should be [0.7px] +PASS Web Animations: property <border-image-outset> from neutral to [2px] at (0) should be [1px] +PASS Web Animations: property <border-image-outset> from neutral to [2px] at (0.3) should be [1.3px] +PASS Web Animations: property <border-image-outset> from neutral to [2px] at (0.6) should be [1.6px] +PASS Web Animations: property <border-image-outset> from neutral to [2px] at (1) should be [2px] +PASS Web Animations: property <border-image-outset> from neutral to [2px] at (1.5) should be [2.5px] +FAIL CSS Transitions: property <border-image-outset> from [initial] to [2] at (-0.3) should be [0] assert_equals: expected "0 " but got "2 " +FAIL CSS Transitions: property <border-image-outset> from [initial] to [2] at (0) should be [0] assert_equals: expected "0 " but got "2 " +FAIL CSS Transitions: property <border-image-outset> from [initial] to [2] at (0.3) should be [0.6] assert_equals: expected "0.6 " but got "2 " +FAIL CSS Transitions: property <border-image-outset> from [initial] to [2] at (0.6) should be [1.2] assert_equals: expected "1.2 " but got "2 " +PASS CSS Transitions: property <border-image-outset> from [initial] to [2] at (1) should be [2] +FAIL CSS Transitions: property <border-image-outset> from [initial] to [2] at (1.5) should be [3] assert_equals: expected "3 " but got "2 " +FAIL CSS Transitions with transition: all: property <border-image-outset> from [initial] to [2] at (-0.3) should be [0] assert_equals: expected "0 " but got "2 " +FAIL CSS Transitions with transition: all: property <border-image-outset> from [initial] to [2] at (0) should be [0] assert_equals: expected "0 " but got "2 " +FAIL CSS Transitions with transition: all: property <border-image-outset> from [initial] to [2] at (0.3) should be [0.6] assert_equals: expected "0.6 " but got "2 " +FAIL CSS Transitions with transition: all: property <border-image-outset> from [initial] to [2] at (0.6) should be [1.2] assert_equals: expected "1.2 " but got "2 " +PASS CSS Transitions with transition: all: property <border-image-outset> from [initial] to [2] at (1) should be [2] +FAIL CSS Transitions with transition: all: property <border-image-outset> from [initial] to [2] at (1.5) should be [3] assert_equals: expected "3 " but got "2 " +FAIL CSS Animations: property <border-image-outset> from [initial] to [2] at (-0.3) should be [0] assert_equals: expected "0 " but got "0px " +FAIL CSS Animations: property <border-image-outset> from [initial] to [2] at (0) should be [0] assert_equals: expected "0 " but got "0px " +FAIL CSS Animations: property <border-image-outset> from [initial] to [2] at (0.3) should be [0.6] assert_equals: expected "0.6 " but got "0px " +FAIL CSS Animations: property <border-image-outset> from [initial] to [2] at (0.6) should be [1.2] assert_equals: expected "1.2 " but got "2 " +PASS CSS Animations: property <border-image-outset> from [initial] to [2] at (1) should be [2] +FAIL CSS Animations: property <border-image-outset> from [initial] to [2] at (1.5) should be [3] assert_equals: expected "3 " but got "2 " +FAIL Web Animations: property <border-image-outset> from [initial] to [2] at (-0.3) should be [0] assert_equals: expected "0 " but got "0px " +FAIL Web Animations: property <border-image-outset> from [initial] to [2] at (0) should be [0] assert_equals: expected "0 " but got "0px " +FAIL Web Animations: property <border-image-outset> from [initial] to [2] at (0.3) should be [0.6] assert_equals: expected "0.6 " but got "0px " +FAIL Web Animations: property <border-image-outset> from [initial] to [2] at (0.6) should be [1.2] assert_equals: expected "1.2 " but got "2 " +PASS Web Animations: property <border-image-outset> from [initial] to [2] at (1) should be [2] +FAIL Web Animations: property <border-image-outset> from [initial] to [2] at (1.5) should be [3] assert_equals: expected "3 " but got "2 " +PASS CSS Transitions: property <border-image-outset> from [inherit] to [2px] at (-0.3) should be [12.4px] +PASS CSS Transitions: property <border-image-outset> from [inherit] to [2px] at (0) should be [10px] +PASS CSS Transitions: property <border-image-outset> from [inherit] to [2px] at (0.3) should be [7.6px] +PASS CSS Transitions: property <border-image-outset> from [inherit] to [2px] at (0.6) should be [5.2px] +PASS CSS Transitions: property <border-image-outset> from [inherit] to [2px] at (1) should be [2px] +PASS CSS Transitions: property <border-image-outset> from [inherit] to [2px] at (1.5) should be [0px] +PASS CSS Transitions with transition: all: property <border-image-outset> from [inherit] to [2px] at (-0.3) should be [12.4px] +PASS CSS Transitions with transition: all: property <border-image-outset> from [inherit] to [2px] at (0) should be [10px] +PASS CSS Transitions with transition: all: property <border-image-outset> from [inherit] to [2px] at (0.3) should be [7.6px] +PASS CSS Transitions with transition: all: property <border-image-outset> from [inherit] to [2px] at (0.6) should be [5.2px] +PASS CSS Transitions with transition: all: property <border-image-outset> from [inherit] to [2px] at (1) should be [2px] +PASS CSS Transitions with transition: all: property <border-image-outset> from [inherit] to [2px] at (1.5) should be [0px] +PASS CSS Animations: property <border-image-outset> from [inherit] to [2px] at (-0.3) should be [12.4px] +PASS CSS Animations: property <border-image-outset> from [inherit] to [2px] at (0) should be [10px] +PASS CSS Animations: property <border-image-outset> from [inherit] to [2px] at (0.3) should be [7.6px] +PASS CSS Animations: property <border-image-outset> from [inherit] to [2px] at (0.6) should be [5.2px] +PASS CSS Animations: property <border-image-outset> from [inherit] to [2px] at (1) should be [2px] +PASS CSS Animations: property <border-image-outset> from [inherit] to [2px] at (1.5) should be [0px] +PASS Web Animations: property <border-image-outset> from [inherit] to [2px] at (-0.3) should be [12.4px] +PASS Web Animations: property <border-image-outset> from [inherit] to [2px] at (0) should be [10px] +PASS Web Animations: property <border-image-outset> from [inherit] to [2px] at (0.3) should be [7.6px] +PASS Web Animations: property <border-image-outset> from [inherit] to [2px] at (0.6) should be [5.2px] +PASS Web Animations: property <border-image-outset> from [inherit] to [2px] at (1) should be [2px] +PASS Web Animations: property <border-image-outset> from [inherit] to [2px] at (1.5) should be [0px] +FAIL CSS Transitions: property <border-image-outset> from [unset] to [2] at (-0.3) should be [0] assert_equals: expected "0 " but got "2 " +FAIL CSS Transitions: property <border-image-outset> from [unset] to [2] at (0) should be [0] assert_equals: expected "0 " but got "2 " +FAIL CSS Transitions: property <border-image-outset> from [unset] to [2] at (0.3) should be [0.6] assert_equals: expected "0.6 " but got "2 " +FAIL CSS Transitions: property <border-image-outset> from [unset] to [2] at (0.6) should be [1.2] assert_equals: expected "1.2 " but got "2 " +PASS CSS Transitions: property <border-image-outset> from [unset] to [2] at (1) should be [2] +FAIL CSS Transitions: property <border-image-outset> from [unset] to [2] at (1.5) should be [3] assert_equals: expected "3 " but got "2 " +FAIL CSS Transitions with transition: all: property <border-image-outset> from [unset] to [2] at (-0.3) should be [0] assert_equals: expected "0 " but got "2 " +FAIL CSS Transitions with transition: all: property <border-image-outset> from [unset] to [2] at (0) should be [0] assert_equals: expected "0 " but got "2 " +FAIL CSS Transitions with transition: all: property <border-image-outset> from [unset] to [2] at (0.3) should be [0.6] assert_equals: expected "0.6 " but got "2 " +FAIL CSS Transitions with transition: all: property <border-image-outset> from [unset] to [2] at (0.6) should be [1.2] assert_equals: expected "1.2 " but got "2 " +PASS CSS Transitions with transition: all: property <border-image-outset> from [unset] to [2] at (1) should be [2] +FAIL CSS Transitions with transition: all: property <border-image-outset> from [unset] to [2] at (1.5) should be [3] assert_equals: expected "3 " but got "2 " +FAIL CSS Animations: property <border-image-outset> from [unset] to [2] at (-0.3) should be [0] assert_equals: expected "0 " but got "0px " +FAIL CSS Animations: property <border-image-outset> from [unset] to [2] at (0) should be [0] assert_equals: expected "0 " but got "0px " +FAIL CSS Animations: property <border-image-outset> from [unset] to [2] at (0.3) should be [0.6] assert_equals: expected "0.6 " but got "0px " +FAIL CSS Animations: property <border-image-outset> from [unset] to [2] at (0.6) should be [1.2] assert_equals: expected "1.2 " but got "2 " +PASS CSS Animations: property <border-image-outset> from [unset] to [2] at (1) should be [2] +FAIL CSS Animations: property <border-image-outset> from [unset] to [2] at (1.5) should be [3] assert_equals: expected "3 " but got "2 " +FAIL Web Animations: property <border-image-outset> from [unset] to [2] at (-0.3) should be [0] assert_equals: expected "0 " but got "0px " +FAIL Web Animations: property <border-image-outset> from [unset] to [2] at (0) should be [0] assert_equals: expected "0 " but got "0px " +FAIL Web Animations: property <border-image-outset> from [unset] to [2] at (0.3) should be [0.6] assert_equals: expected "0.6 " but got "0px " +FAIL Web Animations: property <border-image-outset> from [unset] to [2] at (0.6) should be [1.2] assert_equals: expected "1.2 " but got "2 " +PASS Web Animations: property <border-image-outset> from [unset] to [2] at (1) should be [2] +FAIL Web Animations: property <border-image-outset> from [unset] to [2] at (1.5) should be [3] assert_equals: expected "3 " but got "2 " +PASS CSS Transitions: property <border-image-outset> from [0px] to [5px] at (-0.3) should be [0px] +PASS CSS Transitions: property <border-image-outset> from [0px] to [5px] at (0) should be [0px] +PASS CSS Transitions: property <border-image-outset> from [0px] to [5px] at (0.3) should be [1.5px] +PASS CSS Transitions: property <border-image-outset> from [0px] to [5px] at (0.6) should be [3px] +PASS CSS Transitions: property <border-image-outset> from [0px] to [5px] at (1) should be [5px] +PASS CSS Transitions: property <border-image-outset> from [0px] to [5px] at (1.5) should be [7.5px] +PASS CSS Transitions with transition: all: property <border-image-outset> from [0px] to [5px] at (-0.3) should be [0px] +PASS CSS Transitions with transition: all: property <border-image-outset> from [0px] to [5px] at (0) should be [0px] +PASS CSS Transitions with transition: all: property <border-image-outset> from [0px] to [5px] at (0.3) should be [1.5px] +PASS CSS Transitions with transition: all: property <border-image-outset> from [0px] to [5px] at (0.6) should be [3px] +PASS CSS Transitions with transition: all: property <border-image-outset> from [0px] to [5px] at (1) should be [5px] +PASS CSS Transitions with transition: all: property <border-image-outset> from [0px] to [5px] at (1.5) should be [7.5px] +PASS CSS Animations: property <border-image-outset> from [0px] to [5px] at (-0.3) should be [0px] +PASS CSS Animations: property <border-image-outset> from [0px] to [5px] at (0) should be [0px] +PASS CSS Animations: property <border-image-outset> from [0px] to [5px] at (0.3) should be [1.5px] +PASS CSS Animations: property <border-image-outset> from [0px] to [5px] at (0.6) should be [3px] +PASS CSS Animations: property <border-image-outset> from [0px] to [5px] at (1) should be [5px] +PASS CSS Animations: property <border-image-outset> from [0px] to [5px] at (1.5) should be [7.5px] +PASS Web Animations: property <border-image-outset> from [0px] to [5px] at (-0.3) should be [0px] +PASS Web Animations: property <border-image-outset> from [0px] to [5px] at (0) should be [0px] +PASS Web Animations: property <border-image-outset> from [0px] to [5px] at (0.3) should be [1.5px] +PASS Web Animations: property <border-image-outset> from [0px] to [5px] at (0.6) should be [3px] +PASS Web Animations: property <border-image-outset> from [0px] to [5px] at (1) should be [5px] +PASS Web Animations: property <border-image-outset> from [0px] to [5px] at (1.5) should be [7.5px] +PASS CSS Transitions: property <border-image-outset> from [0] to [1] at (-0.3) should be [0] +PASS CSS Transitions: property <border-image-outset> from [0] to [1] at (0) should be [0] +PASS CSS Transitions: property <border-image-outset> from [0] to [1] at (0.3) should be [0.3] +PASS CSS Transitions: property <border-image-outset> from [0] to [1] at (0.6) should be [0.6] +PASS CSS Transitions: property <border-image-outset> from [0] to [1] at (1) should be [1] +PASS CSS Transitions: property <border-image-outset> from [0] to [1] at (1.5) should be [1.5] +PASS CSS Transitions with transition: all: property <border-image-outset> from [0] to [1] at (-0.3) should be [0] +PASS CSS Transitions with transition: all: property <border-image-outset> from [0] to [1] at (0) should be [0] +PASS CSS Transitions with transition: all: property <border-image-outset> from [0] to [1] at (0.3) should be [0.3] +PASS CSS Transitions with transition: all: property <border-image-outset> from [0] to [1] at (0.6) should be [0.6] +PASS CSS Transitions with transition: all: property <border-image-outset> from [0] to [1] at (1) should be [1] +PASS CSS Transitions with transition: all: property <border-image-outset> from [0] to [1] at (1.5) should be [1.5] +PASS CSS Animations: property <border-image-outset> from [0] to [1] at (-0.3) should be [0] +PASS CSS Animations: property <border-image-outset> from [0] to [1] at (0) should be [0] +PASS CSS Animations: property <border-image-outset> from [0] to [1] at (0.3) should be [0.3] +PASS CSS Animations: property <border-image-outset> from [0] to [1] at (0.6) should be [0.6] +PASS CSS Animations: property <border-image-outset> from [0] to [1] at (1) should be [1] +PASS CSS Animations: property <border-image-outset> from [0] to [1] at (1.5) should be [1.5] +PASS Web Animations: property <border-image-outset> from [0] to [1] at (-0.3) should be [0] +PASS Web Animations: property <border-image-outset> from [0] to [1] at (0) should be [0] +PASS Web Animations: property <border-image-outset> from [0] to [1] at (0.3) should be [0.3] +PASS Web Animations: property <border-image-outset> from [0] to [1] at (0.6) should be [0.6] +PASS Web Animations: property <border-image-outset> from [0] to [1] at (1) should be [1] +PASS Web Animations: property <border-image-outset> from [0] to [1] at (1.5) should be [1.5] +PASS CSS Transitions: property <border-image-outset> from [1 2 3px 4px] to [101 102 103px 104px] at (-0.3) should be [0 0 0px 0px] +PASS CSS Transitions: property <border-image-outset> from [1 2 3px 4px] to [101 102 103px 104px] at (0) should be [1 2 3px 4px] +PASS CSS Transitions: property <border-image-outset> from [1 2 3px 4px] to [101 102 103px 104px] at (0.3) should be [31 32 33px 34px] +PASS CSS Transitions: property <border-image-outset> from [1 2 3px 4px] to [101 102 103px 104px] at (0.6) should be [61 62 63px 64px] +PASS CSS Transitions: property <border-image-outset> from [1 2 3px 4px] to [101 102 103px 104px] at (1) should be [101 102 103px 104px] +PASS CSS Transitions: property <border-image-outset> from [1 2 3px 4px] to [101 102 103px 104px] at (1.5) should be [151 152 153px 154px] +PASS CSS Transitions with transition: all: property <border-image-outset> from [1 2 3px 4px] to [101 102 103px 104px] at (-0.3) should be [0 0 0px 0px] +PASS CSS Transitions with transition: all: property <border-image-outset> from [1 2 3px 4px] to [101 102 103px 104px] at (0) should be [1 2 3px 4px] +PASS CSS Transitions with transition: all: property <border-image-outset> from [1 2 3px 4px] to [101 102 103px 104px] at (0.3) should be [31 32 33px 34px] +PASS CSS Transitions with transition: all: property <border-image-outset> from [1 2 3px 4px] to [101 102 103px 104px] at (0.6) should be [61 62 63px 64px] +PASS CSS Transitions with transition: all: property <border-image-outset> from [1 2 3px 4px] to [101 102 103px 104px] at (1) should be [101 102 103px 104px] +PASS CSS Transitions with transition: all: property <border-image-outset> from [1 2 3px 4px] to [101 102 103px 104px] at (1.5) should be [151 152 153px 154px] +PASS CSS Animations: property <border-image-outset> from [1 2 3px 4px] to [101 102 103px 104px] at (-0.3) should be [0 0 0px 0px] +PASS CSS Animations: property <border-image-outset> from [1 2 3px 4px] to [101 102 103px 104px] at (0) should be [1 2 3px 4px] +PASS CSS Animations: property <border-image-outset> from [1 2 3px 4px] to [101 102 103px 104px] at (0.3) should be [31 32 33px 34px] +PASS CSS Animations: property <border-image-outset> from [1 2 3px 4px] to [101 102 103px 104px] at (0.6) should be [61 62 63px 64px] +PASS CSS Animations: property <border-image-outset> from [1 2 3px 4px] to [101 102 103px 104px] at (1) should be [101 102 103px 104px] +PASS CSS Animations: property <border-image-outset> from [1 2 3px 4px] to [101 102 103px 104px] at (1.5) should be [151 152 153px 154px] +PASS Web Animations: property <border-image-outset> from [1 2 3px 4px] to [101 102 103px 104px] at (-0.3) should be [0 0 0px 0px] +PASS Web Animations: property <border-image-outset> from [1 2 3px 4px] to [101 102 103px 104px] at (0) should be [1 2 3px 4px] +PASS Web Animations: property <border-image-outset> from [1 2 3px 4px] to [101 102 103px 104px] at (0.3) should be [31 32 33px 34px] +PASS Web Animations: property <border-image-outset> from [1 2 3px 4px] to [101 102 103px 104px] at (0.6) should be [61 62 63px 64px] +PASS Web Animations: property <border-image-outset> from [1 2 3px 4px] to [101 102 103px 104px] at (1) should be [101 102 103px 104px] +PASS Web Animations: property <border-image-outset> from [1 2 3px 4px] to [101 102 103px 104px] at (1.5) should be [151 152 153px 154px] +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-image-outset-interpolation.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-image-outset-interpolation.html index d4726e8..aebadbb 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-image-outset-interpolation.html +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/animations/border-image-outset-interpolation.html
@@ -48,14 +48,14 @@ test_interpolation({ property: 'border-image-outset', from: 'initial', - to: '2px', + to: '2', }, [ - {at: -0.3, expect: '0px'}, // Non-negative - {at: 0, expect: '0px'}, - {at: 0.3, expect: '0.6px'}, - {at: 0.6, expect: '1.2px'}, - {at: 1, expect: '2px'}, - {at: 1.5, expect: '3px'}, + {at: -0.3, expect: '0'}, // Non-negative + {at: 0, expect: '0'}, + {at: 0.3, expect: '0.6'}, + {at: 0.6, expect: '1.2'}, + {at: 1, expect: '2'}, + {at: 1.5, expect: '3'}, ]); test_interpolation({ @@ -74,14 +74,14 @@ test_interpolation({ property: 'border-image-outset', from: 'unset', - to: '2px', + to: '2', }, [ - {at: -0.3, expect: '0px'}, // Non-negative - {at: 0, expect: '0px'}, - {at: 0.3, expect: '0.6px'}, - {at: 0.6, expect: '1.2px'}, - {at: 1, expect: '2px'}, - {at: 1.5, expect: '3px'}, + {at: -0.3, expect: '0'}, // Non-negative + {at: 0, expect: '0'}, + {at: 0.3, expect: '0.6'}, + {at: 0.6, expect: '1.2'}, + {at: 1, expect: '2'}, + {at: 1.5, expect: '3'}, ]); test_interpolation({
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/parsing/border-image-width-computed.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/parsing/border-image-width-computed.html index 98e5616..2c36eda8 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/parsing/border-image-width-computed.html +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/parsing/border-image-width-computed.html
@@ -17,6 +17,7 @@ <body> <div id="target"></div> <script> +test_computed_value("border-image-width", "0"); test_computed_value("border-image-width", "1"); test_computed_value("border-image-width", "auto"); test_computed_value("border-image-width", "10px");
diff --git a/third_party/blink/web_tests/external/wpt/css/css-box/parsing/margin-shorthand.html b/third_party/blink/web_tests/external/wpt/css/css-box/parsing/margin-shorthand.html new file mode 100644 index 0000000..2939279 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-box/parsing/margin-shorthand.html
@@ -0,0 +1,43 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS basic box model: margin sets longhands</title> +<link rel="help" href="https://drafts.csswg.org/css-box-3/#propdef-margin"> +<meta name="assert" content="margin supports the full grammar '<length-percentage>{1,4}'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/shorthand-testcommon.js"></script> +</head> +<body> +<script> +test_shorthand_value('margin', '1px 2px 3px 4px', { + 'margin-top': '1px', + 'margin-right': '2px', + 'margin-bottom': '3px', + 'margin-left': '4px' +}); + +test_shorthand_value('margin', '1px 2px 3px', { + 'margin-top': '1px', + 'margin-right': '2px', + 'margin-bottom': '3px', + 'margin-left': '2px' +}); + +test_shorthand_value('margin', '1px 2px', { + 'margin-top': '1px', + 'margin-right': '2px', + 'margin-bottom': '1px', + 'margin-left': '2px' +}); + +test_shorthand_value('margin', '1px', { + 'margin-top': '1px', + 'margin-right': '1px', + 'margin-bottom': '1px', + 'margin-left': '1px' +}); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-box/parsing/padding-shorthand.html b/third_party/blink/web_tests/external/wpt/css/css-box/parsing/padding-shorthand.html new file mode 100644 index 0000000..dc0139dc --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-box/parsing/padding-shorthand.html
@@ -0,0 +1,43 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS basic box model: padding sets longhands</title> +<link rel="help" href="https://drafts.csswg.org/css-box-3/#propdef-padding"> +<meta name="assert" content="padding supports the full grammar '<length-percentage>{1,4}'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/shorthand-testcommon.js"></script> +</head> +<body> +<script> +test_shorthand_value('padding', '1px 2px 3px 4px', { + 'padding-top': '1px', + 'padding-right': '2px', + 'padding-bottom': '3px', + 'padding-left': '4px' +}); + +test_shorthand_value('padding', '1px 2px 3px', { + 'padding-top': '1px', + 'padding-right': '2px', + 'padding-bottom': '3px', + 'padding-left': '2px' +}); + +test_shorthand_value('padding', '1px 2px', { + 'padding-top': '1px', + 'padding-right': '2px', + 'padding-bottom': '1px', + 'padding-left': '2px' +}); + +test_shorthand_value('padding', '1px', { + 'padding-top': '1px', + 'padding-right': '1px', + 'padding-bottom': '1px', + 'padding-left': '1px' +}); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-flexbox/parsing/flex-flow-shorthand.html b/third_party/blink/web_tests/external/wpt/css/css-flexbox/parsing/flex-flow-shorthand.html new file mode 100644 index 0000000..6ae19bd --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-flexbox/parsing/flex-flow-shorthand.html
@@ -0,0 +1,25 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Flexible Box Layout Module Level 1: flex-flow sets longhands</title> +<link rel="help" href="https://drafts.csswg.org/css-flexbox/#propdef-flex-flow"> +<meta name="assert" content="flex-flow supports the full grammar '<flex-direction> || <flex-wrap>'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/shorthand-testcommon.js"></script> +</head> +<body> +<script> +test_shorthand_value('flex-flow', 'nowrap column', { + 'flex-direction': 'column', + 'flex-wrap': 'nowrap' +}); + +test_shorthand_value('flex-flow', 'wrap row-reverse', { + 'flex-direction': 'row-reverse', + 'flex-wrap': 'wrap' +}); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-flexbox/parsing/flex-shorthand.html b/third_party/blink/web_tests/external/wpt/css/css-flexbox/parsing/flex-shorthand.html new file mode 100644 index 0000000..51e01794 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-flexbox/parsing/flex-shorthand.html
@@ -0,0 +1,51 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Flexible Box Layout Module Level 1: flex sets longhands</title> +<link rel="help" href="https://drafts.csswg.org/css-flexbox/#propdef-flex"> +<meta name="assert" content="flex supports the full grammar 'none | [ <‘flex-grow’> <‘flex-shrink’>? || <‘flex-basis’> ]'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/shorthand-testcommon.js"></script> +</head> +<body> +<script> +test_shorthand_value('flex', 'none', { + 'flex-grow': '0', + 'flex-shrink': '0', + 'flex-basis': 'auto' +}); + +test_shorthand_value('flex', '1', { + 'flex-grow': '1', + 'flex-shrink': '1', + 'flex-basis': '0%' +}); + +test_shorthand_value('flex', '2 3', { + 'flex-grow': '2', + 'flex-shrink': '3', + 'flex-basis': '0%' +}); + +test_shorthand_value('flex', '4 5 6px', { + 'flex-grow': '4', + 'flex-shrink': '5', + 'flex-basis': '6px' +}); + +test_shorthand_value('flex', '7% 8', { + 'flex-grow': '8', + 'flex-shrink': '1', + 'flex-basis': '7%' +}); + +test_shorthand_value('flex', '8 auto', { + 'flex-grow': '8', + 'flex-shrink': '1', + 'flex-basis': 'auto' +}); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-item-dynamic-min-contribution-001.html b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-item-dynamic-min-contribution-001.html new file mode 100644 index 0000000..c4ced6b --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-item-dynamic-min-contribution-001.html
@@ -0,0 +1,39 @@ +<!DOCTYPE html> +<meta charset="utf-8" /> +<title>CSS Grid Layout Test: dynamic minimum contribution</title> +<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com" /> +<link rel="help" href="https://drafts.csswg.org/css-grid/#min-size-contribution"> +<meta name="assert" content="This test checks that grid items are sized correctly when their minimum contribution is dynamically changed with JavaScript." /> +<style> +#grid { + display: grid; + height: 100px; + width: 100px; +} +</style> +<div id="log"></div> +<div id="grid"> + <div id="item"></div> +</div> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +const tests = [ + ["auto", "100px"], + ["0%", "100px"], + ["100%", "100px"], + ["200%", "200px"], + ["300%", "300px"], + ["400px", "400px"], + ["500px", "500px"], +]; +const item = document.getElementById("item"); +for (let [minSize, expectedSize] of tests) { + test(() => { + item.style.minHeight = item.style.minWidth = minSize; + let cs = getComputedStyle(item); + assert_equals(cs.height, expectedSize, "height"); + assert_equals(cs.width, expectedSize, "width"); + }, `Minimum size: ${minSize}`); +} +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-003.html b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-003.html new file mode 100644 index 0000000..03d5d7f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-003.html
@@ -0,0 +1,41 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Grid Layout Test: Grid items with percentage margins</title> +<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com"> +<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins"> +<meta name="assert" content="Checks grid items percentage margins are resolved correctly in a 'auto' sized grid area after changing the item's width and forcing a new layout."> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> +<link rel="stylesheet" href="support/grid.css"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +.container { + font: 25px/1 Ahem; + width: 100px; +} +.child { + margin: 50px; + color: red; +} +.ref { + position: absolute; + z-index: -1; + background: green; + height: 100px; +} +.grid { + background: none; +} +#item { + margin: 50%; + color: green; +} +</style> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div class="container ref"><div class="child">X</div></div> +<div class="container grid"><div class="child" id="item">X</div></div> +<script> + item.offsetLeft; + item.style.width = "0px"; + item.offsetLeft; + item.style.width = "auto"; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-004.html b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-004.html new file mode 100644 index 0000000..52e6f3bf --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-004.html
@@ -0,0 +1,42 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Grid Layout Test: Grid items with percentage margins</title> +<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com"> +<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins"> +<meta name="assert" content="Checks grid items percentage margins are resolved correctly in a 'auto' sized grid area after changing the item's width and forcing a new layout."> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> +<link rel="stylesheet" href="support/grid.css"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +.container { + width: 100px; +} +.child { + width: 25px; + height: 25px; + margin: 50px; + background: red; +} +.ref { + position: absolute; + z-index: -1; + background: green; + height: 100px; +} +.grid { + background: none; +} +#item { + margin: 50%; + background: green; +} +</style> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div class="container ref"><div class="child"></div></div> +<div class="container grid"><div class="child" id="item"></div></div> +<script> + item.offsetLeft; + item.style.width = "0px"; + item.offsetLeft; + item.style.width = "25px"; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-005.html b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-005.html new file mode 100644 index 0000000..9cff92d --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-005.html
@@ -0,0 +1,42 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Grid Layout Test: Grid items with percentage margins</title> +<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com"> +<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins"> +<meta name="assert" content="Checks grid items percentage margins are resolved correctly in a 'auto' sized grid area after changing the item's width and forcing a new layout."> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> +<link rel="stylesheet" href="support/grid.css"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +.container { + width: 100px; +} +.child { + width: 25px; + height: 25px; + margin: 50px; + background: red; +} +.ref { + position: absolute; + z-index: -1; + background: green; + height: 100px; +} +.grid { + background: none; +} +#item { + margin: 50%; + background: green; +} +</style> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div class="container ref"><div class="child"></div></div> +<div class="container grid"><div class="child" id="item"></div></div> +<script> + item.offsetLeft; + item.style.margin = "100%"; + item.offsetLeft; + item.style.margin = "50%"; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-006.html b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-006.html new file mode 100644 index 0000000..04d30e3 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-006.html
@@ -0,0 +1,42 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Grid Layout Test: Grid items with percentage margins</title> +<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com"> +<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins"> +<meta name="assert" content="Checks grid items percentage margins are resolved correctly in a 'auto' sized grid area after changing the item's width and forcing a new layout."> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> +<link rel="stylesheet" href="support/grid.css"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +.container { + width: 100px; +} +.child { + min-width: 25px; + min-height: 25px; + margin: 50px; + background: red; +} +.ref { + position: absolute; + z-index: -1; + background: green; + height: 100px; +} +.grid { + background: none; +} +#item { + margin: 50%; + background: green; +} +</style> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div class="container ref"><div class="child"></div></div> +<div class="container grid"><div class="child" id="item"></div></div> +<script> + item.offsetLeft; + item.style.margin = "100%"; + item.offsetLeft; + item.style.margin = "50%"; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-007.html b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-007.html new file mode 100644 index 0000000..2906fe06 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-007.html
@@ -0,0 +1,42 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Grid Layout Test: Grid items with percentage margins</title> +<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com"> +<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins"> +<meta name="assert" content="Checks grid items percentage margins are resolved correctly in a 'auto' sized grid area after changing the item's width and forcing a new layout."> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> +<link rel="stylesheet" href="support/grid.css"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +.container { + font: 25px/1 Ahem; + width: 100px; +} +.child { + margin: 0px 50px; + color: red; +} +.ref { + position: absolute; + z-index: -1; + background: green; + height: 100px; +} +.grid { + background: none; + grid-template-rows: 100px; +} +#item { + margin: 0px 50%; + color: green; +} +</style> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div class="container ref"><div class="child">X</div></div> +<div class="container grid"><div class="child" id="item">X</div></div> +<script> + item.offsetLeft; + item.style.width = "0px"; + item.offsetLeft; + item.style.width = "auto"; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-008.html b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-008.html new file mode 100644 index 0000000..7bd2e0f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-008.html
@@ -0,0 +1,43 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Grid Layout Test: Grid items with percentage margins</title> +<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com"> +<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins"> +<meta name="assert" content="Checks grid items percentage margins are resolved correctly in a 'auto' sized grid area after changing the item's width and forcing a new layout."> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> +<link rel="stylesheet" href="support/grid.css"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +.container { + width: 100px; +} +.child { + width: 25px; + height: 25px; + margin: 0px 50px; + background: red; +} +.ref { + position: absolute; + z-index: -1; + background: green; + height: 100px; +} +.grid { + background: none; + grid-template-rows: 100px; +} +#item { + margin: 0px 50%; + background: green; +} +</style> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div class="container ref"><div class="child"></div></div> +<div class="container grid"><div class="child" id="item"></div></div> +<script> + item.offsetLeft; + item.style.width = "0px"; + item.offsetLeft; + item.style.width = "25px"; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-009.html b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-009.html new file mode 100644 index 0000000..70a6c23 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-009.html
@@ -0,0 +1,43 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Grid Layout Test: Grid items with percentage margins</title> +<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com"> +<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins"> +<meta name="assert" content="Checks grid items percentage margins are resolved correctly in a 'auto' sized grid area after changing the item's width and forcing a new layout."> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> +<link rel="stylesheet" href="support/grid.css"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +.container { + width: 100px; +} +.child { + width: 25px; + height: 25px; + margin: 0px 50px; + background: red; +} +.ref { + position: absolute; + z-index: -1; + background: green; + height: 100px; +} +.grid { + background: none; + grid-template-rows: 100px; +} +#item { + margin: 0px 50%; + background: green; +} +</style> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div class="container ref"><div class="child"></div></div> +<div class="container grid"><div class="child" id="item"></div></div> +<script> + item.offsetLeft; + item.style.margin = "0px 100%"; + item.offsetLeft; + item.style.margin = "0px 50%"; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-010.html b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-010.html new file mode 100644 index 0000000..34352f6 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-010.html
@@ -0,0 +1,43 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Grid Layout Test: Grid items with percentage margins</title> +<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com"> +<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins"> +<meta name="assert" content="Checks grid items percentage margins are resolved correctly in a 'auto' sized grid area after changing the item's width and forcing a new layout."> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> +<link rel="stylesheet" href="support/grid.css"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +.container { + width: 100px; +} +.child { + min-width: 25px; + min-height: 25px; + margin: 0px 50px; + background: red; +} +.ref { + position: absolute; + z-index: -1; + background: green; + height: 100px; +} +.grid { + background: none; + grid-template-rows: 100px; +} +#item { + margin: 0px 50%; + background: green; +} +</style> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div class="container ref"><div class="child"></div></div> +<div class="container grid"><div class="child" id="item"></div></div> +<script> + item.offsetLeft; + item.style.margin = "0px 100%"; + item.offsetLeft; + item.style.margin = "0px 50%"; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-011.html b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-011.html new file mode 100644 index 0000000..36bd208 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-011.html
@@ -0,0 +1,41 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Grid Layout Test: Grid items with percentage margins</title> +<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com"> +<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins"> +<meta name="assert" content="Checks grid items percentage margins are resolved correctly in a 'auto' sized grid area after changing the item's width and forcing a new layout."> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> +<link rel="stylesheet" href="support/grid.css"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +.container { + font: 25px/1 Ahem; + width: 100px; +} +.child { + margin: 50px 0px; + color: red; +} +.ref { + position: absolute; + z-index: -1; + background: green; + height: 100px; +} +.grid { + background: none; +} +#item { + margin: 50% 0px; + color: green; +} +</style> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div class="container ref"><div class="child">X</div></div> +<div class="container grid"><div class="child" id="item">X</div></div> +<script> + item.offsetLeft; + item.style.width = "0px"; + item.offsetLeft; + item.style.width = "auto"; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-012.html b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-012.html new file mode 100644 index 0000000..9cdc153 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-012.html
@@ -0,0 +1,42 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Grid Layout Test: Grid items with percentage margins</title> +<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com"> +<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins"> +<meta name="assert" content="Checks grid items percentage margins are resolved correctly in a 'auto' sized grid area after changing the item's width and forcing a new layout."> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> +<link rel="stylesheet" href="support/grid.css"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +.container { + width: 100px; +} +.child { + width: 25px; + height: 25px; + margin: 50px 0px; + background: red; +} +.ref { + position: absolute; + z-index: -1; + background: green; + height: 100px; +} +.grid { + background: none; +} +#item { + margin: 50% 0px; + background: green; +} +</style> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div class="container ref"><div class="child"></div></div> +<div class="container grid"><div class="child" id="item"></div></div> +<script> + item.offsetLeft; + item.style.width = "0px"; + item.offsetLeft; + item.style.width = "25px"; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-013.html b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-013.html new file mode 100644 index 0000000..581415b8 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-013.html
@@ -0,0 +1,42 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Grid Layout Test: Grid items with percentage margins</title> +<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com"> +<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins"> +<meta name="assert" content="Checks grid items percentage margins are resolved correctly in a 'auto' sized grid area after changing the item's width and forcing a new layout."> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> +<link rel="stylesheet" href="support/grid.css"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +.container { + width: 100px; +} +.child { + width: 25px; + height: 25px; + margin: 50px 0px; + background: red; +} +.ref { + position: absolute; + z-index: -1; + background: green; + height: 100px; +} +.grid { + background: none; +} +#item { + margin: 50% 0px; + background: green; +} +</style> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div class="container ref"><div class="child"></div></div> +<div class="container grid"><div class="child" id="item"></div></div> +<script> + item.offsetLeft; + item.style.margin = "100% 0px"; + item.offsetLeft; + item.style.margin = "50% 0px"; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-014.html b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-014.html new file mode 100644 index 0000000..5766e60 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-margins-014.html
@@ -0,0 +1,43 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Grid Layout Test: Grid items with percentage margins</title> +<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com"> +<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins"> +<meta name="assert" content="Checks grid items percentage margins are resolved correctly in a 'auto' sized grid area after changing the item's width and forcing a new layout."> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> +<link rel="stylesheet" href="support/grid.css"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +.container { + width: 100px; +} +.child { + min-width: 25px; + min-height: 25px; + margin: 50px 0px; + background: red; +} +.ref { + position: absolute; + z-index: -1; + background: green; + height: 100px; +} +.grid { + background: none; + grid-template-columns: 100px; +} +#item { + margin: 50% 0px; + background: green; +} +</style> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div class="container ref"><div class="child"></div></div> +<div class="container grid"><div class="child" id="item"></div></div> +<script> + item.offsetLeft; + item.style.margin = "100% 0px"; + item.offsetLeft; + item.style.margin = "50% 0px"; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-003.html b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-003.html new file mode 100644 index 0000000..d85a6c1 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-003.html
@@ -0,0 +1,41 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Grid Layout Test: Grid items with percentage paddings</title> +<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com"> +<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins"> +<meta name="assert" content="Checks grid items percentage paddings are resolved correctly in a 'auto' sized grid area after changing the item's width and forcing a new layout."> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> +<link rel="stylesheet" href="support/grid.css"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +.container { + font: 80px/1 Ahem; + width: 100px; +} +.child { + padding: 10px; + color: red; +} +.ref { + position: absolute; + z-index: -1; + background: red; + height: 100px; +} +.grid { + background: green; +} +#item { + padding: 10%; + color: green; +} +</style> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div class="container ref"><div class="child">X</div></div> +<div class="container grid"><div class="child" id="item">X</div></div> +<script> + item.offsetLeft; + item.style.width = "0px"; + item.offsetLeft; + item.style.width = "auto"; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-004.html b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-004.html new file mode 100644 index 0000000..26302da --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-004.html
@@ -0,0 +1,42 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Grid Layout Test: Grid items with percentage paddings</title> +<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com"> +<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins"> +<meta name="assert" content="Checks grid items percentage paddings are resolved correctly in a 'auto' sized grid area after changing the item's width and forcing a new layout."> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> +<link rel="stylesheet" href="support/grid.css"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +.container { + width: 100px; +} +.child { + width: 80px; + height: 80px; + padding: 10px; + background: red; +} +.ref { + position: absolute; + z-index: -1; + background: none; + height: 100px; +} +.grid { + background: none; +} +#item { + padding: 10%; + background: green; +} +</style> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div class="container ref"><div class="child"></div></div> +<div class="container grid"><div class="child" id="item"></div></div> +<script> + item.offsetLeft; + item.style.width = "0px"; + item.offsetLeft; + item.style.width = "80px"; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-005.html b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-005.html new file mode 100644 index 0000000..151b604f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-005.html
@@ -0,0 +1,41 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Grid Layout Test: Grid items with percentage paddings</title> +<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com"> +<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins"> +<meta name="assert" content="Checks grid items percentage paddings are resolved correctly in a 'auto' sized grid area after changing the item's width and forcing a new layout."> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> +<link rel="stylesheet" href="support/grid.css"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +.container { + width: 100px; +} +.child { + width: 80px; + height: 80px; + padding: 10px; + background: red; +} +.ref { + position: absolute; + z-index: -1; + height: 100px; +} +.grid { + background: none; +} +#item { + padding: 10%; + background: green; +} +</style> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div class="container ref"><div class="child"></div></div> +<div class="container grid"><div class="child" id="item"></div></div> +<script> + item.offsetLeft; + item.style.padding = "50%"; + item.offsetLeft; + item.style.padding = "10%"; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-006.html b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-006.html new file mode 100644 index 0000000..bcbc7ce --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-006.html
@@ -0,0 +1,41 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Grid Layout Test: Grid items with percentage paddings</title> +<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com"> +<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins"> +<meta name="assert" content="Checks grid items percentage paddings are resolved correctly in a 'auto' sized grid area after changing the item's width and forcing a new layout."> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> +<link rel="stylesheet" href="support/grid.css"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +.container { + width: 100px; +} +.child { + min-width: 80px; + min-height: 80px; + padding: 10px; + background: red; +} +.ref { + position: absolute; + z-index: -1; + height: 100px; +} +.grid { + background: none; +} +#item { + padding: 10%; + background: green; +} +</style> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div class="container ref"><div class="child"></div></div> +<div class="container grid"><div class="child" id="item"></div></div> +<script> + item.offsetLeft; + item.style.padding = "50%"; + item.offsetLeft; + item.style.padding = "10%"; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-007.html b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-007.html new file mode 100644 index 0000000..d4cf80c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-007.html
@@ -0,0 +1,42 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Grid Layout Test: Grid items with percentage paddings</title> +<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com"> +<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins"> +<meta name="assert" content="Checks grid items percentage paddings are resolved correctly in a 'auto' sized grid area after changing the item's width and forcing a new layout."> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> +<link rel="stylesheet" href="support/grid.css"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +.container { + font: 80px/1 Ahem; + width: 100px; +} +.child { + padding: 0px 10px; + color: red; +} +.ref { + position: absolute; + z-index: -1; + background: red; + height: 100px; +} +.grid { + background: green; + grid-template-rows: 100px; +} +#item { + padding: 0px 10%; + color: green; +} +</style> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div class="container ref"><div class="child">X</div></div> +<div class="container grid"><div class="child" id="item">X</div></div> +<script> + item.offsetLeft; + item.style.width = "0px"; + item.offsetLeft; + item.style.width = "auto"; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-008.html b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-008.html new file mode 100644 index 0000000..38f766b --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-008.html
@@ -0,0 +1,43 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Grid Layout Test: Grid items with percentage paddings</title> +<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com"> +<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins"> +<meta name="assert" content="Checks grid items percentage paddings are resolved correctly in a 'auto' sized grid area after changing the item's width and forcing a new layout."> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> +<link rel="stylesheet" href="support/grid.css"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +.container { + width: 100px; +} +.child { + width: 80px; + height: 100px; + padding: 0px 10px; + background: red; +} +.ref { + position: absolute; + z-index: -1; + background: none; + height: 100px; +} +.grid { + background: none; + grid-template-rows: 100px; +} +#item { + padding: 0px 10%; + background: green; +} +</style> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div class="container ref"><div class="child"></div></div> +<div class="container grid"><div class="child" id="item"></div></div> +<script> + item.offsetLeft; + item.style.width = "0px"; + item.offsetLeft; + item.style.width = "80px"; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-009.html b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-009.html new file mode 100644 index 0000000..eb1d1f47 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-009.html
@@ -0,0 +1,43 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Grid Layout Test: Grid items with percentage paddings</title> +<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com"> +<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins"> +<meta name="assert" content="Checks grid items percentage paddings are resolved correctly in a 'auto' sized grid area after changing the item's width and forcing a new layout."> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> +<link rel="stylesheet" href="support/grid.css"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +.container { + width: 100px; +} +.child { + width: 80px; + height: 100px; + padding: 0px 10px; + background: red; +} +.ref { + position: absolute; + z-index: -1; + height: 100px; + grid-template-rows: 100px; +} +.grid { + background: none; + grid-template-rows: 100px; +} +#item { + padding: 0px 10%; + background: green; +} +</style> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div class="container ref"><div class="child"></div></div> +<div class="container grid"><div class="child" id="item"></div></div> +<script> + item.offsetLeft; + item.style.padding = "0px 50%"; + item.offsetLeft; + item.style.padding = "0px 10%"; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-010.html b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-010.html new file mode 100644 index 0000000..ecd430c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-010.html
@@ -0,0 +1,42 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Grid Layout Test: Grid items with percentage paddings</title> +<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com"> +<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins"> +<meta name="assert" content="Checks grid items percentage paddings are resolved correctly in a 'auto' sized grid area after changing the item's width and forcing a new layout."> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> +<link rel="stylesheet" href="support/grid.css"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +.container { + width: 100px; +} +.child { + min-width: 80px; + min-height: 100px; + padding: 0px 10px; + background: red; +} +.ref { + position: absolute; + z-index: -1; + height: 100px; +} +.grid { + background: none; + grid-template-rows: 100px; +} +#item { + padding: 0px 10%; + background: green; +} +</style> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div class="container ref"><div class="child"></div></div> +<div class="container grid"><div class="child" id="item"></div></div> +<script> + item.offsetLeft; + item.style.padding = "0px 50%"; + item.offsetLeft; + item.style.padding = "0px 10%"; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-011.html b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-011.html new file mode 100644 index 0000000..e394ced --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-011.html
@@ -0,0 +1,41 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Grid Layout Test: Grid items with percentage paddings</title> +<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com"> +<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins"> +<meta name="assert" content="Checks grid items percentage paddings are resolved correctly in a 'auto' sized grid area after changing the item's width and forcing a new layout."> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> +<link rel="stylesheet" href="support/grid.css"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +.container { + font: 80px/1 Ahem; + width: 100px; +} +.child { + padding: 10px 0px; + color: red; +} +.ref { + position: absolute; + z-index: -1; + background: red; + height: 100px; +} +.grid { + background: green; +} +#item { + padding: 10px 0px; + color: green; +} +</style> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div class="container ref"><div class="child">X</div></div> +<div class="container grid"><div class="child" id="item">X</div></div> +<script> + item.offsetLeft; + item.style.width = "0px"; + item.offsetLeft; + item.style.width = "auto"; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-012.html b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-012.html new file mode 100644 index 0000000..07b2d27 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-012.html
@@ -0,0 +1,42 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Grid Layout Test: Grid items with percentage paddings</title> +<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com"> +<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins"> +<meta name="assert" content="Checks grid items percentage paddings are resolved correctly in a 'auto' sized grid area after changing the item's width and forcing a new layout."> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> +<link rel="stylesheet" href="support/grid.css"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +.container { + width: 100px; +} +.child { + width: 100px; + height: 80px; + padding: 10px 0px; + background: red; +} +.ref { + position: absolute; + z-index: -1; + background: none; + height: 100px; +} +.grid { + background: none; +} +#item { + padding: 10% 0px; + background: green; +} +</style> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div class="container ref"><div class="child"></div></div> +<div class="container grid"><div class="child" id="item"></div></div> +<script> + item.offsetLeft; + item.style.height = "0px"; + item.offsetLeft; + item.style.height = "80px"; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-013.html b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-013.html new file mode 100644 index 0000000..9b6c2bfe --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-013.html
@@ -0,0 +1,41 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Grid Layout Test: Grid items with percentage paddings</title> +<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com"> +<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins"> +<meta name="assert" content="Checks grid items percentage paddings are resolved correctly in a 'auto' sized grid area after changing the item's width and forcing a new layout."> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> +<link rel="stylesheet" href="support/grid.css"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +.container { + width: 100px; +} +.child { + width: 100px; + height: 80px; + padding: 10px 0px; + background: red; +} +.ref { + position: absolute; + z-index: -1; + height: 100px; +} +.grid { + background: none; +} +#item { + padding: 10% 0px; + background: green; +} +</style> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div class="container ref"><div class="child"></div></div> +<div class="container grid"><div class="child" id="item"></div></div> +<script> + item.offsetLeft; + item.style.padding = "50% 0px"; + item.offsetLeft; + item.style.padding = "10% 0px"; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-014.html b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-014.html new file mode 100644 index 0000000..9e67960 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/grid-items/grid-items-percentage-paddings-014.html
@@ -0,0 +1,41 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Grid Layout Test: Grid items with percentage paddings</title> +<link rel="author" title="Javier Fernandez Garcia-Boente" href="mailto:jfernandez@igalia.com"> +<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins"> +<meta name="assert" content="Checks grid items percentage paddings are resolved correctly in a 'auto' sized grid area after changing the item's width and forcing a new layout."> +<link rel="match" href="../../reference/ref-filled-green-100px-square.xht"> +<link rel="stylesheet" href="support/grid.css"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" /> +<style> +.container { + width: 100px; +} +.child { + min-width: 100px; + min-height: 80px; + padding: 10px 0px; + background: red; +} +.ref { + position: absolute; + z-index: -1; + height: 100px; +} +.grid { + background: none; +} +#item { + padding: 10% 0px; + background: green; +} +</style> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div class="container ref"><div class="child"></div></div> +<div class="container grid"><div class="child" id="item"></div></div> +<script> + item.offsetLeft; + item.style.padding = "50% 0px"; + item.offsetLeft; + item.style.padding = "10% 0px"; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/parsing/list-style-shorthand.sub.html b/third_party/blink/web_tests/external/wpt/css/css-lists/parsing/list-style-shorthand.sub.html new file mode 100644 index 0000000..140df208 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-lists/parsing/list-style-shorthand.sub.html
@@ -0,0 +1,21 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Lists: list-style sets longhands</title> +<link rel="help" href="https://drafts.csswg.org/css-lists-3/#propdef-list-style"> +<meta name="assert" content="list-style supports the full grammar '<'list-style-position'> || <'list-style-image'> || <'list-style-type'>'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/shorthand-testcommon.js"></script> +</head> +<body> +<script> +test_shorthand_value('list-style', 'square url("https://{{host}}/") inside', { + 'list-style-position': 'inside', + 'list-style-image': 'url("https://{{host}}/")', + 'list-style-type': 'square' +}); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/inset-shorthand.html b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/inset-shorthand.html new file mode 100644 index 0000000..455787912 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-logical/parsing/inset-shorthand.html
@@ -0,0 +1,43 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Logical Properties and Values: inset sets longhands</title> +<link rel="help" href="https://drafts.csswg.org/css-logical/#propdef-inset"> +<meta name="assert" content="inset supports the full grammar '<'top'>{1,4}'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/shorthand-testcommon.js"></script> +</head> +<body> +<script> +test_shorthand_value('inset', '1px 2px 3px 4px', { + 'top': '1px', + 'right': '2px', + 'bottom': '3px', + 'left': '4px' +}); + +test_shorthand_value('inset', '1px 2px 3px', { + 'top': '1px', + 'right': '2px', + 'bottom': '3px', + 'left': '2px' +}); + +test_shorthand_value('inset', '1px 2px', { + 'top': '1px', + 'right': '2px', + 'bottom': '1px', + 'left': '2px' +}); + +test_shorthand_value('inset', '1px', { + 'top': '1px', + 'right': '1px', + 'bottom': '1px', + 'left': '1px' +}); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text-decor/parsing/text-decoration-shorthand.html b/third_party/blink/web_tests/external/wpt/css/css-text-decor/parsing/text-decoration-shorthand.html new file mode 100644 index 0000000..904313f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text-decor/parsing/text-decoration-shorthand.html
@@ -0,0 +1,21 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Text Decoration: text-decoration sets longhands</title> +<link rel="help" href="https://drafts.csswg.org/css-text-decor-3/#propdef-text-decoration"> +<meta name="assert" content="text-decoration supports the full grammar '<‘text-decoration-line’> || <‘text-decoration-style’> || <‘text-decoration-color’>'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/shorthand-testcommon.js"></script> +</head> +<body> +<script> +test_shorthand_value('text-decoration', 'overline dotted green', { + 'text-decoration-line': 'overline', + 'text-decoration-style': 'dotted', + 'text-decoration-color': 'green' +}); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transitions/parsing/transition-delay-invalid.html b/third_party/blink/web_tests/external/wpt/css/css-transitions/parsing/transition-delay-invalid.html index b34d505..4b7a1432 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-transitions/parsing/transition-delay-invalid.html +++ b/third_party/blink/web_tests/external/wpt/css/css-transitions/parsing/transition-delay-invalid.html
@@ -14,6 +14,9 @@ test_invalid_value("transition-delay", 'infinite'); test_invalid_value("transition-delay", '0'); test_invalid_value("transition-delay", '500ms 0.5s'); + +test_invalid_value("transition-delay", '-3s, initial'); +test_invalid_value("transition-delay", 'initial, -3s'); </script> </body> </html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transitions/parsing/transition-duration-invalid.html b/third_party/blink/web_tests/external/wpt/css/css-transitions/parsing/transition-duration-invalid.html index fd0f341f..4474089 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-transitions/parsing/transition-duration-invalid.html +++ b/third_party/blink/web_tests/external/wpt/css/css-transitions/parsing/transition-duration-invalid.html
@@ -14,6 +14,9 @@ test_invalid_value("transition-duration", 'infinite'); test_invalid_value("transition-duration", '-500ms'); test_invalid_value("transition-duration", '1s 2s'); + +test_invalid_value("transition-duration", '1s, initial'); +test_invalid_value("transition-duration", 'initial, 1s'); </script> </body> </html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transitions/parsing/transition-invalid.html b/third_party/blink/web_tests/external/wpt/css/css-transitions/parsing/transition-invalid.html new file mode 100644 index 0000000..64310b1 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-transitions/parsing/transition-invalid.html
@@ -0,0 +1,24 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Transitions: parsing transition with invalid values</title> +<link rel="help" href="https://drafts.csswg.org/css-transitions/#transition-shorthand-property"> +<meta name="assert" content="transition supports only the grammar '<single-transition> #'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/parsing-testcommon.js"></script> +</head> +<body> +<script> +// <single-transition> = [ none | <single-transition-property> ] || +// <time> || <easing-function> || <time> +test_invalid_value("transition", "1s 2s 3s"); +test_invalid_value("transition", "-1s -2s"); + +test_invalid_value("transition", "steps(1) steps(2)"); + +test_invalid_value("transition", "none top"); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transitions/parsing/transition-property-invalid.html b/third_party/blink/web_tests/external/wpt/css/css-transitions/parsing/transition-property-invalid.html index 903a206..715e13d 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-transitions/parsing/transition-property-invalid.html +++ b/third_party/blink/web_tests/external/wpt/css/css-transitions/parsing/transition-property-invalid.html
@@ -14,6 +14,9 @@ test_invalid_value("transition-property", 'one two three'); test_invalid_value("transition-property", '1, 2, 3'); test_invalid_value("transition-property", 'none, one'); + +test_invalid_value("transition-property", 'initial, top'); +test_invalid_value("transition-property", 'top, initial'); </script> </body> </html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transitions/parsing/transition-shorthand.html b/third_party/blink/web_tests/external/wpt/css/css-transitions/parsing/transition-shorthand.html new file mode 100644 index 0000000..caffb39 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-transitions/parsing/transition-shorthand.html
@@ -0,0 +1,36 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Transitions: transition sets longhands</title> +<link rel="help" href="https://drafts.csswg.org/css-transitions/#transition-shorthand-property"> +<meta name="assert" content="transition supports the full grammar '<single-transition> #'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/shorthand-testcommon.js"></script> +</head> +<body> +<script> +test_shorthand_value('transition', '1s -3s cubic-bezier(0, -2, 1, 3) top', { + 'transition-property': 'top', + 'transition-duration': '1s', + 'transition-timing-function': 'cubic-bezier(0, -2, 1, 3)', + 'transition-delay': '-3s' +}); + +test_shorthand_value('transition', '1s -3s, cubic-bezier(0, -2, 1, 3) top', { + 'transition-property': 'all, top', + 'transition-duration': '1s, 0s', + 'transition-timing-function': 'ease, cubic-bezier(0, -2, 1, 3)', + 'transition-delay': '-3s, 0s' +}); + +test_shorthand_value('transition', 'cubic-bezier(0, -2, 1, 3) top, 1s -3s', { + 'transition-property': 'top, all', + 'transition-duration': '0s, 1s', + 'transition-timing-function': 'cubic-bezier(0, -2, 1, 3), ease', + 'transition-delay': '0s, -3s' +}); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transitions/parsing/transition-timing-function-computed.html b/third_party/blink/web_tests/external/wpt/css/css-transitions/parsing/transition-timing-function-computed.html index e57856b..fa03b22 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-transitions/parsing/transition-timing-function-computed.html +++ b/third_party/blink/web_tests/external/wpt/css/css-transitions/parsing/transition-timing-function-computed.html
@@ -26,7 +26,6 @@ test_computed_value("transition-timing-function", "step-start", "steps(1, start)"); test_computed_value("transition-timing-function", "step-end", "steps(1)"); -test_computed_value("transition-timing-function", "steps(4)"); test_computed_value("transition-timing-function", "steps(4, start)"); test_computed_value("transition-timing-function", "steps(2, end)", "steps(2)"); test_computed_value("transition-timing-function", "steps(2, jump-start)");
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transitions/parsing/transition-timing-function-invalid.html b/third_party/blink/web_tests/external/wpt/css/css-transitions/parsing/transition-timing-function-invalid.html index d736ef0..c69b7e75 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-transitions/parsing/transition-timing-function-invalid.html +++ b/third_party/blink/web_tests/external/wpt/css/css-transitions/parsing/transition-timing-function-invalid.html
@@ -31,6 +31,8 @@ test_invalid_value("transition-timing-function", "steps(0, jump-both)"); test_invalid_value("transition-timing-function", "steps(1, jump-none)"); +test_invalid_value("transition-timing-function", "initial, cubic-bezier(0, -2, 1, 3)"); +test_invalid_value("transition-timing-function", "cubic-bezier(0, -2, 1, 3), initial"); </script> </body> </html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transitions/parsing/transition-valid.html b/third_party/blink/web_tests/external/wpt/css/css-transitions/parsing/transition-valid.html new file mode 100644 index 0000000..c4651f5 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-transitions/parsing/transition-valid.html
@@ -0,0 +1,29 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS Transitions: parsing transition with valid values</title> +<link rel="help" href="https://drafts.csswg.org/css-transitions/#transition-shorthand-property"> +<meta name="assert" content="transition supports the full grammar '<single-transition> #'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/parsing-testcommon.js"></script> +</head> +<body> +<script> +// <single-transition> = [ none | <single-transition-property> ] || +// <time> || <easing-function> || <time> +test_valid_value("transition", "1s", ["1s", "all 1s ease 0s"]); +test_valid_value("transition", "cubic-bezier(0, -2, 1, 3)", ["cubic-bezier(0, -2, 1, 3)", "all 0s cubic-bezier(0, -2, 1, 3) 0s"]); +test_valid_value("transition", "1s -3s", ["1s -3s", "all 1s ease -3s"]); +test_valid_value("transition", "none", ["none", "none 0s ease 0s"]); +test_valid_value("transition", "top", ["top", "top 0s ease 0s"]); + +test_valid_value("transition", "1s -3s cubic-bezier(0, -2, 1, 3) top", "top 1s cubic-bezier(0, -2, 1, 3) -3s"); +test_valid_value("transition", "1s -3s, cubic-bezier(0, -2, 1, 3) top", ["1s -3s, top cubic-bezier(0, -2, 1, 3)", "all 1s ease -3s, top 0s cubic-bezier(0, -2, 1, 3) 0s"]); + +// TODO: Add test with a single negative time. +// TODO: Add test with a single timing-function keyword. +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ui/parsing/outline-shorthand.html b/third_party/blink/web_tests/external/wpt/css/css-ui/parsing/outline-shorthand.html new file mode 100644 index 0000000..01239e19 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-ui/parsing/outline-shorthand.html
@@ -0,0 +1,22 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +<title>CSS UI Level 3: outline sets longhands</title> +<link rel="help" href="https://drafts.csswg.org/css-ui-3/#outline"> +<link rel="help" href="https://drafts.csswg.org/cssom/#serializing-css-values"> +<meta name="assert" content="outline supports the full grammar '<outline-color> || <outline> || <outline>'."> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/css/support/shorthand-testcommon.js"></script> +</head> +<body> +<script> +test_shorthand_value('outline', '3px ridge blue', { + 'outline-color': 'blue', + 'outline-style': 'ridge', + 'outline-width': '3px' +}); +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/mediaqueries/aspect-ratio-serialization-expected.txt b/third_party/blink/web_tests/external/wpt/css/mediaqueries/aspect-ratio-serialization-expected.txt new file mode 100644 index 0000000..551aadd1 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/mediaqueries/aspect-ratio-serialization-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL <ratio> serializes with spaces around the integer. assert_equals: expected "(aspect-ratio: 1 / 3)" but got "(aspect-ratio: 1/3)" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/css/mediaqueries/aspect-ratio-serialization.html b/third_party/blink/web_tests/external/wpt/css/mediaqueries/aspect-ratio-serialization.html new file mode 100644 index 0000000..cce35592 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/mediaqueries/aspect-ratio-serialization.html
@@ -0,0 +1,13 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Media Queries Test: 'aspect-ratio' serializes with spaces around ' / '.</title> +<link rel="help" href="https://drafts.csswg.org/cssom/#serialize-a-css-component-value"> +<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez"> +<link rel="author" href="https://mozilla.org" title="Mozilla"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +test(function() { + assert_equals(matchMedia("(aspect-ratio: 1/3)").media, "(aspect-ratio: 1 / 3)"); +}, "<ratio> serializes with spaces around the integer."); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/motion/animation/offset-interpolation.html b/third_party/blink/web_tests/external/wpt/css/motion/animation/offset-interpolation.html index 04f4d4b3..2ee011bd 100644 --- a/third_party/blink/web_tests/external/wpt/css/motion/animation/offset-interpolation.html +++ b/third_party/blink/web_tests/external/wpt/css/motion/animation/offset-interpolation.html
@@ -57,9 +57,9 @@ to: 'path("M0 0H 300") 600px 0deg', method: 'CSS Animations', }, [ - {at: -0.3, expect: 'path("M0 0H 170") 470px auto'}, - {at: 0, expect: 'path("M0 0H 200") 500px auto'}, - {at: 0.3, expect: 'path("M0 0H 230") 530px auto'}, + {at: -0.3, expect: 'path("M0 0H 170") 470px'}, + {at: 0, expect: 'path("M0 0H 200") 500px'}, + {at: 0.3, expect: 'path("M0 0H 230") 530px'}, {at: 0.6, expect: 'path("M0 0H 260") 560px 0deg'}, {at: 1, expect: 'path("M0 0H 300") 600px 0deg'}, {at: 1.5, expect: 'path("M0 0H 350") 650px 0deg'}, @@ -85,9 +85,9 @@ to: 'path("M0 0H 300") 600px 0deg', method: 'Web Animations', }, [ - {at: -0.3, expect: 'path("M0 0V 200") 470px auto'}, - {at: 0, expect: 'path("M0 0V 200") 500px auto'}, - {at: 0.3, expect: 'path("M0 0V 200") 530px auto'}, + {at: -0.3, expect: 'path("M0 0V 200") 470px'}, + {at: 0, expect: 'path("M0 0V 200") 500px'}, + {at: 0.3, expect: 'path("M0 0V 200") 530px'}, {at: 0.6, expect: 'path("M0 0H 300") 560px 0deg'}, {at: 1, expect: 'path("M0 0H 300") 600px 0deg'}, {at: 1.5, expect: 'path("M0 0H 300") 650px 0deg'},
diff --git a/third_party/blink/web_tests/external/wpt/css/motion/parsing/offset-parsing-valid-expected.txt b/third_party/blink/web_tests/external/wpt/css/motion/parsing/offset-parsing-valid-expected.txt new file mode 100644 index 0000000..2a04307 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/motion/parsing/offset-parsing-valid-expected.txt
@@ -0,0 +1,32 @@ +This is a testharness.js-based test. +PASS e.style['offset'] = "100px none auto 90deg" should set the property value +PASS e.style['offset'] = "100px" should set the property value +PASS e.style['offset'] = "auto none reverse" should set the property value +PASS e.style['offset'] = "auto" should set the property value +PASS e.style['offset'] = "center bottom path(\"M 1 2 V 3 Z\")" should set the property value +PASS e.style['offset'] = "center center path(\"M 0 0 L 100 100 M 100 200 L 200 200 Z L 300 300 Z\") 100% 90deg / left bottom" should set the property value +PASS e.style['offset'] = "left bottom ray(0rad closest-side) 10px auto 30deg / right bottom" should set the property value +PASS e.style['offset'] = "left top" should set the property value +PASS e.style['offset'] = "none 30deg reverse" should set the property value +PASS e.style['offset'] = "none 50px reverse 30deg" should set the property value +FAIL e.style['offset'] = "none calc(10px + 20%) auto" should set the property value assert_equals: serialization should be canonical expected "none calc(20% + 10px)" but got "none calc(10px + 20%) auto" +PASS e.style['offset'] = "none reverse" should set the property value +FAIL e.style['offset'] = "path(\"M 0 0 H 1\") -200% auto" should set the property value assert_equals: serialization should be canonical expected "path(\"M 0 0 H 1\") -200%" but got "path(\"M 0 0 H 1\") -200% auto" +PASS e.style['offset'] = "path(\"M 0 0 H 1\") -200%" should set the property value +PASS e.style['offset'] = "path('M 0 0 H 1') 50px" should set the property value +FAIL e.style['offset'] = "path(\"M 0 0 H 1\") auto" should set the property value assert_equals: serialization should be canonical expected "path(\"M 0 0 H 1\")" but got "path(\"M 0 0 H 1\") auto" +FAIL e.style['offset'] = "path(\"M 0 0 H 1\") auto 0deg" should set the property value assert_equals: serialization should be canonical expected "path(\"M 0 0 H 1\")" but got "path(\"M 0 0 H 1\") auto 0deg" +FAIL e.style['offset'] = "path(\"M 0 0 H 1\") auto 0rad" should set the property value assert_equals: serialization should be canonical expected "path(\"M 0 0 H 1\")" but got "path(\"M 0 0 H 1\") auto 0rad" +PASS e.style['offset'] = "path(\"M 0 0 H 1\") auto 0.5turn" should set the property value +PASS e.style['offset'] = "path('M 0 0 H 1') reverse 30deg 50px" should set the property value +PASS e.style['offset'] = "path(\"M 0 0 H 1\")" should set the property value +FAIL e.style['offset'] = "path('m 20 0 h 100') -7rad 8px / auto" should set the property value assert_equals: serialization should be canonical expected "path(\"m 20 0 h 100\") 8px -7rad" but got "path(\"m 20 0 h 100\") 8px -7rad / auto" +PASS e.style['offset'] = "path('m 0 30 v 100') -7rad 8px / left top" should set the property value +PASS e.style['offset'] = "path('m 0 0 h 100') -7rad 8px" should set the property value +PASS e.style['offset'] = "path(\"M 0 0 H 100\") 100px 0deg" should set the property value +PASS e.style['offset'] = "path( 'm 1 2 v 3.00 z')" should set the property value +PASS e.style['offset'] = "ray(farthest-corner 90deg) 1%" should set the property value +PASS e.style['offset'] = "ray(sides 0deg) 50% 90deg auto" should set the property value +PASS e.style['offset'] = "right bottom / left top" should set the property value +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/css/motion/parsing/offset-parsing-valid.html b/third_party/blink/web_tests/external/wpt/css/motion/parsing/offset-parsing-valid.html index 3fe8a5b..7f8a0fd 100644 --- a/third_party/blink/web_tests/external/wpt/css/motion/parsing/offset-parsing-valid.html +++ b/third_party/blink/web_tests/external/wpt/css/motion/parsing/offset-parsing-valid.html
@@ -22,15 +22,18 @@ test_valid_value("offset", "left top"); test_valid_value("offset", "none 30deg reverse", "none reverse 30deg"); test_valid_value("offset", "none 50px reverse 30deg"); -test_valid_value("offset", "none calc(10px + 20%) auto"); +test_valid_value("offset", "none calc(10px + 20%) auto", "none calc(20% + 10px)"); test_valid_value("offset", "none reverse"); -test_valid_value("offset", "path(\"M 0 0 H 1\") -200% auto"); +test_valid_value("offset", "path(\"M 0 0 H 1\") -200% auto", "path(\"M 0 0 H 1\") -200%"); test_valid_value("offset", "path(\"M 0 0 H 1\") -200%"); test_valid_value("offset", "path('M 0 0 H 1') 50px", "path(\"M 0 0 H 1\") 50px"); -test_valid_value("offset", "path(\"M 0 0 H 1\") auto"); +test_valid_value("offset", "path(\"M 0 0 H 1\") auto", "path(\"M 0 0 H 1\")"); +test_valid_value("offset", "path(\"M 0 0 H 1\") auto 0deg", "path(\"M 0 0 H 1\")"); +test_valid_value("offset", "path(\"M 0 0 H 1\") auto 0rad", "path(\"M 0 0 H 1\")"); +test_valid_value("offset", "path(\"M 0 0 H 1\") auto 0.5turn", "path(\"M 0 0 H 1\") auto 0.5turn"); test_valid_value("offset", "path('M 0 0 H 1') reverse 30deg 50px", "path(\"M 0 0 H 1\") 50px reverse 30deg"); test_valid_value("offset", "path(\"M 0 0 H 1\")"); -test_valid_value("offset", "path('m 20 0 h 100') -7rad 8px / auto", "path(\"m 20 0 h 100\") 8px -7rad / auto"); +test_valid_value("offset", "path('m 20 0 h 100') -7rad 8px / auto", "path(\"m 20 0 h 100\") 8px -7rad"); test_valid_value("offset", "path('m 0 30 v 100') -7rad 8px / left top", "path(\"m 0 30 v 100\") 8px -7rad / left top"); test_valid_value("offset", "path('m 0 0 h 100') -7rad 8px", "path(\"m 0 0 h 100\") 8px -7rad"); test_valid_value("offset", "path(\"M 0 0 H 100\") 100px 0deg");
diff --git a/third_party/blink/web_tests/external/wpt/css/support/interpolation-testcommon.js b/third_party/blink/web_tests/external/wpt/css/support/interpolation-testcommon.js index e7ee011..24c47e1 100644 --- a/third_party/blink/web_tests/external/wpt/css/support/interpolation-testcommon.js +++ b/third_party/blink/web_tests/external/wpt/css/support/interpolation-testcommon.js
@@ -11,11 +11,10 @@ return keyframe === neutralKeyframe; } - // For the CSS interpolation methods, we set the animation duration long - // enough that any advancement in time during the test is irrelevant in terms - // of the progress. We then set the delay to be negative half the duration, so - // we are immediately at the halfway point of the animation. Finally, we use - // an easing function that maps halfway to whatever progress we actually want. + // For the CSS interpolation methods set the delay to be negative half the + // duration, so we are immediately at the halfway point of the animation. + // We then use an easing function that maps halfway to whatever progress + // we actually want. var cssAnimationsInterpolation = { name: 'CSS Animations', @@ -36,8 +35,8 @@ (isNeutralKeyframe(to) ? '' : `to {${property}:${to};}`) + '}'; target.style.animationName = 'animation' + id; - target.style.animationDuration = '2e9s'; - target.style.animationDelay = '-1e9s'; + target.style.animationDuration = '100s'; + target.style.animationDelay = '-50s'; target.style.animationTimingFunction = createEasing(at); }, }; @@ -54,9 +53,9 @@ }, interpolate: function(property, from, to, at, target) { // Force a style recalc on target to set the 'from' value. - getComputedStyle(target).left; - target.style.transitionDuration = '2e9s'; - target.style.transitionDelay = '-1e9s'; + getComputedStyle(target).getPropertyValue(property); + target.style.transitionDuration = '100s'; + target.style.transitionDelay = '-50s'; target.style.transitionTimingFunction = createEasing(at); target.style.transitionProperty = property; target.style.setProperty(property, isNeutralKeyframe(to) ? '' : to); @@ -76,9 +75,9 @@ }, interpolate: function(property, from, to, at, target) { // Force a style recalc on target to set the 'from' value. - getComputedStyle(target).left; - target.style.transitionDuration = '2e9s'; - target.style.transitionDelay = '-1e9s'; + getComputedStyle(target).getPropertyValue(property); + target.style.transitionDuration = '100s'; + target.style.transitionDelay = '-50s'; target.style.transitionTimingFunction = createEasing(at); target.style.transitionProperty = 'all'; target.style.setProperty(property, isNeutralKeyframe(to) ? '' : to); @@ -104,8 +103,11 @@ property = property.substring(0, i) + property[i + 1].toUpperCase() + property.substring(i + 2); } } - if (property === 'offset') + if (property === 'offset') { property = 'cssOffset'; + } else if (property === 'float') { + property = 'cssFloat'; + } } var keyframes = []; if (!isNeutralKeyframe(from)) { @@ -124,11 +126,11 @@ } var animation = target.animate(keyframes, { fill: 'forwards', - duration: 1, + duration: 100 * 1000, easing: createEasing(at), }); animation.pause(); - animation.currentTime = 0.5; + animation.currentTime = 50 * 1000; }, }; @@ -150,7 +152,7 @@ return 'steps(1, start)'; } if (y == 0.5) { - return 'steps(2, end)'; + return 'linear'; } // Approximate using a bezier. var b = (8 * y - 1) / 6;
diff --git a/third_party/blink/web_tests/external/wpt/css/support/shorthand-testcommon.js b/third_party/blink/web_tests/external/wpt/css/support/shorthand-testcommon.js index 1fd603c..3298113 100644 --- a/third_party/blink/web_tests/external/wpt/css/support/shorthand-testcommon.js +++ b/third_party/blink/web_tests/external/wpt/css/support/shorthand-testcommon.js
@@ -3,18 +3,37 @@ function test_shorthand_value(property, value, longhands) { const stringifiedValue = JSON.stringify(value); + for (let longhand of Object.keys(longhands).sort()) { + test(function(){ + var div = document.getElementById('target') || document.createElement('div'); + div.style[property] = ""; + try { + div.style[property] = value; + + const readValue = div.style[longhand]; + assert_equals(readValue, longhands[longhand], longhand + " should be canonical"); + + div.style[longhand] = ""; + div.style[longhand] = readValue; + assert_equals(div.style[longhand], readValue, "serialization should round-trip"); + } finally { + div.style[property] = ""; + } + }, "e.style['" + property + "'] = " + stringifiedValue + " should set " + longhand); + } + test(function(){ var div = document.getElementById('target') || document.createElement('div'); div.style[property] = ""; - div.style[property] = value; - - for (let longhand of Object.keys(longhands).sort()) { - const readValue = div.style[longhand]; - assert_equals(readValue, longhands[longhand], longhand + " should be canonical"); - - div.style[longhand] = ""; - div.style[longhand] = readValue; - assert_equals(div.style[longhand], readValue, "serialization should round-trip"); + try { + const expectedLength = div.style.length; + div.style[property] = value; + for (let longhand of Object.keys(longhands).sort()) { + div.style[longhand] = ""; + } + assert_equals(div.style.length, expectedLength); + } finally { + div.style[property] = ""; } - }, "e.style['" + property + "'] = " + stringifiedValue + " should set the longhand values"); + }, "e.style['" + property + "'] = " + stringifiedValue + " should not set unrelated longhands"); }
diff --git a/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/shape-outside-margin-box-border-radius-008-ref.html b/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/shape-outside-margin-box-border-radius-008-ref.html index f5edbed..7cf8faf 100644 --- a/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/shape-outside-margin-box-border-radius-008-ref.html +++ b/third_party/blink/web_tests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/shapes1/shape-outside-margin-box-border-radius-008-ref.html
@@ -40,7 +40,7 @@ } </style> - <body class="bfc"> + <main class="bfc"> <span class="container"> <div class="shape"></div> </span> @@ -50,5 +50,5 @@ <div class="box" style="height: 36px; top: 60px; right: 120px;"></div> <div class="box" style="height: 12px; top: 96px; right: 120px;"></div> <!-- Box at corner --> <div class="box" style="height: 12px; top: 108px; right: 120px;"></div> <!-- Box at corner --> - </body> + </main> </html>
diff --git a/third_party/blink/web_tests/external/wpt/dom/nodes/MutationObserver-sanity.html b/third_party/blink/web_tests/external/wpt/dom/nodes/MutationObserver-sanity.html new file mode 100644 index 0000000..a4f6382b --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/dom/nodes/MutationObserver-sanity.html
@@ -0,0 +1,95 @@ +<!doctype html> +<meta charset=utf-8> +<title></title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script> + test(() => { + var m = new MutationObserver(() => {}); + assert_throws_js(TypeError, () => { + m.observe(document, {}); + }); + }, "Should throw if none of childList, attributes, characterData are true"); + + test(() => { + var m = new MutationObserver(() => {}); + m.observe(document, { childList: true }); + m.disconnect(); + }, "Should not throw if childList is true"); + + test(() => { + var m = new MutationObserver(() => {}); + m.observe(document, { attributes: true }); + m.disconnect(); + }, "Should not throw if attributes is true"); + + test(() => { + var m = new MutationObserver(() => {}); + m.observe(document, { characterData: true }); + m.disconnect(); + }, "Should not throw if characterData is true"); + + test(() => { + var m = new MutationObserver(() => {}); + m.observe(document, { attributeOldValue: true }); + m.disconnect(); + }, "Should not throw if attributeOldValue is true and attributes is omitted"); + + test(() => { + var m = new MutationObserver(() => {}); + m.observe(document, { characterDataOldValue: true }); + m.disconnect(); + }, "Should not throw if characterDataOldValue is true and characterData is omitted"); + + test(() => { + var m = new MutationObserver(() => {}); + m.observe(document, { attributes: ["abc"] }); + m.disconnect(); + }, "Should not throw if attributeFilter is present and attributes is omitted"); + + test(() => { + var m = new MutationObserver(() => {}); + assert_throws_js(TypeError, () => { + m.observe(document, { childList: true, attributeOldValue: true, + attributes: false }); + }); + }, "Should throw if attributeOldValue is true and attributes is false"); + + test(() => { + var m = new MutationObserver(() => {}); + m.observe(document, { childList: true, attributeOldValue: true, + attributes: true }); + m.disconnect(); + }, "Should not throw if attributeOldValue and attributes are both true"); + + test(() => { + var m = new MutationObserver(() => {}); + assert_throws_js(TypeError, () => { + m.observe(document, { childList: true, attributeFilter: ["abc"], + attributes: false }); + }); + }, "Should throw if attributeFilter is present and attributes is false"); + + test(() => { + var m = new MutationObserver(() => {}); + m.observe(document, { childList: true, attributeFilter: ["abc"], + attributes: true }); + m.disconnect(); + }, "Should not throw if attributeFilter is present and attributes is true"); + + test(() => { + var m = new MutationObserver(() => {}); + assert_throws_js(TypeError, () => { + m.observe(document, { childList: true, characterDataOldValue: true, + characterData: false }); + }); + }, "Should throw if characterDataOldValue is true and characterData is false"); + + test(() => { + var m = new MutationObserver(() => {}); + m.observe(document, { childList: true, characterDataOldValue: true, + characterData: true }); + m.disconnect(); + }, "Should not throw if characterDataOldValue is true and characterData is true"); + +</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window-expected.txt b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window-expected.txt index d86c1db..61e4b6f1 100644 --- a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window-expected.txt +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window-expected.txt
@@ -7,7 +7,7 @@ PASS JS-engine-created TypeError (cross-site iframe) PASS web API-created TypeError (worker) PASS web API-created TypeError (cross-site iframe) -FAIL web API-created DOMException (worker) assert_equals: expected (string) "Error: Failed to execute 'createElement' on 'Document': The tag name provided ('') is not a valid name.\n at http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:33:14\n at Test.<anonymous> (http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:41:19)\n at Test.step (http://web-platform.test:8001/resources/testharness.js:1611:25)\n at async_test (http://web-platform.test:8001/resources/testharness.js:576:22)\n at stackTests (http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:40:3)\n at http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:31:1" but got (undefined) undefined -FAIL web API-created DOMException (cross-site iframe) assert_equals: expected (string) "Error: Failed to execute 'createElement' on 'Document': The tag name provided ('') is not a valid name.\n at http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:33:14\n at Test.<anonymous> (http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:60:19)\n at Test.step (http://web-platform.test:8001/resources/testharness.js:1611:25)\n at async_test (http://web-platform.test:8001/resources/testharness.js:576:22)\n at stackTests (http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:57:3)\n at http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:31:1" but got (undefined) undefined +FAIL web API-created DOMException (worker) assert_equals: expected (string) "Error: Failed to execute 'createElement' on 'Document': The tag name provided ('') is not a valid name.\n at http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:33:14\n at Test.<anonymous> (http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:41:19)\n at Test.step (http://web-platform.test:8001/resources/testharness.js:1905:25)\n at async_test (http://web-platform.test:8001/resources/testharness.js:576:22)\n at stackTests (http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:40:3)\n at http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:31:1" but got (undefined) undefined +FAIL web API-created DOMException (cross-site iframe) assert_equals: expected (string) "Error: Failed to execute 'createElement' on 'Document': The tag name provided ('') is not a valid name.\n at http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:33:14\n at Test.<anonymous> (http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:60:19)\n at Test.step (http://web-platform.test:8001/resources/testharness.js:1905:25)\n at async_test (http://web-platform.test:8001/resources/testharness.js:576:22)\n at stackTests (http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:57:3)\n at http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:31:1" but got (undefined) undefined Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/tables/table-column-width-ref.html b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/tables/table-column-width-ref.html new file mode 100644 index 0000000..1eb7c00 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/tables/table-column-width-ref.html
@@ -0,0 +1,2 @@ +<!doctype html> +<div style="border: 1px solid green; width: 0">Text</div>
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/tables/table-column-width.html b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/tables/table-column-width.html new file mode 100644 index 0000000..6358e14 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/tables/table-column-width.html
@@ -0,0 +1,10 @@ +<!doctype html> +<link rel="match" href="table-column-width-ref.html"> +<table style="display: block"> + <colgroup style="display: block"> + <col style="border: 1px solid green; display: block" width="0"></col> + </colgroup> +</table> +<script> + document.querySelector("col").append("Text"); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-remove-from-document-different-load.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-remove-from-document-different-load.html new file mode 100644 index 0000000..4802665c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-remove-from-document-different-load.html
@@ -0,0 +1,44 @@ +<!doctype html> +<title>paused state when removing from a document</title> +<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1583052"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/media.js"></script> +<div id="log"></div> +<div> + <video hidden></video> +</div> +<script> +function afterStableState(func) { + var a = new Audio(); + a.volume = 0; + a.addEventListener('volumechange', func); +} + +async_test(function(t) { + var v = document.querySelector('video'); + + // Much like pause-remove-from-document.html, modulo this call. + document.body.appendChild(v); + + v.src = getVideoURI('/media/movie_300'); + v.play(); + v.onplaying = t.step_func(function() { + assert_false(v.paused, 'paused after playing'); + v.parentNode.removeChild(v); + assert_false(v.paused, 'paused after removing'); + afterStableState(t.step_func(function() { + assert_true(v.paused, 'paused after stable state'); + v.onpause = t.step_func(function() { + assert_true(v.paused, 'paused in pause event'); + // re-insert and verify that it stays paused + document.body.appendChild(v); + t.step_timeout(function() { + assert_true(v.paused, 'paused after re-inserting'); + t.done(); + }, 0); + }); + })); + }); +}); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/expected-fail/unhandled-rejection-expected.txt b/third_party/blink/web_tests/external/wpt/infrastructure/expected-fail/unhandled-rejection-expected.txt new file mode 100644 index 0000000..3a828c8 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/infrastructure/expected-fail/unhandled-rejection-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Unhandled rejection Unhandled rejection: error outside any setup or test +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/expected-fail/unhandled-rejection.html b/third_party/blink/web_tests/external/wpt/infrastructure/expected-fail/unhandled-rejection.html new file mode 100644 index 0000000..f25f6e0 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/infrastructure/expected-fail/unhandled-rejection.html
@@ -0,0 +1,8 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Unhandled rejection</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +Promise.reject(new Error("error outside any setup or test")); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/expected-fail/unhandled-rejection.html.ini b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/expected-fail/unhandled-rejection.html.ini new file mode 100644 index 0000000..39773df --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/expected-fail/unhandled-rejection.html.ini
@@ -0,0 +1,4 @@ +[unhandled-rejection.html] + [Unhandled rejection] + expected: FAIL +
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/gamepad.idl b/third_party/blink/web_tests/external/wpt/interfaces/gamepad.idl index b7497c2..27541bf2 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/gamepad.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/gamepad.idl
@@ -38,6 +38,6 @@ [SameObject] readonly attribute Gamepad gamepad; }; -dictionary GamepadEventInit: EventInit { +dictionary GamepadEventInit : EventInit { required Gamepad gamepad; };
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/payment-handler.idl b/third_party/blink/web_tests/external/wpt/interfaces/payment-handler.idl index b5d79de..c87c855 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/payment-handler.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/payment-handler.idl
@@ -40,8 +40,9 @@ attribute EventHandler oncanmakepayment; }; -[Constructor(DOMString type, CanMakePaymentEventInit eventInitDict), Exposed=ServiceWorker] +[Exposed=ServiceWorker] interface CanMakePaymentEvent : ExtendableEvent { + constructor(DOMString type, CanMakePaymentEventInit eventInitDict); readonly attribute USVString topOrigin; readonly attribute USVString paymentRequestOrigin; readonly attribute FrozenArray<PaymentMethodData> methodData; @@ -65,8 +66,9 @@ object paymentMethodErrors; }; -[Constructor(DOMString type, PaymentRequestEventInit eventInitDict), Exposed=ServiceWorker] +[Exposed=ServiceWorker] interface PaymentRequestEvent : ExtendableEvent { + constructor(DOMString type, PaymentRequestEventInit eventInitDict); readonly attribute USVString topOrigin; readonly attribute USVString paymentRequestOrigin; readonly attribute DOMString paymentRequestId;
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/webxr-ar-module.idl b/third_party/blink/web_tests/external/wpt/interfaces/webxr-ar-module.idl new file mode 100644 index 0000000..61fcd6a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/interfaces/webxr-ar-module.idl
@@ -0,0 +1,21 @@ +// GENERATED CONTENT - DO NOT EDIT +// Content was automatically extracted by Reffy into reffy-reports +// (https://github.com/tidoust/reffy-reports) +// Source: WebXR Augmented Reality Module - Level 1 (https://immersive-web.github.io/webxr-ar-module/) + +enum XRSessionMode { + "inline", + "immersive-vr", + "immersive-ar" +}; + +enum XREnvironmentBlendMode { + "opaque", + "alpha-blend", + "additive" +}; + +partial interface XRSession { + // Attributes + readonly attribute XREnvironmentBlendMode environmentBlendMode; +};
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/webxr-gamepads-module.idl b/third_party/blink/web_tests/external/wpt/interfaces/webxr-gamepads-module.idl new file mode 100644 index 0000000..3aa17a7f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/interfaces/webxr-gamepads-module.idl
@@ -0,0 +1,14 @@ +// GENERATED CONTENT - DO NOT EDIT +// Content was automatically extracted by Reffy into reffy-reports +// (https://github.com/tidoust/reffy-reports) +// Source: WebXR Gamepads Module - Level 1 (https://immersive-web.github.io/webxr-gamepads-module/) + +partial interface XRInputSource { + [SameObject] readonly attribute Gamepad? gamepad; +}; + +enum GamepadMappingType { + "", // Defined in the Gamepad API + "standard", // Defined in the Gamepad API + "xr-standard", +};
diff --git a/third_party/blink/web_tests/external/wpt/intersection-observer/resources/cross-origin-child-iframe.sub.html b/third_party/blink/web_tests/external/wpt/intersection-observer/resources/cross-origin-child-iframe.sub.html new file mode 100644 index 0000000..8e2c36ed --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/intersection-observer/resources/cross-origin-child-iframe.sub.html
@@ -0,0 +1,7 @@ +<!DOCTYPE html> +<script src="/common/get-host-info.sub.js"></script> +<iframe id="iframe"></iframe> +<script> +iframe.src = + get_host_info().ORIGIN + "/intersection-observer/resources/same-origin-grand-child-iframe.html"; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/intersection-observer/resources/same-origin-grand-child-iframe.html b/third_party/blink/web_tests/external/wpt/intersection-observer/resources/same-origin-grand-child-iframe.html new file mode 100644 index 0000000..25db5a2 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/intersection-observer/resources/same-origin-grand-child-iframe.html
@@ -0,0 +1,8 @@ +<!DOCTYPE html> +<div id="target"></div> +<script> +const observer = new IntersectionObserver(records => { + window.top.postMessage(records[0].rootBounds, "*"); +}, {}); +observer.observe(target); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/intersection-observer/same-origin-grand-child-iframe.sub.html b/third_party/blink/web_tests/external/wpt/intersection-observer/same-origin-grand-child-iframe.sub.html new file mode 100644 index 0000000..57c0347 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/intersection-observer/same-origin-grand-child-iframe.sub.html
@@ -0,0 +1,24 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<meta name="viewport" content="width=device-width,initial-scale=1"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/get-host-info.sub.js"></script> +<script src="./resources/intersection-observer-test-utils.js"></script> +<iframe id="iframe"></iframe> +<script> +promise_test(async t => { + iframe.src = + get_host_info().HTTP_NOTSAMESITE_ORIGIN + "/intersection-observer/resources/cross-origin-child-iframe.sub.html"; + + const rootBounds = await new Promise(resolve => { + window.addEventListener("message", event => resolve(event.data)); + }, { once: true } ); + + assert_equals(rootBounds.left, 0); + assert_equals(rootBounds.top, 0); + assert_equals(rootBounds.right, document.documentElement.clientWidth); + assert_equals(rootBounds.bottom, document.documentElement.clientHeight); +}, "rootBounds in a same-origin iframe in the case where there is a cross-origin " ++ "iframe in between the top document and the same origin iframe"); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/lint.whitelist b/third_party/blink/web_tests/external/wpt/lint.whitelist index be87d27..d9ea5c1 100644 --- a/third_party/blink/web_tests/external/wpt/lint.whitelist +++ b/third_party/blink/web_tests/external/wpt/lint.whitelist
@@ -836,11 +836,6 @@ AHEM SYSTEM FONT: resource-timing/resources/all_resource_types.htm AHEM SYSTEM FONT: resource-timing/resources/iframe-reload-TAO.sub.html -# These tests are imported from mozilla-central and can't be modified in WPT. -# They do load Ahem as a web font, but they use their own copy which trips the -# lint rule. Basically false positives. -AHEM SYSTEM FONT: css/vendor-imports/mozilla/mozilla-central-reftests/* - # TODO: The following should be deleted along with the Ahem web font cleanup # PR (https://github.com/web-platform-tests/wpt/pull/18702) AHEM SYSTEM FONT: infrastructure/assumptions/ahem-ref.html
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/clipboard-event-handlers.tentative.html b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/clipboard-event-handlers.tentative.html index 82fda88..9816f51 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/clipboard-event-handlers.tentative.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/clipboard-event-handlers.tentative.html
@@ -30,6 +30,9 @@ "math" ); async_test(test => { + test.step(function() { + assert_true(MathMLElement.prototype.hasOwnProperty(`on${name}`)); + }); mathEl[`on${name}`] = test.step_func_done(e => { assert_equals(e.currentTarget, mathEl, "The event must be fired at the <math> element");
diff --git a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/math-global-event-handlers.tentative.html b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/math-global-event-handlers.tentative.html index e96feea..be9bee9c6 100644 --- a/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/math-global-event-handlers.tentative.html +++ b/third_party/blink/web_tests/external/wpt/mathml/relations/html5-tree/math-global-event-handlers.tentative.html
@@ -125,6 +125,9 @@ }, `${name}: dynamic changes on the attribute`); async_test(t => { + t.step(function() { + assert_true(MathMLElement.prototype.hasOwnProperty(name)); + }); const element = document.createElementNS( "http://www.w3.org/1998/Math/MathML", "math"
diff --git a/third_party/blink/web_tests/external/wpt/payment-handler/change-payment-method-manual.https-expected.txt b/third_party/blink/web_tests/external/wpt/payment-handler/change-payment-method-manual.https-expected.txt new file mode 100644 index 0000000..f30628b --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/payment-handler/change-payment-method-manual.https-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Tests for PaymentRequestEvent.changePaymentMethod() Unhandled rejection: Not allowed to install this payment handler +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/payment-handler/payment-request-event-manual.https-expected.txt b/third_party/blink/web_tests/external/wpt/payment-handler/payment-request-event-manual.https-expected.txt index b76179f..a00a329 100644 --- a/third_party/blink/web_tests/external/wpt/payment-handler/payment-request-event-manual.https-expected.txt +++ b/third_party/blink/web_tests/external/wpt/payment-handler/payment-request-event-manual.https-expected.txt
@@ -1,4 +1,4 @@ This is a testharness.js-based test. -FAIL Tests for PaymentRequestEvent Not allowed to install this payment handler +FAIL Tests for PaymentRequestEvent Unhandled rejection: Not allowed to install this payment handler Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/payment-handler/supports-shipping-contact-delegation-manual.https-expected.txt b/third_party/blink/web_tests/external/wpt/payment-handler/supports-shipping-contact-delegation-manual.https-expected.txt index 3a76dbf..149709f31 100644 --- a/third_party/blink/web_tests/external/wpt/payment-handler/supports-shipping-contact-delegation-manual.https-expected.txt +++ b/third_party/blink/web_tests/external/wpt/payment-handler/supports-shipping-contact-delegation-manual.https-expected.txt
@@ -1,4 +1,4 @@ This is a testharness.js-based test. -FAIL Tests for Delegation of shipping and contact collection to PH Not allowed to install this payment handler +FAIL Tests for Delegation of shipping and contact collection to PH Unhandled rejection: Not allowed to install this payment handler Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-canmakepayment-method.https-expected.txt b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-canmakepayment-method.https-expected.txt index 5b7ee0ea..f12b171 100644 --- a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-canmakepayment-method.https-expected.txt +++ b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-canmakepayment-method.https-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Harness Error. harness_status.status = 1 , harness_status.message = No show() or retry() in progress, so nothing to abort +Harness Error. harness_status.status = 1 , harness_status.message = Unhandled rejection: No show() or retry() in progress, so nothing to abort FAIL If payment method identifier are supported, resolve promise with true. promise_test: Unhandled rejection with value: object "UnknownError: Renderer process could not establish or lost IPC connection to the PaymentRequest service in the browser process." FAIL If request.[[state]] is "created", then return a promise that resolves to true for known method. assert_equals: if it throws, then it must be a NotAllowedError. expected "NotAllowedError" but got "UnknownError" FAIL All methods are unsupported promise_test: Unhandled rejection with value: object "UnknownError: Renderer process could not establish or lost IPC connection to the PaymentRequest service in the browser process."
diff --git a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-show-method.https-expected.txt b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-show-method.https-expected.txt index b9ec0ae..694a3c86 100644 --- a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-show-method.https-expected.txt +++ b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-show-method.https-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Harness Error. harness_status.status = 1 , harness_status.message = Already called show() once +Harness Error. harness_status.status = 1 , harness_status.message = Unhandled rejection: Already called show() once FAIL Calling show() without being triggered by user interaction throws assert_throws: function "function() { throw e }" threw object "UnknownError: Renderer process could not establish or lost IPC connection to the PaymentRequest service in the browser process." that is not a DOMException SecurityError: property "code" is equal to 0, expected 18 FAIL Throws if the promise [[state]] is not 'created'. promise_test: Unhandled rejection with value: object "InvalidStateError: No show() or retry() in progress, so nothing to abort" FAIL If the user agent's "payment request is showing" boolean is true, then return a promise rejected with an "AbortError" DOMException. assert_throws: function "function() { throw e }" threw object "InvalidStateError: Already called show() once" that is not a DOMException AbortError: property "code" is equal to 11, expected 20
diff --git a/third_party/blink/web_tests/external/wpt/permissions/feature-policy-permissions-query.html b/third_party/blink/web_tests/external/wpt/permissions/feature-policy-permissions-query.html new file mode 100644 index 0000000..bd152e9 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/permissions/feature-policy-permissions-query.html
@@ -0,0 +1,11 @@ +<script> +'use strict'; + +Promise.resolve().then(() => navigator.permissions.query({name:'geolocation'})) + .then(permissionStatus => { + window.parent.postMessage({ state: permissionStatus.state }, '*'); +}, error => { + window.parent.postMessage({ state: null }, '*'); +}); +</script> +
diff --git a/third_party/blink/web_tests/external/wpt/permissions/permissions-query-feature-policy-attribute.https.sub-expected.txt b/third_party/blink/web_tests/external/wpt/permissions/permissions-query-feature-policy-attribute.https.sub-expected.txt new file mode 100644 index 0000000..b3a5213 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/permissions/permissions-query-feature-policy-attribute.https.sub-expected.txt
@@ -0,0 +1,7 @@ +This is a testharness.js-based test. +FAIL Permissions.state is "prompt" with allow="geolocation" in same-origin iframes. assert_equals: navigator.permissions.query("geolocation") expected "prompt" but got "denied" +FAIL Permissions.state is "prompt" with allow="geolocation" in cross-origin iframes. assert_equals: navigator.permissions.query("geolocation") expected "prompt" but got "denied" +FAIL Permission.state is "prompt" in same-origin iframes. assert_equals: navigator.permissions.query("geolocation") expected "prompt" but got "denied" +PASS Permission.state is "denied" in cross-origin iframes. +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/permissions/permissions-query-feature-policy-attribute.https.sub.html b/third_party/blink/web_tests/external/wpt/permissions/permissions-query-feature-policy-attribute.https.sub.html new file mode 100644 index 0000000..1d7333d9 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/permissions/permissions-query-feature-policy-attribute.https.sub.html
@@ -0,0 +1,75 @@ +<!doctype html> +<meta charset=utf-8> +<title>Test permissions query againts feature policy allow attribute</title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<div id="log"></div> + +<script> + "use strict"; + + function test_permissions_query( + feature_description, test, src, expect_state, allow_attribute) { + let frame = document.createElement('iframe'); + frame.src = src; + + if (typeof allow_attribute !== 'undefined') { + frame.allow = allow_attribute; + } + + window.addEventListener('message', test.step_func(function handler(evt) { + if (evt.source === frame.contentWindow) { + assert_equals(evt.data.state, expect_state, feature_description); + document.body.removeChild(frame); + window.removeEventListener('message', handler); + test.done(); + } + })); + + document.body.appendChild(frame); + } + + const same_origin_src = + "/permissions/feature-policy-permissions-query.html"; + const cross_origin_src = + "https://{{domains[www]}}:{{ports[https][0]}}" + same_origin_src; + + async_test(t => { + test_permissions_query( + 'navigator.permissions.query("geolocation")', + t, + same_origin_src, + "prompt", + "geolocation" + ); + }, 'Permissions.state is "prompt" with allow="geolocation" in same-origin iframes.'); + + async_test(t => { + test_permissions_query( + 'navigator.permissions.query("geolocation")', + t, + cross_origin_src, + "prompt", + "geolocation" + ); + }, 'Permissions.state is "prompt" with allow="geolocation" in cross-origin iframes.'); + + async_test(t => { + test_permissions_query( + 'navigator.permissions.query("geolocation")', + t, + same_origin_src, + "prompt" + ); + }, 'Permission.state is "prompt" in same-origin iframes.'); + + async_test(t => { + test_permissions_query( + 'navigator.permissions.query("geolocation")', + t, + cross_origin_src, + "denied" + ); + }, 'Permission.state is "denied" in cross-origin iframes.'); + +</script>
diff --git a/third_party/blink/web_tests/external/wpt/resources/chromium/contacts_manager_mock.js b/third_party/blink/web_tests/external/wpt/resources/chromium/contacts_manager_mock.js index 618968ec..ae4c33b 100644 --- a/third_party/blink/web_tests/external/wpt/resources/chromium/contacts_manager_mock.js +++ b/third_party/blink/web_tests/external/wpt/resources/chromium/contacts_manager_mock.js
@@ -10,7 +10,7 @@ this.bindingSet_ = new mojo.BindingSet(blink.mojom.ContactsManager); this.interceptor_ = new MojoInterfaceInterceptor( - blink.mojom.ContactsManager.name); + blink.mojom.ContactsManager.name, "context", true); this.interceptor_.oninterfacerequest = e => this.bindingSet_.addBinding(this, e.handle); this.interceptor_.start();
diff --git a/third_party/blink/web_tests/external/wpt/resources/testharness.js b/third_party/blink/web_tests/external/wpt/resources/testharness.js index 1559104..9ef46ca 100644 --- a/third_party/blink/web_tests/external/wpt/resources/testharness.js +++ b/third_party/blink/web_tests/external/wpt/resources/testharness.js
@@ -630,6 +630,27 @@ }); } + function promise_rejects_js(test, expected, promise, description) { + return promise.then(test.unreached_func("Should have rejected: " + description)).catch(function(e) { + assert_throws_js_impl(expected, function() { throw e }, + description, "promise_reject_js"); + }); + } + + function promise_rejects_dom(test, expected, promise, description) { + return promise.then(test.unreached_func("Should have rejected: " + description)).catch(function(e) { + assert_throws_dom_impl(expected, function() { throw e }, + description, "promise_rejects_dom"); + }); + } + + function promise_rejects_exactly(test, expected, promise, description) { + return promise.then(test.unreached_func("Should have rejected: " + description)).catch(function(e) { + assert_throws_exactly_impl(expected, function() { throw e }, + description, "promise_rejects_exactly"); + }); + } + /** * This constructor helper allows DOM events to be handled using Promises, * which can make it a lot easier to test a very specific series of events, @@ -811,6 +832,9 @@ expose(async_test, 'async_test'); expose(promise_test, 'promise_test'); expose(promise_rejects, 'promise_rejects'); + expose(promise_rejects_js, 'promise_rejects_js'); + expose(promise_rejects_dom, 'promise_rejects_dom'); + expose(promise_rejects_exactly, 'promise_rejects_exactly'); expose(generate_tests, 'generate_tests'); expose(setup, 'setup'); expose(done, 'done'); @@ -1482,6 +1506,276 @@ } expose(assert_throws, "assert_throws"); + /** + * Assert a JS Error with the expected constructor is thrown. + * + * @param {object} constructor The expected exception constructor. + * @param {Function} func Function which should throw. + * @param {string} description Error description for the case that the error is not thrown. + */ + function assert_throws_js(constructor, func, description) + { + assert_throws_js_impl(constructor, func, description, + "assert_throws_js"); + } + expose(assert_throws_js, "assert_throws_js"); + + /** + * Like assert_throws_js but allows specifying the assertion type + * (assert_throws_js or promise_rejects_js, in practice). + */ + function assert_throws_js_impl(constructor, func, description, + assertion_type) + { + try { + func.call(this); + assert(false, assertion_type, description, + "${func} did not throw", {func:func}); + } catch (e) { + if (e instanceof AssertionError) { + throw e; + } + + // Basic sanity-checks on the thrown exception. + assert(typeof e === "object", + assertion_type, description, + "${func} threw ${e} with type ${type}, not an object", + {func:func, e:e, type:typeof e}); + + assert(e !== null, + assertion_type, description, + "${func} threw null, not an object", + {func:func}); + + // Basic sanity-check on the passed-in constructor + assert(typeof constructor == "function", + assertion_type, description, + "${constructor} is not a constructor", + {constructor:constructor}); + var obj = constructor; + while (obj) { + if (typeof obj === "function" && + obj.name === "Error") { + break; + } + obj = Object.getPrototypeOf(obj); + } + assert(obj != null, + assertion_type, description, + "${constructor} is not an Error subtype", + {constructor:constructor}); + + // And checking that our exception is reasonable + assert(e.constructor === constructor && + e.name === constructor.name, + assertion_type, description, + "${func} threw ${actual} (${actual_name}) expected instance of ${expected} (${expected_name})", + {func:func, actual:e, actual_name:e.name, + expected:constructor, + expected_name:constructor.name}); + } + } + + /** + * Assert a DOMException with the expected type is thrown. + * + * @param {number|string} type The expected exception name or code. See the + * table of names and codes at + * https://heycam.github.io/webidl/#dfn-error-names-table + * If a number is passed it should be one of the numeric code values + * in that table (e.g. 3, 4, etc). If a string is passed it can + * either be an exception name (e.g. "HierarchyRequestError", + * "WrongDocumentError") or the name of the corresponding error code + * (e.g. "HIERARCHY_REQUEST_ERR", "WRONG_DOCUMENT_ERR"). + * @param {Function} func Function which should throw. + * @param {string} description Error description for the case that the error is not thrown. + */ + function assert_throws_dom(type, func, description) + { + assert_throws_dom_impl(type, func, description, "assert_throws_dom") + } + expose(assert_throws_dom, "assert_throws_dom"); + + /** + * Like assert_throws_dom but allows specifying the assertion type + * (assert_throws_dom or promise_rejects_dom, in practice). + */ + function assert_throws_dom_impl(type, func, description, assertion_type) + { + try { + func.call(this); + assert(false, assertion_type, description, + "${func} did not throw", {func:func}); + } catch (e) { + if (e instanceof AssertionError) { + throw e; + } + + assert(typeof e === "object", + assertion_type, description, + "${func} threw ${e} with type ${type}, not an object", + {func:func, e:e, type:typeof e}); + + assert(e !== null, + assertion_type, description, + "${func} threw null, not an object", + {func:func}); + + // Sanity-check our type + assert(typeof type == "number" || + typeof type == "string", + assertion_type, description, + "${type} is not a number or string", + {type:type}); + + var codename_name_map = { + INDEX_SIZE_ERR: 'IndexSizeError', + HIERARCHY_REQUEST_ERR: 'HierarchyRequestError', + WRONG_DOCUMENT_ERR: 'WrongDocumentError', + INVALID_CHARACTER_ERR: 'InvalidCharacterError', + NO_MODIFICATION_ALLOWED_ERR: 'NoModificationAllowedError', + NOT_FOUND_ERR: 'NotFoundError', + NOT_SUPPORTED_ERR: 'NotSupportedError', + INUSE_ATTRIBUTE_ERR: 'InUseAttributeError', + INVALID_STATE_ERR: 'InvalidStateError', + SYNTAX_ERR: 'SyntaxError', + INVALID_MODIFICATION_ERR: 'InvalidModificationError', + NAMESPACE_ERR: 'NamespaceError', + INVALID_ACCESS_ERR: 'InvalidAccessError', + TYPE_MISMATCH_ERR: 'TypeMismatchError', + SECURITY_ERR: 'SecurityError', + NETWORK_ERR: 'NetworkError', + ABORT_ERR: 'AbortError', + URL_MISMATCH_ERR: 'URLMismatchError', + QUOTA_EXCEEDED_ERR: 'QuotaExceededError', + TIMEOUT_ERR: 'TimeoutError', + INVALID_NODE_TYPE_ERR: 'InvalidNodeTypeError', + DATA_CLONE_ERR: 'DataCloneError' + }; + + var name_code_map = { + IndexSizeError: 1, + HierarchyRequestError: 3, + WrongDocumentError: 4, + InvalidCharacterError: 5, + NoModificationAllowedError: 7, + NotFoundError: 8, + NotSupportedError: 9, + InUseAttributeError: 10, + InvalidStateError: 11, + SyntaxError: 12, + InvalidModificationError: 13, + NamespaceError: 14, + InvalidAccessError: 15, + TypeMismatchError: 17, + SecurityError: 18, + NetworkError: 19, + AbortError: 20, + URLMismatchError: 21, + QuotaExceededError: 22, + TimeoutError: 23, + InvalidNodeTypeError: 24, + DataCloneError: 25, + + EncodingError: 0, + NotReadableError: 0, + UnknownError: 0, + ConstraintError: 0, + DataError: 0, + TransactionInactiveError: 0, + ReadOnlyError: 0, + VersionError: 0, + OperationError: 0, + NotAllowedError: 0 + }; + + var code_name_map = {}; + for (var key in name_code_map) { + if (name_code_map[key] > 0) { + code_name_map[name_code_map[key]] = key; + } + } + + var required_props = {}; + var name; + + if (typeof type === "number") { + if (type === 0) { + throw new AssertionError('Test bug: ambiguous DOMException code 0 passed to assert_throws_dom()'); + } else if (!(type in code_name_map)) { + throw new AssertionError('Test bug: unrecognized DOMException code "' + type + '" passed to assert_throws_dom()'); + } + name = code_name_map[type]; + required_props.code = type; + } else if (typeof type === "string") { + name = type in codename_name_map ? codename_name_map[type] : type; + if (!(name in name_code_map)) { + throw new AssertionError('Test bug: unrecognized DOMException code name or name "' + type + '" passed to assert_throws_dom()'); + } + + required_props.code = name_code_map[name]; + } + + if (required_props.code === 0 || + ("name" in e && + e.name !== e.name.toUpperCase() && + e.name !== "DOMException")) { + // New style exception: also test the name property. + required_props.name = name; + } + + //We'd like to test that e instanceof the appropriate interface, + //but we can't, because we don't know what window it was created + //in. It might be an instanceof the appropriate interface on some + //unknown other window. TODO: Work around this somehow? Maybe have + //the first arg just be a DOMException with the right name instead + //of the string-or-code thing we have now? + + for (var prop in required_props) { + assert(prop in e && e[prop] == required_props[prop], + assertion_type, description, + "${func} threw ${e} that is not a DOMException " + type + ": property ${prop} is equal to ${actual}, expected ${expected}", + {func:func, e:e, prop:prop, actual:e[prop], expected:required_props[prop]}); + } + } + } + + /** + * Assert the provided value is thrown. + * + * @param {value} exception The expected exception. + * @param {Function} func Function which should throw. + * @param {string} description Error description for the case that the error is not thrown. + */ + function assert_throws_exactly(exception, func, description) + { + assert_throws_exactly_impl(exception, func, description, + "assert_throws_exactly"); + } + expose(assert_throws_exactly, "assert_throws_exactly"); + + /** + * Like assert_throws_exactly but allows specifying the assertion type + * (assert_throws_exactly or promise_rejects_exactly, in practice). + */ + function assert_throws_exactly_impl(exception, func, description, + assertion_type) + { + try { + func.call(this); + assert(false, assertion_type, description, + "${func} did not throw", {func:func}); + } catch (e) { + if (e instanceof AssertionError) { + throw e; + } + + assert(same_value(e, exception), assertion_type, description, + "${func} threw ${e} but we expected it to throw ${exception}", + {func:func, e:e, exception:exception}); + } + } + function assert_unreached(description) { assert(false, "assert_unreached", description, "Reached unreachable code"); @@ -3365,38 +3659,42 @@ var tests = new Tests(); if (global_scope.addEventListener) { - var error_handler = function(e) { + var error_handler = function(message, stack) { if (tests.tests.length === 0 && !tests.allow_uncaught_exception) { tests.set_file_is_test(); } - var stack; - if (e.error && e.error.stack) { - stack = e.error.stack; - } else { - stack = e.filename + ":" + e.lineno + ":" + e.colno; - } - if (tests.file_is_test) { var test = tests.tests[0]; if (test.phase >= test.phases.HAS_RESULT) { return; } - test.set_status(test.FAIL, e.message, stack); + test.set_status(test.FAIL, message, stack); test.phase = test.phases.HAS_RESULT; - // The following function invocation is superfluous. - // TODO: Remove. - test.done(); } else if (!tests.allow_uncaught_exception) { tests.status.status = tests.status.ERROR; - tests.status.message = e.message; + tests.status.message = message; tests.status.stack = stack; } done(); }; - addEventListener("error", error_handler, false); - addEventListener("unhandledrejection", function(e){ error_handler(e.reason); }, false); + addEventListener("error", function(e) { + var message = e.message; + var stack; + if (e.error && e.error.stack) { + stack = e.error.stack; + } else { + stack = e.filename + ":" + e.lineno + ":" + e.colno; + } + error_handler(message, stack); + }, false); + + addEventListener("unhandledrejection", function(e) { + var message = "Unhandled rejection: " + e.reason.message; + // There's no stack for unhandled rejections. + error_handler(message); + }, false); } test_environment.on_tests_ready();
diff --git a/third_party/blink/web_tests/external/wpt/shadow-dom/focus/focus-selector-delegatesFocus-expected.txt b/third_party/blink/web_tests/external/wpt/shadow-dom/focus/focus-selector-delegatesFocus-expected.txt new file mode 100644 index 0000000..8b0d0bf --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/shadow-dom/focus/focus-selector-delegatesFocus-expected.txt
@@ -0,0 +1,11 @@ +This is a testharness.js-based test. +PASS :focus applies to host with delegatesFocus=true when the shadow root's descendant has focus +FAIL :focus applies to host with delegatesFocus=true when slotted element has focus assert_true: host matches :focus expected true got false +PASS :focus applies to host with delegatesFocus=true when an element in a nested shadow tree with delegatesFocus=true is focused +FAIL :focus applies to host with delegatesFocus=true when an element in a nested shadow tree with delegatesFocus=false is focused assert_true: host of nested shadow tree matches focus expected true got false +FAIL :focus applies to host with delegatesFocus=false when the shadow root's descendant has focus assert_true: host matches :focus expected true got false +FAIL :focus applies to host with delegatesFocus=false when slotted element has focus assert_true: host matches :focus expected true got false +FAIL :focus applies to host with delegatesFocus=false when an element in a nested shadow tree with delegatesFocus=true is focused assert_true: topmost host matches focus expected true got false +FAIL :focus applies to host with delegatesFocus=false when an element in a nested shadow tree with delegatesFocus=false is focused assert_true: host of nested shadow tree matches focus expected true got false +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/shadow-dom/focus/focus-selector-delegatesFocus.html b/third_party/blink/web_tests/external/wpt/shadow-dom/focus/focus-selector-delegatesFocus.html new file mode 100644 index 0000000..38604525 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/shadow-dom/focus/focus-selector-delegatesFocus.html
@@ -0,0 +1,72 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="utf-8" /> + <title>CSS Test (Selectors): :focus behavior with shadow hosts & delegatesFocus </title> + <link rel="author" title="Rakina Zata Amni" href="rakina@chromium.org" /> + <link rel="help" href="https://html.spec.whatwg.org/multipage/semantics-other.html#selector-focus" /> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/resources/testdriver.js"></script> + <script src="/resources/testdriver-vendor.js"></script> + <script src="resources/shadow-utils.js"></script> +</head> + +<body> +<script> +function createFocusableDiv() { + const div = document.createElement("div"); + div.innerText = "foo"; + div.tabIndex = 0; + return div; +} + +function createShadowHost(delegatesFocus, container) { + const host = document.createElement("div"); + host.attachShadow({ mode: "open", delegatesFocus: delegatesFocus }); + container.appendChild(host); + return host; +} + +const delegatesFocusValues = [true, false]; + +for (const delegatesFocus of delegatesFocusValues) { + test(() => { + resetFocus(); + const host = createShadowHost(delegatesFocus, document.body); + const shadowChild = createFocusableDiv(); + host.shadowRoot.appendChild(shadowChild); + + shadowChild.focus(); + assert_true(shadowChild.matches(":focus"), "element in shadow tree matches :focus"); + assert_true(host.matches(":focus"), "host matches :focus"); + }, `:focus applies to host with delegatesFocus=${delegatesFocus} when the shadow root's descendant has focus`); + + test(() => { + resetFocus(); + const host = createShadowHost(delegatesFocus, document.body); + const slotted = createFocusableDiv(); + host.shadowRoot.appendChild(document.createElement("slot")); + host.appendChild(slotted); + + slotted.focus(); + assert_true(slotted.matches(":focus"), "slotted element matches :focus"); + assert_true(host.matches(":focus"), "host matches :focus"); + }, `:focus applies to host with delegatesFocus=${delegatesFocus} when slotted element has focus`); + + for (const nestedDelegatesFocus of delegatesFocusValues) { + test(() => { + resetFocus(); + const host = createShadowHost(delegatesFocus, document.body); + const nestedHost = createShadowHost(nestedDelegatesFocus, host.shadowRoot); + const nestedShadowChild = createFocusableDiv(); + nestedHost.shadowRoot.appendChild(nestedShadowChild); + nestedShadowChild.focus(); + assert_true(nestedShadowChild.matches(":focus"), "element in nested shadow tree matches :focus"); + assert_true(nestedHost.matches(":focus"), "host of nested shadow tree matches focus"); + assert_true(host.matches(":focus"), "topmost host matches focus"); +}, `:focus applies to host with delegatesFocus=${delegatesFocus} when an element in a nested shadow tree with delegatesFocus=${nestedDelegatesFocus} is focused`); + } +} +</script> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/shadow-dom/focus/resources/shadow-utils.js b/third_party/blink/web_tests/external/wpt/shadow-dom/focus/resources/shadow-utils.js index 6ea372a..8033ce0 100644 --- a/third_party/blink/web_tests/external/wpt/shadow-dom/focus/resources/shadow-utils.js +++ b/third_party/blink/web_tests/external/wpt/shadow-dom/focus/resources/shadow-utils.js
@@ -60,8 +60,9 @@ } } -function resetFocus() { - document.body.focus(); +function resetFocus(root = document) { + if (root.activeElement) + root.activeElement.blur(); } function navigateFocusForward() {
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any.serviceworker-expected.txt b/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any.serviceworker-expected.txt index 39cb31b..6e0da30 100644 --- a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any.serviceworker-expected.txt +++ b/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any.serviceworker-expected.txt
@@ -1,4 +1,4 @@ This is a testharness.js-based test. -FAIL construct-byob-request Failed to register a ServiceWorker for scope ('https://web-platform.test:8444/streams/readable-byte-streams/does/not/exist') with script ('https://web-platform.test:8444/streams/readable-byte-streams/construct-byob-request.any.worker.js'): ServiceWorker script evaluation failed +FAIL construct-byob-request Unhandled rejection: Failed to register a ServiceWorker for scope ('https://web-platform.test:8444/streams/readable-byte-streams/does/not/exist') with script ('https://web-platform.test:8444/streams/readable-byte-streams/construct-byob-request.any.worker.js'): ServiceWorker script evaluation failed Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/svg/animations/scripted/onhover-syncbases.html b/third_party/blink/web_tests/external/wpt/svg/animations/scripted/onhover-syncbases.html index 0772601..de757f3 100644 --- a/third_party/blink/web_tests/external/wpt/svg/animations/scripted/onhover-syncbases.html +++ b/third_party/blink/web_tests/external/wpt/svg/animations/scripted/onhover-syncbases.html
@@ -20,7 +20,7 @@ let rounds = 5; // How many times the cursor is moved in and out let circle = document.querySelector("#circle"); let delay = 20; - let f = t.step_func(function() { + function f() { assert_equals(window.getComputedStyle(circle, null).fill, "rgb(255, 0, 0)") if (rounds-- == 0) { @@ -29,14 +29,14 @@ } circle.dispatchEvent(new Event("mouseover")); - step_timeout(t.step_func(function() { + t.step_timeout(function() { assert_equals(window.getComputedStyle(circle, null).fill, "rgb(0, 255, 0)") circle.dispatchEvent(new Event("mouseout")) t.step_timeout(f, delay); - }), delay); - }); - step_timeout(f, 0); + }, delay); + } + t.step_timeout(f, 0); }); </script> </body>
diff --git a/third_party/blink/web_tests/external/wpt/tools/ci/tcdownload.py b/third_party/blink/web_tests/external/wpt/tools/ci/tcdownload.py index 91c763a7..46e9005 100644 --- a/third_party/blink/web_tests/external/wpt/tools/ci/tcdownload.py +++ b/third_party/blink/web_tests/external/wpt/tools/ci/tcdownload.py
@@ -71,7 +71,7 @@ if not taskgroups: logger.error("No complete TaskCluster runs found for ref %s" % kwargs["ref"]) - return + return 1 for taskgroup in taskgroups: taskgroup_url = "https://queue.taskcluster.net/v1/task-group/%s/list"
diff --git a/third_party/blink/web_tests/external/wpt/tools/lint/lint.py b/third_party/blink/web_tests/external/wpt/tools/lint/lint.py index 48a275b..7689c35 100644 --- a/third_party/blink/web_tests/external/wpt/tools/lint/lint.py +++ b/third_party/blink/web_tests/external/wpt/tools/lint/lint.py
@@ -681,7 +681,10 @@ ahem_font_re = re.compile(b"font.*:.*ahem", flags=re.IGNORECASE) -ahem_stylesheet_re = re.compile(b"\/fonts\/ahem\.css", flags=re.IGNORECASE) +# Ahem can appear either in the global location or in the support +# directory for legacy Mozilla imports +ahem_stylesheet_re = re.compile(b"\/fonts\/ahem\.css|support\/ahem.css", + flags=re.IGNORECASE) def check_ahem_system_font(repo_root, path, f):
diff --git a/third_party/blink/web_tests/external/wpt/tools/wptrunner/requirements.txt b/third_party/blink/web_tests/external/wpt/tools/wptrunner/requirements.txt index d6c7a4f..3584c93 100644 --- a/third_party/blink/web_tests/external/wpt/tools/wptrunner/requirements.txt +++ b/third_party/blink/web_tests/external/wpt/tools/wptrunner/requirements.txt
@@ -3,6 +3,6 @@ mozlog==4.2.0 mozdebug==0.1.1 pillow==6.1.0 -urllib3[secure]==1.25.3 +urllib3[secure]==1.25.5 requests==2.22.0 six==1.12.0
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-001-expected.txt b/third_party/blink/web_tests/external/wpt/web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-001-expected.txt new file mode 100644 index 0000000..5b5ccfe7 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-001-expected.txt
@@ -0,0 +1,74 @@ +This is a testharness.js-based test. +Found 70 tests; 68 PASS, 2 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS non-animatable property 'animation' is not accessed when using a property-indexed keyframe object +PASS non-animatable property 'animationDelay' is not accessed when using a property-indexed keyframe object +PASS non-animatable property 'animationDirection' is not accessed when using a property-indexed keyframe object +PASS non-animatable property 'animationDuration' is not accessed when using a property-indexed keyframe object +PASS non-animatable property 'animationFillMode' is not accessed when using a property-indexed keyframe object +PASS non-animatable property 'animationIterationCount' is not accessed when using a property-indexed keyframe object +PASS non-animatable property 'animationName' is not accessed when using a property-indexed keyframe object +PASS non-animatable property 'animationPlayState' is not accessed when using a property-indexed keyframe object +PASS non-animatable property 'animationTimingFunction' is not accessed when using a property-indexed keyframe object +PASS non-animatable property 'transition' is not accessed when using a property-indexed keyframe object +PASS non-animatable property 'transitionDelay' is not accessed when using a property-indexed keyframe object +PASS non-animatable property 'transitionDuration' is not accessed when using a property-indexed keyframe object +PASS non-animatable property 'transitionProperty' is not accessed when using a property-indexed keyframe object +PASS non-animatable property 'transitionTimingFunction' is not accessed when using a property-indexed keyframe object +PASS non-animatable property 'contain' is not accessed when using a property-indexed keyframe object +PASS non-animatable property 'direction' is not accessed when using a property-indexed keyframe object +PASS non-animatable property 'display' is not accessed when using a property-indexed keyframe object +PASS non-animatable property 'textOrientation' is not accessed when using a property-indexed keyframe object +PASS non-animatable property 'unicodeBidi' is not accessed when using a property-indexed keyframe object +PASS non-animatable property 'willChange' is not accessed when using a property-indexed keyframe object +PASS non-animatable property 'writingMode' is not accessed when using a property-indexed keyframe object +PASS non-animatable property 'unsupportedProperty' is not accessed when using a property-indexed keyframe object +FAIL non-animatable property 'float' is not accessed when using a property-indexed keyframe object assert_equals: Accessor not called expected 0 but got 1 +PASS non-animatable property 'font-size' is not accessed when using a property-indexed keyframe object +PASS non-animatable property 'animation' is not accessed when using a keyframe sequence +PASS non-animatable property 'animationDelay' is not accessed when using a keyframe sequence +PASS non-animatable property 'animationDirection' is not accessed when using a keyframe sequence +PASS non-animatable property 'animationDuration' is not accessed when using a keyframe sequence +PASS non-animatable property 'animationFillMode' is not accessed when using a keyframe sequence +PASS non-animatable property 'animationIterationCount' is not accessed when using a keyframe sequence +PASS non-animatable property 'animationName' is not accessed when using a keyframe sequence +PASS non-animatable property 'animationPlayState' is not accessed when using a keyframe sequence +PASS non-animatable property 'animationTimingFunction' is not accessed when using a keyframe sequence +PASS non-animatable property 'transition' is not accessed when using a keyframe sequence +PASS non-animatable property 'transitionDelay' is not accessed when using a keyframe sequence +PASS non-animatable property 'transitionDuration' is not accessed when using a keyframe sequence +PASS non-animatable property 'transitionProperty' is not accessed when using a keyframe sequence +PASS non-animatable property 'transitionTimingFunction' is not accessed when using a keyframe sequence +PASS non-animatable property 'contain' is not accessed when using a keyframe sequence +PASS non-animatable property 'direction' is not accessed when using a keyframe sequence +PASS non-animatable property 'display' is not accessed when using a keyframe sequence +PASS non-animatable property 'textOrientation' is not accessed when using a keyframe sequence +PASS non-animatable property 'unicodeBidi' is not accessed when using a keyframe sequence +PASS non-animatable property 'willChange' is not accessed when using a keyframe sequence +PASS non-animatable property 'writingMode' is not accessed when using a keyframe sequence +PASS non-animatable property 'unsupportedProperty' is not accessed when using a keyframe sequence +FAIL non-animatable property 'float' is not accessed when using a keyframe sequence assert_equals: Accessor not called expected 0 but got 1 +PASS non-animatable property 'font-size' is not accessed when using a keyframe sequence +PASS Equivalent property-indexed and sequenced keyframes: two properties with one value +PASS Equivalent property-indexed and sequenced keyframes: two properties with three values +PASS Equivalent property-indexed and sequenced keyframes: two properties with different numbers of values +PASS Equivalent property-indexed and sequenced keyframes: same easing applied to all keyframes +PASS Equivalent property-indexed and sequenced keyframes: same composite applied to all keyframes +PASS Keyframes are read from a custom iterator +PASS 'easing' and 'offset' are ignored on iterable objects +PASS Keyframes are read from a custom iterator with multiple properties specified +PASS Keyframes are read from a custom iterator with where an offset is specified +PASS If a keyframe throws for an animatable property, that exception should be propagated +PASS Reading from a custom iterator that returns a non-object keyframe should throw +PASS An undefined keyframe returned from a custom iterator should be treated as a default keyframe +PASS A null keyframe returned from a custom iterator should be treated as a default keyframe +PASS A list of values returned from a custom iterator should be ignored +PASS If a custom iterator throws from next(), the exception should be rethrown +PASS Accessing a Symbol.iterator property that throws should rethrow +PASS A non-object returned from the Symbol.iterator property should cause a TypeError to be thrown +PASS Only enumerable properties on keyframes are read +PASS Only properties defined directly on keyframes are read +PASS Only enumerable properties on property-indexed keyframes are read +PASS Only properties defined directly on property-indexed keyframes are read +PASS Properties are read in ascending order by Unicode codepoint +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-001.html b/third_party/blink/web_tests/external/wpt/web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-001.html index 5c9ec84e..5bd0ae2 100644 --- a/third_party/blink/web_tests/external/wpt/web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-001.html +++ b/third_party/blink/web_tests/external/wpt/web-animations/interfaces/KeyframeEffect/processing-a-keyframes-argument-001.html
@@ -45,6 +45,8 @@ 'unsupportedProperty', + 'float', // We use the string "cssFloat" to represent "float" property, and + // so reject "float" in the keyframe-like object. 'font-size', // Supported property that uses dashes ];
diff --git a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-addmodule-resolution.https.html b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-addmodule-resolution.https.html index e946212..dc324b2 100644 --- a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-addmodule-resolution.https.html +++ b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-audioworklet-interface/audioworklet-addmodule-resolution.https.html
@@ -12,48 +12,50 @@ <script id="layout-test-code"> let audit = Audit.createTaskRunner(); - let sampleRate = 48000; - let realtimeContext = new AudioContext(); - let offlineContext = new OfflineAudioContext(1, sampleRate, sampleRate); + setup(() => { + let sampleRate = 48000; + let realtimeContext = new AudioContext(); + let offlineContext = new OfflineAudioContext(1, sampleRate, sampleRate); - let filePath = 'processors/dummy-processor.js'; + let filePath = 'processors/dummy-processor.js'; - // Test if the browser does not crash upon addModule() call after the - // realtime context construction. - audit.define( - {label: 'module-loading-after-realtime-context-creation'}, - (task, should) => { - let dummyWorkletNode = - new AudioWorkletNode(realtimeContext, 'dummy'); - dummyWorkletNode.connect(realtimeContext.destination); - should(dummyWorkletNode instanceof AudioWorkletNode, - '"dummyWorkletNode" is an instance of AudioWorkletNode ' + - 'from realtime context') - .beTrue(); - task.done(); + // Test if the browser does not crash upon addModule() call after the + // realtime context construction. + audit.define( + {label: 'module-loading-after-realtime-context-creation'}, + (task, should) => { + let dummyWorkletNode = + new AudioWorkletNode(realtimeContext, 'dummy'); + dummyWorkletNode.connect(realtimeContext.destination); + should(dummyWorkletNode instanceof AudioWorkletNode, + '"dummyWorkletNode" is an instance of AudioWorkletNode ' + + 'from realtime context') + .beTrue(); + task.done(); + }); + + // Test if the browser does not crash upon addModule() call after the + // offline context construction. + audit.define( + {label: 'module-loading-after-offline-context-creation'}, + (task, should) => { + let dummyWorkletNode = + new AudioWorkletNode(offlineContext, 'dummy'); + dummyWorkletNode.connect(offlineContext.destination); + should(dummyWorkletNode instanceof AudioWorkletNode, + '"dummyWorkletNode" is an instance of AudioWorkletNode ' + + 'from offline context') + .beTrue(); + task.done(); + }); + + Promise.all([ + realtimeContext.audioWorklet.addModule(filePath), + offlineContext.audioWorklet.addModule(filePath) + ]).then(() => { + audit.run(); }); - - // Test if the browser does not crash upon addModule() call after the - // offline context construction. - audit.define( - {label: 'module-loading-after-offline-context-creation'}, - (task, should) => { - let dummyWorkletNode = - new AudioWorkletNode(offlineContext, 'dummy'); - dummyWorkletNode.connect(offlineContext.destination); - should(dummyWorkletNode instanceof AudioWorkletNode, - '"dummyWorkletNode" is an instance of AudioWorkletNode ' + - 'from offline context') - .beTrue(); - task.done(); - }); - - Promise.all([ - realtimeContext.audioWorklet.addModule(filePath), - offlineContext.audioWorklet.addModule(filePath) - ]).then(() => { - audit.run(); - }); + }); </script> </body> </html>
diff --git a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-mediaelementaudiosourcenode-interface/mediaElementAudioSourceToScriptProcessorTest.html b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-mediaelementaudiosourcenode-interface/mediaElementAudioSourceToScriptProcessorTest.html index 3e364eb7..b1f18d39 100644 --- a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-mediaelementaudiosourcenode-interface/mediaElementAudioSourceToScriptProcessorTest.html +++ b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-mediaelementaudiosourcenode-interface/mediaElementAudioSourceToScriptProcessorTest.html
@@ -22,104 +22,106 @@ <body class="a"> <div id="log"></div> <script> - var elementSourceTest = async_test("Element Source tests completed"); + var elementSourceTest = async_test(function(elementSourceTest) { - var src = '/webaudio/resources/sin_440Hz_-6dBFS_1s.wav'; - var BUFFER_SIZE = 2048; - var context = null; - var actualBufferArrayC0 = new Float32Array(0); - var actualBufferArrayC1 = new Float32Array(0); - var audio = null, source = null, processor = null + var src = '/webaudio/resources/sin_440Hz_-6dBFS_1s.wav'; + var BUFFER_SIZE = 2048; + var context = null; + var actualBufferArrayC0 = new Float32Array(0); + var actualBufferArrayC1 = new Float32Array(0); + var audio = null, source = null, processor = null - function loadExpectedBuffer(event) { - bufferLoader = new BufferLoader( - context, - [src], - bufferLoadCompleted - ); - bufferLoader.load(); - }; + function loadExpectedBuffer(event) { + bufferLoader = new BufferLoader( + context, + [src], + elementSourceTest.step_func(bufferLoadCompleted) + ); + bufferLoader.load(); + }; - function bufferLoadCompleted(buffer) { - runTests(buffer); - }; + function bufferLoadCompleted(buffer) { + runTests(buffer); + }; - function concatTypedArray(arr1, arr2) { - var result = new Float32Array(arr1.length + arr2.length); - result.set(arr1); - result.set(arr2, arr1.length); - return result; - } + function concatTypedArray(arr1, arr2) { + var result = new Float32Array(arr1.length + arr2.length); + result.set(arr1); + result.set(arr2, arr1.length); + return result; + } - // Create Audio context. The reference wav file is sampled at 44.1 kHz so - // use the same rate for the context to remove extra resampling that might - // be required. - context = new AudioContext({sampleRate: 44100}); + // Create Audio context. The reference wav file is sampled at 44.1 kHz so + // use the same rate for the context to remove extra resampling that might + // be required. + context = new AudioContext({sampleRate: 44100}); - // Create an audio element, and a media element source - audio = document.createElement('audio'); - audio.src = src; - source = context.createMediaElementSource(audio); + // Create an audio element, and a media element source + audio = document.createElement('audio'); + audio.src = src; + source = context.createMediaElementSource(audio); -function processListener (e) { - actualBufferArrayC0 = concatTypedArray(actualBufferArrayC0, e.inputBuffer.getChannelData(0)); - actualBufferArrayC1 = concatTypedArray(actualBufferArrayC1, e.inputBuffer.getChannelData(1)); -} + function processListener (e) { + actualBufferArrayC0 = concatTypedArray(actualBufferArrayC0, e.inputBuffer.getChannelData(0)); + actualBufferArrayC1 = concatTypedArray(actualBufferArrayC1, e.inputBuffer.getChannelData(1)); + } - // Create a processor node to copy the input to the actual buffer - processor = context.createScriptProcessor(BUFFER_SIZE); - source.connect(processor); - processor.connect(context.destination); - processor.addEventListener('audioprocess', processListener); + // Create a processor node to copy the input to the actual buffer + processor = context.createScriptProcessor(BUFFER_SIZE); + source.connect(processor); + processor.connect(context.destination); + let audioprocessListener = elementSourceTest.step_func(processListener); + processor.addEventListener('audioprocess', audioprocessListener); - // When media playback ended, save the begin to compare with expected buffer - audio.addEventListener("ended", function(e) { - // Setting a timeout since we need audioProcess event to run for all samples - window.setTimeout(loadExpectedBuffer, 50); - }); + // When media playback ended, save the begin to compare with expected buffer + audio.addEventListener("ended", elementSourceTest.step_func(function(e) { + // Setting a timeout since we need audioProcess event to run for all samples + window.setTimeout(elementSourceTest.step_func(loadExpectedBuffer), 50); + })); - audio.play(); + audio.play(); - function runTests(expected) { - source.disconnect(); - processor.disconnect(); + function runTests(expected) { + source.disconnect(); + processor.disconnect(); - // firefox seems to process events after disconnect - processor.removeEventListener('audioprocess', processListener) + // firefox seems to process events after disconnect + processor.removeEventListener('audioprocess', audioprocessListener) - // Note: the expected result is from a mono source file. - var expectedBuffer = expected[0]; + // Note: the expected result is from a mono source file. + var expectedBuffer = expected[0]; - // Trim the actual elements because we don't have a fine-grained - // control over the start and end time of recording the data. - var actualTrimmedC0 = trimEmptyElements(actualBufferArrayC0); - var actualTrimmedC1 = trimEmptyElements(actualBufferArrayC1); - var expectedLength = trimEmptyElements(expectedBuffer.getChannelData(0)).length; + // Trim the actual elements because we don't have a fine-grained + // control over the start and end time of recording the data. + var actualTrimmedC0 = trimEmptyElements(actualBufferArrayC0); + var actualTrimmedC1 = trimEmptyElements(actualBufferArrayC1); + var expectedLength = trimEmptyElements(expectedBuffer.getChannelData(0)).length; - // Test that there is some data. - test(function() { - assert_greater_than(actualTrimmedC0.length, 0, - "processed data array (C0) length greater than 0"); - assert_greater_than(actualTrimmedC1.length, 0, - "processed data array (C1) length greater than 0"); - }, "Channel 0 processed some data"); + // Test that there is some data. + test(function() { + assert_greater_than(actualTrimmedC0.length, 0, + "processed data array (C0) length greater than 0"); + assert_greater_than(actualTrimmedC1.length, 0, + "processed data array (C1) length greater than 0"); + }, "Channel 0 processed some data"); - // Test the actual contents of the 1st and second channel. - test(function() { - assert_array_approx_equals( - actualTrimmedC0, - trimEmptyElements(expectedBuffer.getChannelData(0)), - 1e-4, - "comparing expected and rendered buffers (channel 0)"); - assert_array_approx_equals( - actualTrimmedC1, - trimEmptyElements(expectedBuffer.getChannelData(0)), - 1e-4, - "comparing expected and rendered buffers (channel 1)"); - }, "All data processed correctly"); + // Test the actual contents of the 1st and second channel. + test(function() { + assert_array_approx_equals( + actualTrimmedC0, + trimEmptyElements(expectedBuffer.getChannelData(0)), + 1e-4, + "comparing expected and rendered buffers (channel 0)"); + assert_array_approx_equals( + actualTrimmedC1, + trimEmptyElements(expectedBuffer.getChannelData(0)), + 1e-4, + "comparing expected and rendered buffers (channel 1)"); + }, "All data processed correctly"); - elementSourceTest.done(); - }; + elementSourceTest.done(); + }; + }, "Element Source tests completed"); </script> </body> </html>
diff --git a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-mediastreamaudiosourcenode-interface/mediastreamaudiosourcenode-routing.html b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-mediastreamaudiosourcenode-interface/mediastreamaudiosourcenode-routing.html index 2e04ab6a..816eba0 100644 --- a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-mediastreamaudiosourcenode-interface/mediastreamaudiosourcenode-routing.html +++ b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-mediastreamaudiosourcenode-interface/mediastreamaudiosourcenode-routing.html
@@ -21,105 +21,107 @@ const t = async_test( "MediaStreamAudioSourceNode captures the right track." ); - const ac = new AudioContext(); - // Test that the right track is captured. Set up a MediaStream that has two - // tracks, one with a tone at 100Hz and one with a tone at 1000Hz. - const dest0 = ac.createMediaStreamDestination(); - const dest1 = ac.createMediaStreamDestination(); - const osc0 = ac.createOscillator(); - const osc1 = ac.createOscillator(); - osc0.frequency.value = 100; - osc1.frequency.value = 1000; - osc0.connect(dest0); - osc1.connect(dest1); - osc0.start(0); - osc1.start(0); - const track0 = dest0.stream.getAudioTracks()[0]; - const track0id = track0.id; - const track1 = dest1.stream.getAudioTracks()[0]; - const track1id = track1.id; + t.step(function() { + const ac = new AudioContext(); + // Test that the right track is captured. Set up a MediaStream that has two + // tracks, one with a tone at 100Hz and one with a tone at 1000Hz. + const dest0 = ac.createMediaStreamDestination(); + const dest1 = ac.createMediaStreamDestination(); + const osc0 = ac.createOscillator(); + const osc1 = ac.createOscillator(); + osc0.frequency.value = 100; + osc1.frequency.value = 1000; + osc0.connect(dest0); + osc1.connect(dest1); + osc0.start(0); + osc1.start(0); + const track0 = dest0.stream.getAudioTracks()[0]; + const track0id = track0.id; + const track1 = dest1.stream.getAudioTracks()[0]; + const track1id = track1.id; - let ids = [track0id, track1id]; - ids.sort(); - let targetFrequency; - let otherFrequency; - if (ids[0] == track0id) { - targetFrequency = 100; - otherFrequency = 1000; - } else { - targetFrequency = 1000; - otherFrequency = 100; - } + let ids = [track0id, track1id]; + ids.sort(); + let targetFrequency; + let otherFrequency; + if (ids[0] == track0id) { + targetFrequency = 100; + otherFrequency = 1000; + } else { + targetFrequency = 1000; + otherFrequency = 100; + } - let twoTrackMediaStream = new MediaStream(); - twoTrackMediaStream.addTrack(track0); - twoTrackMediaStream.addTrack(track1); + let twoTrackMediaStream = new MediaStream(); + twoTrackMediaStream.addTrack(track0); + twoTrackMediaStream.addTrack(track1); - const twoTrackSource = ac.createMediaStreamSource(twoTrackMediaStream); - const analyser = ac.createAnalyser(); - // Don't do smoothing so that the frequency data changes quickly - analyser.smoothingTimeConstant = 0; + const twoTrackSource = ac.createMediaStreamSource(twoTrackMediaStream); + const analyser = ac.createAnalyser(); + // Don't do smoothing so that the frequency data changes quickly + analyser.smoothingTimeConstant = 0; - twoTrackSource.connect(analyser); + twoTrackSource.connect(analyser); - const indexToCheckForHighEnergy = binIndexForFrequency( - targetFrequency, - analyser - ); - const indexToCheckForLowEnergy = binIndexForFrequency( - otherFrequency, - analyser - ); - let frequencyData = new Float32Array(1024); - let checkCount = 0; - let numberOfRemovals = 0; - let stopped = false; - function analyse() { - analyser.getFloatFrequencyData(frequencyData); - // there should be high energy in the right bin, higher than 40dbfs because - // it's supposed to be a sine wave at 0dbfs - if (frequencyData[indexToCheckForHighEnergy] > -40 && !stopped) { - assert_true(true, "Correct track routed to the AudioContext."); - checkCount++; - } - if (stopped && frequencyData[indexToCheckForHighEnergy] < -40) { - assert_true( - true, - `After stopping the track, low energy is found in the + const indexToCheckForHighEnergy = binIndexForFrequency( + targetFrequency, + analyser + ); + const indexToCheckForLowEnergy = binIndexForFrequency( + otherFrequency, + analyser + ); + let frequencyData = new Float32Array(1024); + let checkCount = 0; + let numberOfRemovals = 0; + let stopped = false; + function analyse() { + analyser.getFloatFrequencyData(frequencyData); + // there should be high energy in the right bin, higher than 40dbfs because + // it's supposed to be a sine wave at 0dbfs + if (frequencyData[indexToCheckForHighEnergy] > -40 && !stopped) { + assert_true(true, "Correct track routed to the AudioContext."); + checkCount++; + } + if (stopped && frequencyData[indexToCheckForHighEnergy] < -40) { + assert_true( + true, + `After stopping the track, low energy is found in the same bin` - ); - checkCount++; - } - if (checkCount > 5 && checkCount < 20) { - twoTrackMediaStream.getAudioTracks().forEach(track => { - if (track.id == ids[0]) { - numberOfRemovals++; - window.removedTrack = track; - twoTrackMediaStream.removeTrack(track); - } - }); - assert_true( - numberOfRemovals == 1, - `The mediastreamtrack can only be + ); + checkCount++; + } + if (checkCount > 5 && checkCount < 20) { + twoTrackMediaStream.getAudioTracks().forEach(track => { + if (track.id == ids[0]) { + numberOfRemovals++; + window.removedTrack = track; + twoTrackMediaStream.removeTrack(track); + } + }); + assert_true( + numberOfRemovals == 1, + `The mediastreamtrack can only be removed once from the mediastream` - ); - } else if (checkCount >= 20 && checkCount < 30) { - window.removedTrack.stop(); - stopped = true; - } else if (checkCount >= 30) { - assert_true( - numberOfRemovals == 1, - `After removing the track from the + ); + } else if (checkCount >= 20 && checkCount < 30) { + window.removedTrack.stop(); + stopped = true; + } else if (checkCount >= 30) { + assert_true( + numberOfRemovals == 1, + `After removing the track from the mediastream, it's still routed to the graph.` - ); - // After some time, consider that it worked. - t.done(); - return; - } + ); + // After some time, consider that it worked. + t.done(); + return; + } - t.step_timeout(analyse, 100); - } - t.step_timeout(analyse, 100); + t.step_timeout(analyse, 100); + } + t.step_timeout(analyse, 100); + }); </script> </body> </html>
diff --git a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-waveshapernode-interface/curve-tests.html b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-waveshapernode-interface/curve-tests.html index a2e40777..81e64dc1 100644 --- a/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-waveshapernode-interface/curve-tests.html +++ b/third_party/blink/web_tests/external/wpt/webaudio/the-audio-api/the-waveshapernode-interface/curve-tests.html
@@ -134,35 +134,35 @@ */ function executeTest(curveData, inputData, expectedData, testName) { var stTest=async_test("WaveShaperNode - "+testName); + stTest.step(function() { - // Create offline audio context. - var ac=new OfflineAudioContext(1, inputData.length, sampleRate); + // Create offline audio context. + var ac=new OfflineAudioContext(1, inputData.length, sampleRate); - // Create the WaveShaper and its curve. - var waveShaper=ac.createWaveShaper(); - if(curveData!=null) { - var curve=new Float32Array(curveData.length); - for(var i=0;i<curveData.length;i++) { curve[i]=curveData[i]; } - waveShaper.curve=curve; - } - waveShaper.connect(ac.destination); + // Create the WaveShaper and its curve. + var waveShaper=ac.createWaveShaper(); + if(curveData!=null) { + var curve=new Float32Array(curveData.length); + for(var i=0;i<curveData.length;i++) { curve[i]=curveData[i]; } + waveShaper.curve=curve; + } + waveShaper.connect(ac.destination); - // Create buffer containing the input values. - var inputBuffer=ac.createBuffer(1, Math.max(inputData.length, 2), sampleRate); - var d=inputBuffer.getChannelData(0); - for(var i=0;i<inputData.length;i++) { d[i]=inputData[i]; } + // Create buffer containing the input values. + var inputBuffer=ac.createBuffer(1, Math.max(inputData.length, 2), sampleRate); + var d=inputBuffer.getChannelData(0); + for(var i=0;i<inputData.length;i++) { d[i]=inputData[i]; } - // Play the input buffer through the WaveShaper. - var src=ac.createBufferSource(); - src.buffer=inputBuffer; - src.connect(waveShaper); - src.start(); + // Play the input buffer through the WaveShaper. + var src=ac.createBufferSource(); + src.buffer=inputBuffer; + src.connect(waveShaper); + src.start(); - // Test the outputs match the expected values. - ac.oncomplete=function(ev) { - var d=ev.renderedBuffer.getChannelData(0); + // Test the outputs match the expected values. + ac.oncomplete=stTest.step_func_done(function(ev) { + var d=ev.renderedBuffer.getChannelData(0); - stTest.step(function() { for(var i=0;i<expectedData.length;i++) { var curveText="null"; if(curve!=null) { @@ -176,10 +176,8 @@ assert_approx_equals(d[i], expectedData[i], tolerance, comment); } }); - - stTest.done(); - }; - ac.startRendering(); + ac.startRendering(); + }); } </script> </body>
diff --git a/third_party/blink/web_tests/external/wpt/webxr/ar-module/idlharness.https.window.js b/third_party/blink/web_tests/external/wpt/webxr/ar-module/idlharness.https.window.js new file mode 100644 index 0000000..1268f4e --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webxr/ar-module/idlharness.https.window.js
@@ -0,0 +1,16 @@ +// META: script=/resources/WebIDLParser.js +// META: script=/resources/idlharness.js + +'use strict'; + +// https://immersive-web.github.io/webxr-ar-module/ + +idl_test( + ['webxr-ar-module'], + ['webxr', 'dom'], + async idl_array => { + idl_array.add_objects({ + // TODO: XRSession + }); + } +);
diff --git a/third_party/blink/web_tests/external/wpt/webxr/gamepads-module/idlharness.https.window.js b/third_party/blink/web_tests/external/wpt/webxr/gamepads-module/idlharness.https.window.js new file mode 100644 index 0000000..4509c67a8 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webxr/gamepads-module/idlharness.https.window.js
@@ -0,0 +1,16 @@ +// META: script=/resources/WebIDLParser.js +// META: script=/resources/idlharness.js + +'use strict'; + +// https://immersive-web.github.io/webxr-gamepads-module/ + +idl_test( + ['webxr-gamepads-module'], + ['webxr', 'dom'], + async idl_array => { + idl_array.add_objects({ + // TODO: XRInputSource + }); + } +);
diff --git a/third_party/blink/web_tests/external/wpt/webxr/xrWebGLLayer_constructor.https-expected.txt b/third_party/blink/web_tests/external/wpt/webxr/xrWebGLLayer_constructor.https-expected.txt new file mode 100644 index 0000000..be0603a7 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webxr/xrWebGLLayer_constructor.https-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL Ensure that XRWebGLLayer's constructor throws appropriate errors promise_test: Unhandled rejection with value: object "TypeError: Cannot read property 'then' of undefined" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/webxr/xrWebGLLayer_constructor.https.html b/third_party/blink/web_tests/external/wpt/webxr/xrWebGLLayer_constructor.https.html index 0584da79..7e57f42 100644 --- a/third_party/blink/web_tests/external/wpt/webxr/xrWebGLLayer_constructor.https.html +++ b/third_party/blink/web_tests/external/wpt/webxr/xrWebGLLayer_constructor.https.html
@@ -17,8 +17,11 @@ let gl = webglCanvas.getContext('webgl', glAttributes); return navigator.xr.test.simulateDeviceConnection(TRACKED_IMMERSIVE_DEVICE) .then(() => { - return navigator.xr.requestSession('inline') - .then((session) => { + let sessionPromise; + navigator.xr.test.simulateUserActivation(function() { + sessionPromise = navigator.xr.requestSession('inline'); + }); + return sessionPromise.then((session) => { try { let webglLayerIncompatible = new XRWebGLLayer(session, gl); } catch (err) {
diff --git a/third_party/blink/web_tests/external/wpt/worklets/animation-worklet-referrer.https-expected.txt b/third_party/blink/web_tests/external/wpt/worklets/animation-worklet-referrer.https-expected.txt index d605c756..afa46578 100644 --- a/third_party/blink/web_tests/external/wpt/worklets/animation-worklet-referrer.https-expected.txt +++ b/third_party/blink/web_tests/external/wpt/worklets/animation-worklet-referrer.https-expected.txt
@@ -7,12 +7,15 @@ PASS Importing a remote-origin script from a page that has "same-origin" referrer policy should not send referrer. PASS Importing a same-origin script from a same-origin worklet script that has "no-referrer" referrer policy should not send referrer. PASS Importing a remote-origin script from a same-origin worklet script that has "no-referrer" referrer policy should not send referrer. +PASS Importing a same-origin script from a remote-origin worklet script that has "no-referrer" referrer policy should not send referrer. PASS Importing a remote-origin script from a remote-origin worklet script that has "no-referrer" referrer policy should not send referrer. PASS Importing a same-origin script from a same-origin worklet script that has "origin" referrer policy should send referrer. PASS Importing a remote-origin script from a same-origin worklet script that has "origin" referrer policy should send referrer. +PASS Importing a same-origin script from a remote-origin worklet script that has "origin" referrer policy should send referrer. PASS Importing a remote-origin script from a remote-origin worklet script that has "origin" referrer policy should send referrer. PASS Importing a same-origin script from a same-origin worklet script that has "same-origin" referrer policy should send referrer. PASS Importing a remote-origin script from a same-origin worklet script that has "same-origin" referrer policy should not send referrer. +FAIL Importing a same-origin script from a remote-origin worklet script that has "same-origin" referrer policy should send referrer. assert_equals: expected "RESOLVED" but got "The user aborted a request." FAIL Importing a remote-origin script from a remote-origin worklet script that has "same-origin" referrer policy should not send referrer. assert_equals: expected "RESOLVED" but got "The user aborted a request." Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/worklets/audio-worklet-referrer.https-expected.txt b/third_party/blink/web_tests/external/wpt/worklets/audio-worklet-referrer.https-expected.txt index d605c756..afa46578 100644 --- a/third_party/blink/web_tests/external/wpt/worklets/audio-worklet-referrer.https-expected.txt +++ b/third_party/blink/web_tests/external/wpt/worklets/audio-worklet-referrer.https-expected.txt
@@ -7,12 +7,15 @@ PASS Importing a remote-origin script from a page that has "same-origin" referrer policy should not send referrer. PASS Importing a same-origin script from a same-origin worklet script that has "no-referrer" referrer policy should not send referrer. PASS Importing a remote-origin script from a same-origin worklet script that has "no-referrer" referrer policy should not send referrer. +PASS Importing a same-origin script from a remote-origin worklet script that has "no-referrer" referrer policy should not send referrer. PASS Importing a remote-origin script from a remote-origin worklet script that has "no-referrer" referrer policy should not send referrer. PASS Importing a same-origin script from a same-origin worklet script that has "origin" referrer policy should send referrer. PASS Importing a remote-origin script from a same-origin worklet script that has "origin" referrer policy should send referrer. +PASS Importing a same-origin script from a remote-origin worklet script that has "origin" referrer policy should send referrer. PASS Importing a remote-origin script from a remote-origin worklet script that has "origin" referrer policy should send referrer. PASS Importing a same-origin script from a same-origin worklet script that has "same-origin" referrer policy should send referrer. PASS Importing a remote-origin script from a same-origin worklet script that has "same-origin" referrer policy should not send referrer. +FAIL Importing a same-origin script from a remote-origin worklet script that has "same-origin" referrer policy should send referrer. assert_equals: expected "RESOLVED" but got "The user aborted a request." FAIL Importing a remote-origin script from a remote-origin worklet script that has "same-origin" referrer policy should not send referrer. assert_equals: expected "RESOLVED" but got "The user aborted a request." Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/worklets/layout-worklet-referrer.https-expected.txt b/third_party/blink/web_tests/external/wpt/worklets/layout-worklet-referrer.https-expected.txt index d605c756..afa46578 100644 --- a/third_party/blink/web_tests/external/wpt/worklets/layout-worklet-referrer.https-expected.txt +++ b/third_party/blink/web_tests/external/wpt/worklets/layout-worklet-referrer.https-expected.txt
@@ -7,12 +7,15 @@ PASS Importing a remote-origin script from a page that has "same-origin" referrer policy should not send referrer. PASS Importing a same-origin script from a same-origin worklet script that has "no-referrer" referrer policy should not send referrer. PASS Importing a remote-origin script from a same-origin worklet script that has "no-referrer" referrer policy should not send referrer. +PASS Importing a same-origin script from a remote-origin worklet script that has "no-referrer" referrer policy should not send referrer. PASS Importing a remote-origin script from a remote-origin worklet script that has "no-referrer" referrer policy should not send referrer. PASS Importing a same-origin script from a same-origin worklet script that has "origin" referrer policy should send referrer. PASS Importing a remote-origin script from a same-origin worklet script that has "origin" referrer policy should send referrer. +PASS Importing a same-origin script from a remote-origin worklet script that has "origin" referrer policy should send referrer. PASS Importing a remote-origin script from a remote-origin worklet script that has "origin" referrer policy should send referrer. PASS Importing a same-origin script from a same-origin worklet script that has "same-origin" referrer policy should send referrer. PASS Importing a remote-origin script from a same-origin worklet script that has "same-origin" referrer policy should not send referrer. +FAIL Importing a same-origin script from a remote-origin worklet script that has "same-origin" referrer policy should send referrer. assert_equals: expected "RESOLVED" but got "The user aborted a request." FAIL Importing a remote-origin script from a remote-origin worklet script that has "same-origin" referrer policy should not send referrer. assert_equals: expected "RESOLVED" but got "The user aborted a request." Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/worklets/paint-worklet-referrer.https-expected.txt b/third_party/blink/web_tests/external/wpt/worklets/paint-worklet-referrer.https-expected.txt index d605c756..afa46578 100644 --- a/third_party/blink/web_tests/external/wpt/worklets/paint-worklet-referrer.https-expected.txt +++ b/third_party/blink/web_tests/external/wpt/worklets/paint-worklet-referrer.https-expected.txt
@@ -7,12 +7,15 @@ PASS Importing a remote-origin script from a page that has "same-origin" referrer policy should not send referrer. PASS Importing a same-origin script from a same-origin worklet script that has "no-referrer" referrer policy should not send referrer. PASS Importing a remote-origin script from a same-origin worklet script that has "no-referrer" referrer policy should not send referrer. +PASS Importing a same-origin script from a remote-origin worklet script that has "no-referrer" referrer policy should not send referrer. PASS Importing a remote-origin script from a remote-origin worklet script that has "no-referrer" referrer policy should not send referrer. PASS Importing a same-origin script from a same-origin worklet script that has "origin" referrer policy should send referrer. PASS Importing a remote-origin script from a same-origin worklet script that has "origin" referrer policy should send referrer. +PASS Importing a same-origin script from a remote-origin worklet script that has "origin" referrer policy should send referrer. PASS Importing a remote-origin script from a remote-origin worklet script that has "origin" referrer policy should send referrer. PASS Importing a same-origin script from a same-origin worklet script that has "same-origin" referrer policy should send referrer. PASS Importing a remote-origin script from a same-origin worklet script that has "same-origin" referrer policy should not send referrer. +FAIL Importing a same-origin script from a remote-origin worklet script that has "same-origin" referrer policy should send referrer. assert_equals: expected "RESOLVED" but got "The user aborted a request." FAIL Importing a remote-origin script from a remote-origin worklet script that has "same-origin" referrer policy should not send referrer. assert_equals: expected "RESOLVED" but got "The user aborted a request." Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/worklets/resources/import-same-origin-referrer-checker-worklet-script-from-remote-origin.sub.js b/third_party/blink/web_tests/external/wpt/worklets/resources/import-same-origin-referrer-checker-worklet-script-from-remote-origin.sub.js new file mode 100644 index 0000000..33af2258 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/worklets/resources/import-same-origin-referrer-checker-worklet-script-from-remote-origin.sub.js
@@ -0,0 +1,2 @@ +// Forward GET parameters to the server. +import '{{GET[requestor_origin]}}/worklets/resources/referrer-checker.py?referrer_policy={{GET[referrer_policy]}}&expected_referrer={{GET[expected_referrer]}}';
diff --git a/third_party/blink/web_tests/external/wpt/worklets/resources/import-same-origin-referrer-checker-worklet-script-from-remote-origin.sub.js.headers b/third_party/blink/web_tests/external/wpt/worklets/resources/import-same-origin-referrer-checker-worklet-script-from-remote-origin.sub.js.headers new file mode 100644 index 0000000..cb762ef --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/worklets/resources/import-same-origin-referrer-checker-worklet-script-from-remote-origin.sub.js.headers
@@ -0,0 +1 @@ +Access-Control-Allow-Origin: *
diff --git a/third_party/blink/web_tests/external/wpt/worklets/resources/referrer-tests.js b/third_party/blink/web_tests/external/wpt/worklets/resources/referrer-tests.js index 01b8e2a..b3c4a048 100644 --- a/third_party/blink/web_tests/external/wpt/worklets/resources/referrer-tests.js +++ b/third_party/blink/web_tests/external/wpt/worklets/resources/referrer-tests.js
@@ -88,6 +88,7 @@ // Tests for descendant script fetch ----------------------------------------- + // Referrer policy: no-referrer. promise_test(() => { return runReferrerTest({ workletType: workletType, fetchType: 'descendant', @@ -111,10 +112,20 @@ fetchType: 'descendant', referrerPolicy: 'no-referrer', scriptOrigins: { topLevel: 'remote', + descendant: 'same' } }); + }, 'Importing a same-origin script from a remote-origin worklet script ' + + 'that has "no-referrer" referrer policy should not send referrer.'); + + promise_test(() => { + return runReferrerTest({ workletType: workletType, + fetchType: 'descendant', + referrerPolicy: 'no-referrer', + scriptOrigins: { topLevel: 'remote', descendant: 'remote' } }); }, 'Importing a remote-origin script from a remote-origin worklet script ' + 'that has "no-referrer" referrer policy should not send referrer.'); + // Referrer policy: origin. promise_test(() => { return runReferrerTest({ workletType: workletType, fetchType: 'descendant', @@ -138,10 +149,20 @@ fetchType: 'descendant', referrerPolicy: 'origin', scriptOrigins: { topLevel: 'remote', + descendant: 'same' } }); + }, 'Importing a same-origin script from a remote-origin worklet script ' + + 'that has "origin" referrer policy should send referrer.'); + + promise_test(() => { + return runReferrerTest({ workletType: workletType, + fetchType: 'descendant', + referrerPolicy: 'origin', + scriptOrigins: { topLevel: 'remote', descendant: 'remote' } }); }, 'Importing a remote-origin script from a remote-origin worklet script ' + 'that has "origin" referrer policy should send referrer.'); + // Referrer policy: same-origin. promise_test(() => { return runReferrerTest({ workletType: workletType, fetchType: 'descendant', @@ -165,7 +186,18 @@ fetchType: 'descendant', referrerPolicy: 'same-origin', scriptOrigins: { topLevel: 'remote', + descendant: 'same' } }); + }, 'Importing a same-origin script from a remote-origin worklet script ' + + 'that has "same-origin" referrer policy should send referrer.'); + + promise_test(() => { + return runReferrerTest({ workletType: workletType, + fetchType: 'descendant', + referrerPolicy: 'same-origin', + scriptOrigins: { topLevel: 'remote', descendant: 'remote' } }); }, 'Importing a remote-origin script from a remote-origin worklet script ' + 'that has "same-origin" referrer policy should not send referrer.'); + + // TODO(domfarolino): Add tests for more referrer policies. }
diff --git a/third_party/blink/web_tests/external/wpt/worklets/resources/referrer-window.html b/third_party/blink/web_tests/external/wpt/worklets/resources/referrer-window.html index 4817f045..934e3dc41 100644 --- a/third_party/blink/web_tests/external/wpt/worklets/resources/referrer-window.html +++ b/third_party/blink/web_tests/external/wpt/worklets/resources/referrer-window.html
@@ -32,6 +32,14 @@ location.href); } if (scriptOrigins.topLevel === 'remote' && + scriptOrigins.descendant === 'same') { + url = new URL( + get_host_info().HTTPS_REMOTE_ORIGIN + + '/worklets/resources/' + + 'import-same-origin-referrer-checker-worklet-script-from-remote-origin.sub.js'); + return url; + } + if (scriptOrigins.topLevel === 'remote' && scriptOrigins.descendant === 'remote') { return new URL( get_host_info().HTTPS_REMOTE_ORIGIN + @@ -88,6 +96,7 @@ } const params = new URLSearchParams; + params.append('requestor_origin', document.location.origin); params.append('referrer_policy', referrerPolicy); params.append('expected_referrer', expectedReferrer);
diff --git a/third_party/blink/web_tests/external/wpt/xhr/xmlhttprequest-sync-default-feature-policy.sub.html b/third_party/blink/web_tests/external/wpt/xhr/xmlhttprequest-sync-default-feature-policy.sub.html index 5ad55577..ab5b78b 100644 --- a/third_party/blink/web_tests/external/wpt/xhr/xmlhttprequest-sync-default-feature-policy.sub.html +++ b/third_party/blink/web_tests/external/wpt/xhr/xmlhttprequest-sync-default-feature-policy.sub.html
@@ -9,7 +9,7 @@ <script> 'use strict'; run_all_fp_tests_allow_all( - 'http://{{domains[www]}}:{{ports[http][0]}}', + 'http://{{hosts[alt][]}}:{{ports[http][0]}}', 'sync-xhr', 'NetworkError', () => {
diff --git a/third_party/blink/web_tests/hid/hid_getDevices.html b/third_party/blink/web_tests/hid/hid_getDevices.html index f5652ec7..5bb3c2a 100644 --- a/third_party/blink/web_tests/hid/hid_getDevices.html +++ b/third_party/blink/web_tests/hid/hid_getDevices.html
@@ -12,7 +12,7 @@ promise_test(async () => { let interceptor = - new MojoInterfaceInterceptor(blink.mojom.HidService.name); + new MojoInterfaceInterceptor(blink.mojom.HidService.name, "context", true); interceptor.oninterfacerequest = e => e.handle.close(); interceptor.start();
diff --git a/third_party/blink/web_tests/hid/hid_requestDevice.html b/third_party/blink/web_tests/hid/hid_requestDevice.html index 4c01da5..edb92ac 100644 --- a/third_party/blink/web_tests/hid/hid_requestDevice.html +++ b/third_party/blink/web_tests/hid/hid_requestDevice.html
@@ -20,7 +20,7 @@ promise_test(async (t) => { let interceptor = - new MojoInterfaceInterceptor(blink.mojom.HidService.name); + new MojoInterfaceInterceptor(blink.mojom.HidService.name, "context", true); interceptor.oninterfacerequest = e => e.handle.close(); interceptor.start();
diff --git a/third_party/blink/web_tests/hid/resources/hid-test-utils.js b/third_party/blink/web_tests/hid/resources/hid-test-utils.js index 0fdbd659..b177301 100644 --- a/third_party/blink/web_tests/hid/resources/hid-test-utils.js +++ b/third_party/blink/web_tests/hid/resources/hid-test-utils.js
@@ -134,7 +134,7 @@ class FakeHidService { constructor() { this.interceptor_ = - new MojoInterfaceInterceptor(blink.mojom.HidService.name); + new MojoInterfaceInterceptor(blink.mojom.HidService.name, "context", true); this.interceptor_.oninterfacerequest = e => this.bind(e.handle); this.bindingSet_ = new mojo.BindingSet(blink.mojom.HidService); this.nextGuidValue_ = 0;
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-breakpoints/use-possible-breakpoints-to-resolve-breakpoint.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-breakpoints/use-possible-breakpoints-to-resolve-breakpoint.js index 7542fe5..c0740b6 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-breakpoints/use-possible-breakpoints-to-resolve-breakpoint.js +++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-breakpoints/use-possible-breakpoints-to-resolve-breakpoint.js
@@ -54,7 +54,8 @@ SourcesTestRunner.debuggerPlugin(sourceFrame)._handleGutterClick({ data: { lineNumber: lineNumberClicked, - event: {button: 0, shiftKey: shiftKey, consume: () => true} + event: {button: 0, shiftKey: shiftKey, consume: () => true}, + gutterType: SourceFrame.SourcesTextEditor.lineNumbersGutterType } }); return promise;
diff --git a/third_party/blink/web_tests/platform/linux/external/wpt/payment-handler/change-payment-method-manual.https-expected.txt b/third_party/blink/web_tests/platform/linux/external/wpt/payment-handler/change-payment-method-manual.https-expected.txt deleted file mode 100644 index 099831a..0000000 --- a/third_party/blink/web_tests/platform/linux/external/wpt/payment-handler/change-payment-method-manual.https-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL Tests for PaymentRequestEvent.changePaymentMethod() Not allowed to install this payment handler -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-hasenrolledinstrument-method.tentative.https-expected.txt b/third_party/blink/web_tests/platform/linux/external/wpt/payment-request/payment-request-hasenrolledinstrument-method.tentative.https-expected.txt similarity index 94% rename from third_party/blink/web_tests/external/wpt/payment-request/payment-request-hasenrolledinstrument-method.tentative.https-expected.txt rename to third_party/blink/web_tests/platform/linux/external/wpt/payment-request/payment-request-hasenrolledinstrument-method.tentative.https-expected.txt index ad1d3ce1..a24f90e2 100644 --- a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-hasenrolledinstrument-method.tentative.https-expected.txt +++ b/third_party/blink/web_tests/platform/linux/external/wpt/payment-request/payment-request-hasenrolledinstrument-method.tentative.https-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Harness Error. harness_status.status = 1 , harness_status.message = Already called show() once +Harness Error. harness_status.status = 1 , harness_status.message = Unhandled rejection: Already called show() once FAIL hasEnrolledInstrument() resolves to false for unsupported payment methods. promise_test: Unhandled rejection with value: object "UnknownError: Renderer process could not establish or lost IPC connection to the PaymentRequest service in the browser process." FAIL If request.[[state]] is "interactive", then return a promise rejected with an "InvalidStateError" DOMException. promise_test: Unhandled rejection with value: object "InvalidStateError: No show() or retry() in progress, so nothing to abort" FAIL If request.[[state]] is "closed", then return a promise rejected with an "InvalidStateError" DOMException. promise_test: Unhandled rejection with value: object "InvalidStateError: No show() or retry() in progress, so nothing to abort"
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/payment-handler/change-payment-method-manual.https-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/payment-handler/change-payment-method-manual.https-expected.txt deleted file mode 100644 index 099831a..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.10/external/wpt/payment-handler/change-payment-method-manual.https-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL Tests for PaymentRequestEvent.changePaymentMethod() Not allowed to install this payment handler -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/mac-mac10.11/external/wpt/payment-handler/change-payment-method-manual.https-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.11/external/wpt/payment-handler/change-payment-method-manual.https-expected.txt deleted file mode 100644 index 099831a..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.11/external/wpt/payment-handler/change-payment-method-manual.https-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL Tests for PaymentRequestEvent.changePaymentMethod() Not allowed to install this payment handler -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/external/wpt/payment-handler/change-payment-method-manual.https-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.12/external/wpt/payment-handler/change-payment-method-manual.https-expected.txt deleted file mode 100644 index 099831a..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.12/external/wpt/payment-handler/change-payment-method-manual.https-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL Tests for PaymentRequestEvent.changePaymentMethod() Not allowed to install this payment handler -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/mac-retina/external/wpt/payment-handler/change-payment-method-manual.https-expected.txt b/third_party/blink/web_tests/platform/mac-retina/external/wpt/payment-handler/change-payment-method-manual.https-expected.txt deleted file mode 100644 index 099831a..0000000 --- a/third_party/blink/web_tests/platform/mac-retina/external/wpt/payment-handler/change-payment-method-manual.https-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL Tests for PaymentRequestEvent.changePaymentMethod() Not allowed to install this payment handler -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/fullscreen/api/element-request-fullscreen-and-move-to-iframe-manual-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/fullscreen/api/element-request-fullscreen-and-move-to-iframe-manual-expected.txt deleted file mode 100644 index b4e9af13..0000000 --- a/third_party/blink/web_tests/platform/mac/external/wpt/fullscreen/api/element-request-fullscreen-and-move-to-iframe-manual-expected.txt +++ /dev/null
@@ -1,5 +0,0 @@ -This is a testharness.js-based test. -Harness Error. harness_status.status = 1 , harness_status.message = fullscreen error -PASS Element#requestFullscreen() followed by moving the element into an iframe -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/payment-handler/change-payment-method-manual.https-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/payment-handler/change-payment-method-manual.https-expected.txt deleted file mode 100644 index 099831a..0000000 --- a/third_party/blink/web_tests/platform/mac/external/wpt/payment-handler/change-payment-method-manual.https-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL Tests for PaymentRequestEvent.changePaymentMethod() Not allowed to install this payment handler -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-hasenrolledinstrument-method.tentative.https-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/payment-request/payment-request-hasenrolledinstrument-method.tentative.https-expected.txt similarity index 94% copy from third_party/blink/web_tests/external/wpt/payment-request/payment-request-hasenrolledinstrument-method.tentative.https-expected.txt copy to third_party/blink/web_tests/platform/mac/external/wpt/payment-request/payment-request-hasenrolledinstrument-method.tentative.https-expected.txt index ad1d3ce1..a24f90e2 100644 --- a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-hasenrolledinstrument-method.tentative.https-expected.txt +++ b/third_party/blink/web_tests/platform/mac/external/wpt/payment-request/payment-request-hasenrolledinstrument-method.tentative.https-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Harness Error. harness_status.status = 1 , harness_status.message = Already called show() once +Harness Error. harness_status.status = 1 , harness_status.message = Unhandled rejection: Already called show() once FAIL hasEnrolledInstrument() resolves to false for unsupported payment methods. promise_test: Unhandled rejection with value: object "UnknownError: Renderer process could not establish or lost IPC connection to the PaymentRequest service in the browser process." FAIL If request.[[state]] is "interactive", then return a promise rejected with an "InvalidStateError" DOMException. promise_test: Unhandled rejection with value: object "InvalidStateError: No show() or retry() in progress, so nothing to abort" FAIL If request.[[state]] is "closed", then return a promise rejected with an "InvalidStateError" DOMException. promise_test: Unhandled rejection with value: object "InvalidStateError: No show() or retry() in progress, so nothing to abort"
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/payment-handler/change-payment-method-manual.https-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/payment-handler/change-payment-method-manual.https-expected.txt deleted file mode 100644 index 099831a..0000000 --- a/third_party/blink/web_tests/platform/win/external/wpt/payment-handler/change-payment-method-manual.https-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL Tests for PaymentRequestEvent.changePaymentMethod() Not allowed to install this payment handler -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/payment-request/payment-request-hasenrolledinstrument-method.tentative.https-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/payment-request/payment-request-hasenrolledinstrument-method.tentative.https-expected.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/third_party/blink/web_tests/platform/win/external/wpt/payment-request/payment-request-hasenrolledinstrument-method.tentative.https-expected.txt
diff --git a/third_party/blink/web_tests/platform/win7/external/wpt/payment-handler/change-payment-method-manual.https-expected.txt b/third_party/blink/web_tests/platform/win7/external/wpt/payment-handler/change-payment-method-manual.https-expected.txt deleted file mode 100644 index 099831a..0000000 --- a/third_party/blink/web_tests/platform/win7/external/wpt/payment-handler/change-payment-method-manual.https-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL Tests for PaymentRequestEvent.changePaymentMethod() Not allowed to install this payment handler -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-hasenrolledinstrument-method.tentative.https-expected.txt b/third_party/blink/web_tests/platform/win7/external/wpt/payment-request/payment-request-hasenrolledinstrument-method.tentative.https-expected.txt similarity index 94% copy from third_party/blink/web_tests/external/wpt/payment-request/payment-request-hasenrolledinstrument-method.tentative.https-expected.txt copy to third_party/blink/web_tests/platform/win7/external/wpt/payment-request/payment-request-hasenrolledinstrument-method.tentative.https-expected.txt index ad1d3ce1..a24f90e2 100644 --- a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-hasenrolledinstrument-method.tentative.https-expected.txt +++ b/third_party/blink/web_tests/platform/win7/external/wpt/payment-request/payment-request-hasenrolledinstrument-method.tentative.https-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Harness Error. harness_status.status = 1 , harness_status.message = Already called show() once +Harness Error. harness_status.status = 1 , harness_status.message = Unhandled rejection: Already called show() once FAIL hasEnrolledInstrument() resolves to false for unsupported payment methods. promise_test: Unhandled rejection with value: object "UnknownError: Renderer process could not establish or lost IPC connection to the PaymentRequest service in the browser process." FAIL If request.[[state]] is "interactive", then return a promise rejected with an "InvalidStateError" DOMException. promise_test: Unhandled rejection with value: object "InvalidStateError: No show() or retry() in progress, so nothing to abort" FAIL If request.[[state]] is "closed", then return a promise rejected with an "InvalidStateError" DOMException. promise_test: Unhandled rejection with value: object "InvalidStateError: No show() or retry() in progress, so nothing to abort"
diff --git a/third_party/blink/web_tests/svg/animations/updated-values-after-sandwich-order-change.html b/third_party/blink/web_tests/svg/animations/updated-values-after-sandwich-order-change.html new file mode 100644 index 0000000..9074009 --- /dev/null +++ b/third_party/blink/web_tests/svg/animations/updated-values-after-sandwich-order-change.html
@@ -0,0 +1,23 @@ +<!DOCTYPE html> +<title>Updating the 'values' attribute after sandwich order change</title> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<svg> + <rect width="100" height="100"> + <animate attributeName="opacity" begin="0ms; 40ms; 70ms" dur="10ms" id="first" fill="freeze"/> + <animate attributeName="opacity" begin="20ms; 50ms" dur="10ms" from="1" to="1" fill="freeze"/> + </rect> +</svg> +<script> + async_test(t => { + let first_animate = document.getElementById("first"); + window.onload = t.step_func(() => { + let svg = first_animate.ownerSVGElement; + svg.pauseAnimations(); + window.requestAnimationFrame(t.step_func_done(() => { + svg.unpauseAnimations(); + first_animate.setAttribute("values", "0; 1"); + })); + }); + }); +</script>
diff --git a/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCRtpTransceiver.https-expected.txt b/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCRtpTransceiver.https-expected.txt index eec6507..e2a810c 100644 --- a/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCRtpTransceiver.https-expected.txt +++ b/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCRtpTransceiver.https-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Harness Error. harness_status.status = 1 , harness_status.message = Cannot read property 'receiver' of undefined +Harness Error. harness_status.status = 1 , harness_status.message = Unhandled rejection: Cannot read property 'receiver' of undefined FAIL checkAddTransceiverNoTrack promise_test: Unhandled rejection with value: object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'." FAIL checkAddTransceiverWithTrack promise_test: Unhandled rejection with value: object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'." FAIL checkAddTransceiverWithAddTrack assert_equals: expected "[{currentDirection:null,direction:\"sendrecv\",mid:null,receiver:{track:{kind:\"audio\"}},sender:{track:{}},stopped:false},{currentDirection:null,direction:\"sendrecv\",mid:null,receiver:{track:{kind:\"video\"}},sender:{track:{}},stopped:false}]" but got "[]"
diff --git a/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCSctpTransport-events-expected.txt b/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCSctpTransport-events-expected.txt index 9a5c3c22..2289ca1 100644 --- a/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCSctpTransport-events-expected.txt +++ b/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCSctpTransport-events-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Harness Error. harness_status.status = 1 , harness_status.message = Cannot read property 'state' of null +Harness Error. harness_status.status = 1 , harness_status.message = Unhandled rejection: Cannot read property 'state' of null FAIL SctpTransport objects are created at appropriate times assert_not_equals: got disallowed value null FAIL SctpTransport reaches connected and closed state promise_test: Unhandled rejection with value: object "TypeError: Cannot read property 'state' of null" Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCSctpTransport-maxChannels-expected.txt b/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCSctpTransport-maxChannels-expected.txt index 4d62c3a..b413fd3 100644 --- a/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCSctpTransport-maxChannels-expected.txt +++ b/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCSctpTransport-maxChannels-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Harness Error. harness_status.status = 1 , harness_status.message = Cannot read property 'state' of null +Harness Error. harness_status.status = 1 , harness_status.message = Unhandled rejection: Cannot read property 'state' of null FAIL An unconnected peerconnection must not have maxChannels set assert_not_equals: RTCSctpTransport must be available got disallowed value null FAIL maxChannels gets instantiated after connecting promise_test: Unhandled rejection with value: object "TypeError: Cannot read property 'maxChannels' of null" Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/lock-grid-with-positioned-child.html b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/lock-grid-with-positioned-child.html new file mode 100644 index 0000000..17456cc6 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/display-lock/rendersubtree/lock-grid-with-positioned-child.html
@@ -0,0 +1,41 @@ +<!doctype HTML> +<html class="reftest-wait"> +<meta charset="utf8"> +<title>Display Locking: lock grid with positioned child</title> +<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org"> +<link rel="help" href="https://github.com/WICG/display-locking"> +<link rel="match" href="pass-ref.html"> +<script src="/common/reftest-wait.js"></script> +<script src="resources/utils.js"></script> + +<style> +#grid { + display: grid; +} +#positioned { + position: absolute; +} +</style> + +<div id=log></div> +<div id=grid> + <div id=positioned>lorem ipsum</div> +</div> + +<script> +function finishTest(status_string) { + if (document.getElementById("log").innerHTML === "") + document.getElementById("log").innerHTML = status_string; + takeScreenshot(); +} + +function runTest() { + const container = document.getElementById("grid"); + setInvisible(container).then(() => { + finishTest("PASS"); + }); +} + +window.onload = () => requestAnimationFrame(runTest); +</script> +</html>
diff --git a/tools/clang/blink_gc_plugin/process-graph.py b/tools/clang/blink_gc_plugin/process-graph.py index 879f95c..fcbce952 100755 --- a/tools/clang/blink_gc_plugin/process-graph.py +++ b/tools/clang/blink_gc_plugin/process-graph.py
@@ -3,6 +3,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +from __future__ import print_function import argparse, os, sys, json, subprocess, pickle, StringIO parser = argparse.ArgumentParser( @@ -312,7 +313,7 @@ sout = out.getvalue() if not is_ignored_cycle(sout): print("\nFound a potentially leaking cycle starting from a GC root:\n", - sout) + sout, sep="") set_reported_error(True) def load_graph():
diff --git a/tools/gritsettings/translation_expectations.pyl b/tools/gritsettings/translation_expectations.pyl index 2e0f459b..7dc85b2 100644 --- a/tools/gritsettings/translation_expectations.pyl +++ b/tools/gritsettings/translation_expectations.pyl
@@ -39,6 +39,7 @@ "chrome/browser/resources/chromeos/chromevox/strings/chromevox_strings.grd", "chrome/browser/resources/chromeos/select_to_speak/strings/select_to_speak_strings.grd", "chrome/browser/resources/chromeos/switch_access/strings/switch_access_strings.grd", + "chrome/browser/touch_to_fill/android/internal/java/strings/android_touch_to_fill_strings.grd", "chrome/browser/ui/android/widget/java/strings/android_ui_widget_strings.grd", "chrome/credential_provider/gaiacp/gaia_resources.grd", "chromeos/chromeos_strings.grd",
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index a430119..d4ddab1 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -13147,6 +13147,17 @@ <int value="6" label="Texture array has one element"/> </enum> +<enum name="DefaultAppName"> + <int value="0" label="Calculator"/> + <int value="1" label="Text"/> + <int value="2" label="Get Help"/> + <int value="3" label="Gallery"/> + <int value="4" label="Video Player"/> + <int value="5" label="Audio Player"/> + <int value="6" label="Chrome Canvas"/> + <int value="7" label="Camera"/> +</enum> + <enum name="DefaultBrowserAsyncAttemptResult"> <obsolete> Deprecated 2015/11. Renamed to SetDefaultAttemptResult. @@ -32751,6 +32762,12 @@ </int> </enum> +<enum name="JavaScriptOnlyValueInPasswordForm"> + <int value="0" label="Only values from JavaScript, and no user focus"/> + <int value="1" label="Only values from JavaScript, and user focus"/> + <int value="2" label="User typed or autofilled values"/> +</enum> + <enum name="JpegColorSpace"> <int value="0" label="Unknown color space"> This is the bucket that counts the images that did not fall under any of the
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index b98eef9..1b457dd0 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -5651,6 +5651,18 @@ </summary> </histogram> +<histogram base="true" name="Apps.DefaultAppLaunch" enum="DefaultAppName" + expires_after="2020-03-21"> +<!-- Name completed by histogram_suffixes name="DefaultAppLaunchSource" --> + + <owner>dominickn@chromium.org</owner> + <owner>nancylingwang@chromium.org</owner> + <owner>nigeltao@chromium.org</owner> + <summary> + Records when a user attempts to launch a particular Chrome OS app. + </summary> +</histogram> + <histogram name="Apps.HomeLauncherTransition.AnimationSmoothness" units="%" expires_after="2020-04-01"> <!-- Name completed by histogram suffixes @@ -71466,7 +71478,7 @@ <owner>clamy@chromium.org</owner> <owner>nasko@chromium.org</owner> <summary> - Whether the navigation led to a change of BrowsingInstance or not + Whether a main frame navigation led to a change of BrowsingInstance or not. </summary> </histogram> @@ -71482,7 +71494,7 @@ <owner>clamy@chromium.org</owner> <owner>nasko@chromium.org</owner> <summary> - Whether the navigation led to a change of SiteInstance or not + Whether the navigation led to a change of SiteInstance or not. </summary> </histogram> @@ -100866,6 +100878,16 @@ </summary> </histogram> +<histogram name="PasswordManager.JavaScriptOnlyValueInSubmittedForm" + enum="JavaScriptOnlyValueInPasswordForm" expires_after="M87"> + <owner>dvadym@chromium.org</owner> + <owner>battre@chromium.org</owner> + <summary> + Records whether a successfully submitted password form has only values that + came from JavaScript. + </summary> +</histogram> + <histogram name="PasswordManager.KeychainMigration.NumChromeOwnedInaccessiblePasswords" units="units"> @@ -106854,6 +106876,28 @@ </summary> </histogram> +<histogram name="PLT.iOS.BrowserInitiatedPageLoadTime" units="ms" + expires_after="2020-08-09"> + <owner>djean@chromium.org</owner> + <owner>eugenebut@chromium.org</owner> + <summary> + Page load time for Browser-initiated navigations. Recorded when + CRWWebRequestController::didFinishWithURL completes successfully. iOS + specific. + </summary> +</histogram> + +<histogram name="PLT.iOS.RendererInitiatedPageLoadTime" units="ms" + expires_after="2020-08-09"> + <owner>djean@chromium.org</owner> + <owner>eugenebut@chromium.org</owner> + <summary> + Page load time for Renderer-initiated navigations. Recorded when + CRWWebRequestController::didFinishWithURL completes successfully. iOS + specific. + </summary> +</histogram> + <histogram name="PLT.LoadType" enum="LoadType" expires_after="2016-08-02"> <obsolete> Use PageLoad.PaintTiming.NavigationToFirstContentfulPaint.LoadType.* @@ -132268,7 +132312,7 @@ </histogram> <histogram name="Signin.AndroidAccountSigninViewSeedingTime" units="ms" - expires_after="M80"> + expires_after="M85"> <owner>bsazonov@chromium.org</owner> <summary> The time it takes to seed accounts before proceeding to the account @@ -165702,6 +165746,19 @@ <affected-histogram name="Renderer4.ImageDecodeTaskDurationUs"/> </histogram_suffixes> +<histogram_suffixes name="DefaultAppLaunchSource" separator="."> + <suffix name="FromAppListGrid" label="From app list grid."/> + <suffix name="FromAppListGridContextMenu" + label="From app list grid context menu."/> + <suffix name="FromAppListQuery" label="From app list query."/> + <suffix name="FromAppListQueryContextMenu" + label="From app list query context menu."/> + <suffix name="FromAppListRecommendation" + label="From app list recommendation."/> + <suffix name="FromShelf" label="From shelf."/> + <affected-histogram name="Apps.DefaultAppLaunch"/> +</histogram_suffixes> + <histogram_suffixes name="DefaultAppsExperiment" separator="_"> <suffix name="NoDefaultApps" label="User's without default apps installed"/> <suffix name="WithDefaultApps" label="User's with default apps installed"/> @@ -169330,6 +169387,7 @@ <histogram_suffixes name="NavigationFrameType" separator="."> <suffix name="MainFrame" label="Navigation in the main frame."/> <suffix name="Subframe" label="Navigation in a subframe."/> + <affected-histogram name="Navigation.IsSameSiteInstance"/> <affected-histogram name="Navigation.StartToCommit"/> <affected-histogram name="Navigation.StartToCommit.CrossProcess"/> <affected-histogram name="Navigation.StartToCommit.SameProcess"/>
diff --git a/tools/perf/benchmarks/system_health_smoke_test.py b/tools/perf/benchmarks/system_health_smoke_test.py index 21d8839..75cb063 100644 --- a/tools/perf/benchmarks/system_health_smoke_test.py +++ b/tools/perf/benchmarks/system_health_smoke_test.py
@@ -41,11 +41,14 @@ # and will later be removed. 'system_health.memory_mobile/browse:tech:discourse_infinite_scroll', 'system_health.memory_mobile/browse:social:facebook_infinite_scroll', + 'system_health.memory_mobile/browse:social:instagram', + 'system_health.memory_mobile/browse:news:reddit', 'system_health.memory_mobile/browse:social:tumblr_infinite_scroll', 'system_health.memory_mobile/browse:tools:maps', 'system_health.memory_mobile/browse:news:cnn', 'system_health.memory_mobile/load:media:facebook_photos', 'system_health.memory_mobile/load:news:cnn', + 'system_health.memory_mobile/load:news:washingtonpost', 'system_health.memory_mobile/load:tools:stackoverflow', 'system_health.memory_desktop/load_accessibility:shopping:amazon', 'system_health.memory_desktop/browse_accessibility:tech:codesearch',
diff --git a/tools/perf/core/results_processor/histograms_output.py b/tools/perf/core/results_processor/histograms_output.py new file mode 100644 index 0000000..144537d --- /dev/null +++ b/tools/perf/core/results_processor/histograms_output.py
@@ -0,0 +1,68 @@ +# Copyright 2019 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Output formatter for HistogramSet Results Format. + +Format specification: +https://github.com/catapult-project/catapult/blob/master/docs/histogram-set-json-format.md +""" + +import json +import logging +import os + +from tracing.value.diagnostics import generic_set +from tracing.value.diagnostics import reserved_infos +from tracing.value import histogram_set + + +# This file is written by telemetry, it contains output of metric computation. +# This is a temporary hack to keep things working while we gradually move +# code from Telemetry to Results Processor. +HISTOGRAM_DICTS_NAME = 'histogram_dicts.json' + +# Output file in HistogramSet format. +OUTPUT_FILENAME = 'histograms.json' + + +def Process(intermediate_results, options): + """Process intermediate results and write output in output_dir.""" + histogram_dicts = Convert(intermediate_results, options.results_label) + + output_file = os.path.join(options.output_dir, OUTPUT_FILENAME) + if not options.reset_results and os.path.isfile(output_file): + with open(output_file) as input_stream: + try: + histogram_dicts += json.load(input_stream) + except ValueError: + logging.warning( + 'Found existing histograms json but failed to parse it.') + + with open(output_file, 'w') as output_stream: + json.dump(histogram_dicts, output_stream) + + +def Convert(intermediate_results, results_label): + """Convert intermediate results to histogram dicts""" + histograms = histogram_set.HistogramSet() + for result in intermediate_results['testResults']: + if HISTOGRAM_DICTS_NAME in result['artifacts']: + with open(result['artifacts'][HISTOGRAM_DICTS_NAME]['filePath']) as f: + histogram_dicts = json.load(f) + histograms.ImportDicts(histogram_dicts) + + diagnostics = intermediate_results['benchmarkRun'].get('diagnostics', {}) + for name, diag in diagnostics.items(): + # For now, we only support GenericSet diagnostics that are serialized + # as lists of values. + assert isinstance(diag, list) + histograms.AddSharedDiagnosticToAllHistograms( + name, generic_set.GenericSet(diag)) + + if results_label is not None: + histograms.AddSharedDiagnosticToAllHistograms( + reserved_infos.LABELS.name, + generic_set.GenericSet([results_label])) + + return histograms.AsDicts()
diff --git a/tools/perf/core/results_processor/histograms_output_unittest.py b/tools/perf/core/results_processor/histograms_output_unittest.py new file mode 100644 index 0000000..b3ea74d --- /dev/null +++ b/tools/perf/core/results_processor/histograms_output_unittest.py
@@ -0,0 +1,114 @@ +# Copyright 2019 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import unittest + +import json +import os +import shutil +import tempfile + +from core.results_processor import histograms_output +from core.results_processor import command_line +from core.results_processor import testing + +from tracing.value import histogram +from tracing.value import histogram_set + + +class HistogramsOutputTest(unittest.TestCase): + def setUp(self): + self.output_dir = tempfile.mkdtemp() + parser = command_line.ArgumentParser() + self.options = parser.parse_args([]) + self.options.output_dir = self.output_dir + command_line.ProcessOptions(self.options) + + def tearDown(self): + shutil.rmtree(self.output_dir) + + def testConvertOneStory(self): + hist_file = os.path.join(self.output_dir, + histograms_output.HISTOGRAM_DICTS_NAME) + with open(hist_file, 'w') as f: + json.dump([histogram.Histogram('a', 'unitless').AsDict()], f) + + in_results = testing.IntermediateResults( + test_results=[ + testing.TestResult( + 'benchmark/story', + artifacts={'histogram_dicts.json': testing.Artifact(hist_file)}, + ), + ], + ) + + histogram_dicts = histograms_output.Convert(in_results, results_label=None) + out_histograms = histogram_set.HistogramSet() + out_histograms.ImportDicts(histogram_dicts) + self.assertEqual(len(out_histograms), 1) + self.assertEqual(out_histograms.GetFirstHistogram().name, 'a') + self.assertEqual(out_histograms.GetFirstHistogram().unit, 'unitless') + + def testConvertDiagnostics(self): + hist_file = os.path.join(self.output_dir, + histograms_output.HISTOGRAM_DICTS_NAME) + with open(hist_file, 'w') as f: + json.dump([histogram.Histogram('a', 'unitless').AsDict()], f) + + in_results = testing.IntermediateResults( + test_results=[], + diagnostics={ + 'benchmarks': ['benchmark'], + 'osNames': ['linux'], + 'documentationUrls': [['documentation', 'url']], + }, + ) + + histogram_dicts = histograms_output.Convert(in_results, + results_label='label') + out_histograms = histogram_set.HistogramSet() + out_histograms.ImportDicts(histogram_dicts) + diag_values = [list(v) for v in out_histograms.shared_diagnostics] + self.assertEqual(len(diag_values), 4) + self.assertIn(['benchmark'], diag_values) + self.assertIn(['linux'], diag_values) + self.assertIn([['documentation', 'url']], diag_values) + self.assertIn(['label'], diag_values) + + def testConvertTwoStories(self): + hist_file = os.path.join(self.output_dir, + histograms_output.HISTOGRAM_DICTS_NAME) + with open(hist_file, 'w') as f: + json.dump([histogram.Histogram('a', 'unitless').AsDict()], f) + + in_results = testing.IntermediateResults( + test_results=[ + testing.TestResult( + 'benchmark/story1', + artifacts={'histogram_dicts.json': testing.Artifact(hist_file)}, + ), + testing.TestResult( + 'benchmark/story2', + artifacts={'histogram_dicts.json': testing.Artifact(hist_file)}, + ), + testing.TestResult( + 'benchmark/story1', + artifacts={'histogram_dicts.json': testing.Artifact(hist_file)}, + ), + testing.TestResult( + 'benchmark/story2', + artifacts={'histogram_dicts.json': testing.Artifact(hist_file)}, + ), + ], + ) + + histogram_dicts = histograms_output.Convert(in_results, + results_label='label') + out_histograms = histogram_set.HistogramSet() + out_histograms.ImportDicts(histogram_dicts) + self.assertEqual(len(out_histograms), 4) + hist = out_histograms.GetFirstHistogram() + self.assertEqual(hist.name, 'a') + self.assertEqual(hist.unit, 'unitless') + self.assertEqual(list(hist.diagnostics['labels']), ['label'])
diff --git a/tools/perf/core/results_processor/json3_output.py b/tools/perf/core/results_processor/json3_output.py index 82cdf28..1585156 100644 --- a/tools/perf/core/results_processor/json3_output.py +++ b/tools/perf/core/results_processor/json3_output.py
@@ -19,10 +19,10 @@ OUTPUT_FILENAME = 'test-results.json' -def Process(intermediate_results, output_dir): +def Process(intermediate_results, options): """Process intermediate results and write output in output_dir.""" - results = Convert(intermediate_results, output_dir) - with open(os.path.join(output_dir, OUTPUT_FILENAME), 'w') as f: + results = Convert(intermediate_results, options.output_dir) + with open(os.path.join(options.output_dir, OUTPUT_FILENAME), 'w') as f: json.dump(results, f, sort_keys=True, indent=4, separators=(',', ': '))
diff --git a/tools/perf/core/results_processor/processor.py b/tools/perf/core/results_processor/processor.py index ad13da4..fb60ca2 100644 --- a/tools/perf/core/results_processor/processor.py +++ b/tools/perf/core/results_processor/processor.py
@@ -13,12 +13,14 @@ from core.results_processor import command_line from core.results_processor import json3_output +from core.results_processor import histograms_output HTML_TRACE_NAME = 'trace.html' TELEMETRY_RESULTS = '_telemetry_results.jsonl' FORMATTERS = { 'json-test-results': json3_output, + 'histograms': histograms_output, } @@ -48,7 +50,7 @@ raise NotImplementedError(output_format) formatter = FORMATTERS[output_format] - formatter.Process(intermediate_results, options.output_dir) + formatter.Process(intermediate_results, options) def _LoadIntermediateResults(intermediate_file):
diff --git a/tools/perf/core/results_processor/processor_test.py b/tools/perf/core/results_processor/processor_test.py index de0bcf0..29d70af 100644 --- a/tools/perf/core/results_processor/processor_test.py +++ b/tools/perf/core/results_processor/processor_test.py
@@ -15,10 +15,16 @@ import tempfile import unittest +import mock + from core.results_processor import json3_output +from core.results_processor import histograms_output from core.results_processor import processor from core.results_processor import testing +from tracing.value import histogram +from tracing.value import histogram_set + class ResultsProcessorIntegrationTests(unittest.TestCase): def setUp(self): @@ -96,3 +102,141 @@ self.assertEqual(len(artifacts), 2) self.assertEqual(artifacts['logs'], ['gs://logs.txt']) self.assertEqual(artifacts['trace.html'], ['gs://trace.html']) + + # TODO(crbug.com/981349): Remove this mock when histograms format + # is enabled in results_processor. + @mock.patch('core.results_processor.command_line.SUPPORTED_FORMATS', + ['histograms']) + def testHistogramsOutput(self): + hist_file = os.path.join(self.output_dir, + histograms_output.HISTOGRAM_DICTS_NAME) + with open(hist_file, 'w') as f: + json.dump([histogram.Histogram('a', 'unitless').AsDict()], f) + + self.SerializeIntermediateResults( + test_results=[ + testing.TestResult( + 'benchmark/story', + artifacts={'histogram_dicts.json': testing.Artifact(hist_file)}, + ), + ], + diagnostics={ + 'benchmarks': ['benchmark'], + 'osNames': ['linux'], + 'documentationUrls': [['documentation', 'url']], + }, + start_time='2009-02-13T23:31:30.987000Z', + ) + + processor.main([ + '--output-format', 'histograms', + '--output-dir', self.output_dir, + '--intermediate-dir', self.intermediate_dir, + '--results-label', 'label', + ]) + + with open(os.path.join( + self.output_dir, histograms_output.OUTPUT_FILENAME)) as f: + results = json.load(f) + + out_histograms = histogram_set.HistogramSet() + out_histograms.ImportDicts(results) + self.assertEqual(len(out_histograms), 1) + self.assertEqual(out_histograms.GetFirstHistogram().name, 'a') + self.assertEqual(out_histograms.GetFirstHistogram().unit, 'unitless') + + diag_values = [list(v) for v in out_histograms.shared_diagnostics] + self.assertEqual(len(diag_values), 4) + self.assertIn(['benchmark'], diag_values) + self.assertIn(['linux'], diag_values) + self.assertIn([['documentation', 'url']], diag_values) + self.assertIn(['label'], diag_values) + + # TODO(crbug.com/981349): Remove this mock when histograms format + # is enabled in results_processor. + @mock.patch('core.results_processor.command_line.SUPPORTED_FORMATS', + ['histograms']) + def testHistogramsOutputResetResults(self): + hist_file = os.path.join(self.output_dir, + histograms_output.HISTOGRAM_DICTS_NAME) + with open(hist_file, 'w') as f: + json.dump([histogram.Histogram('a', 'unitless').AsDict()], f) + + self.SerializeIntermediateResults( + test_results=[ + testing.TestResult( + 'benchmark/story', + artifacts={'histogram_dicts.json': testing.Artifact(hist_file)}, + ), + ], + ) + + processor.main([ + '--output-format', 'histograms', + '--output-dir', self.output_dir, + '--intermediate-dir', self.intermediate_dir, + '--results-label', 'label1', + ]) + + processor.main([ + '--output-format', 'histograms', + '--output-dir', self.output_dir, + '--intermediate-dir', self.intermediate_dir, + '--results-label', 'label2', + '--reset-results', + ]) + + with open(os.path.join( + self.output_dir, histograms_output.OUTPUT_FILENAME)) as f: + results = json.load(f) + + out_histograms = histogram_set.HistogramSet() + out_histograms.ImportDicts(results) + self.assertEqual(len(out_histograms), 1) + diag_values = [list(v) for v in out_histograms.shared_diagnostics] + self.assertNotIn(['label1'], diag_values) + self.assertIn(['label2'], diag_values) + + # TODO(crbug.com/981349): Remove this mock when histograms format + # is enabled in results_processor. + @mock.patch('core.results_processor.command_line.SUPPORTED_FORMATS', + ['histograms']) + def testHistogramsOutputAppendResults(self): + hist_file = os.path.join(self.output_dir, + histograms_output.HISTOGRAM_DICTS_NAME) + with open(hist_file, 'w') as f: + json.dump([histogram.Histogram('a', 'unitless').AsDict()], f) + + self.SerializeIntermediateResults( + test_results=[ + testing.TestResult( + 'benchmark/story', + artifacts={'histogram_dicts.json': testing.Artifact(hist_file)}, + ), + ], + ) + + processor.main([ + '--output-format', 'histograms', + '--output-dir', self.output_dir, + '--intermediate-dir', self.intermediate_dir, + '--results-label', 'label1', + ]) + + processor.main([ + '--output-format', 'histograms', + '--output-dir', self.output_dir, + '--intermediate-dir', self.intermediate_dir, + '--results-label', 'label2', + ]) + + with open(os.path.join( + self.output_dir, histograms_output.OUTPUT_FILENAME)) as f: + results = json.load(f) + + out_histograms = histogram_set.HistogramSet() + out_histograms.ImportDicts(results) + self.assertEqual(len(out_histograms), 2) + diag_values = [list(v) for v in out_histograms.shared_diagnostics] + self.assertIn(['label1'], diag_values) + self.assertIn(['label2'], diag_values)
diff --git a/tools/perf/core/results_processor/testing.py b/tools/perf/core/results_processor/testing.py index 275d5cf..21adc520 100644 --- a/tools/perf/core/results_processor/testing.py +++ b/tools/perf/core/results_processor/testing.py
@@ -11,7 +11,7 @@ def IntermediateResults(test_results, start_time='2015-10-21T07:28:00.000Z', - finalized=True, interrupted=False): + finalized=True, interrupted=False, diagnostics=None): """Build a dict of 'parsed' intermediate results. Args: @@ -28,6 +28,7 @@ 'startTime': start_time, 'finalized': finalized, 'interrupted': interrupted, + 'diagnostics': diagnostics or {}, }, 'testResults': list(test_results) }
diff --git a/tools/perf/page_sets/data/system_health_desktop.json b/tools/perf/page_sets/data/system_health_desktop.json index 88fc0a77..64aee06 100644 --- a/tools/perf/page_sets/data/system_health_desktop.json +++ b/tools/perf/page_sets/data/system_health_desktop.json
@@ -113,6 +113,9 @@ }, "browse:tools:maps:2019": { "DEFAULT": "system_health_desktop_feb332ef0c.wprgo" + }, + "browse:tools:sheets:2019": { + "DEFAULT": "system_health_desktop_d7b02362d8.wprgo" }, "browse_accessibility:media:youtube": { "DEFAULT": "system_health_desktop_062.wprgo" @@ -369,4 +372,4 @@ }, "description": "Describes the Web Page Replay archives for a story set. Don't edit by hand! Use record_wpr for updating.", "platform_specific": true -} \ No newline at end of file +}
diff --git a/tools/perf/page_sets/data/system_health_desktop_d7b02362d8.wprgo.sha1 b/tools/perf/page_sets/data/system_health_desktop_d7b02362d8.wprgo.sha1 new file mode 100644 index 0000000..ff4301e --- /dev/null +++ b/tools/perf/page_sets/data/system_health_desktop_d7b02362d8.wprgo.sha1
@@ -0,0 +1 @@ +d7b02362d877b62af94558abea7f3767d2fcd55a \ No newline at end of file
diff --git a/tools/perf/page_sets/data/system_health_mobile.json b/tools/perf/page_sets/data/system_health_mobile.json index 6c471ac6..95cecac9 100644 --- a/tools/perf/page_sets/data/system_health_mobile.json +++ b/tools/perf/page_sets/data/system_health_mobile.json
@@ -63,6 +63,9 @@ "browse:news:reddit": { "DEFAULT": "system_health_mobile_027.wprgo" }, + "browse:news:reddit:2019": { + "DEFAULT": "system_health_mobile_1a5563286a.wprgo" + }, "browse:news:toi": { "DEFAULT": "system_health_mobile_064.wprgo" }, @@ -99,6 +102,9 @@ "browse:social:instagram": { "DEFAULT": "system_health_mobile_060.wprgo" }, + "browse:social:instagram:2019": { + "DEFAULT": "system_health_mobile_c38cfb84fc.wprgo" + }, "browse:social:pinterest_infinite_scroll": { "DEFAULT": "system_health_mobile_063.wprgo" }, @@ -210,6 +216,9 @@ "load:news:washingtonpost": { "DEFAULT": "system_health_mobile_013.wprgo" }, + "load:news:washingtonpost:2019": { + "DEFAULT": "system_health_mobile_f2584469fe.wprgo" + }, "load:news:wikipedia": { "DEFAULT": "system_health_mobile_002.wprgo" },
diff --git a/tools/perf/page_sets/data/system_health_mobile_1a5563286a.wprgo.sha1 b/tools/perf/page_sets/data/system_health_mobile_1a5563286a.wprgo.sha1 new file mode 100644 index 0000000..9a4c651 --- /dev/null +++ b/tools/perf/page_sets/data/system_health_mobile_1a5563286a.wprgo.sha1
@@ -0,0 +1 @@ +1a5563286a468da721755207026403338f629d23 \ No newline at end of file
diff --git a/tools/perf/page_sets/data/system_health_mobile_c38cfb84fc.wprgo.sha1 b/tools/perf/page_sets/data/system_health_mobile_c38cfb84fc.wprgo.sha1 new file mode 100644 index 0000000..f4fa097 --- /dev/null +++ b/tools/perf/page_sets/data/system_health_mobile_c38cfb84fc.wprgo.sha1
@@ -0,0 +1 @@ +c38cfb84fcfa54c0540d69f2e4d7f19b46d04ff0 \ No newline at end of file
diff --git a/tools/perf/page_sets/data/system_health_mobile_f2584469fe.wprgo.sha1 b/tools/perf/page_sets/data/system_health_mobile_f2584469fe.wprgo.sha1 new file mode 100644 index 0000000..c21563a6 --- /dev/null +++ b/tools/perf/page_sets/data/system_health_mobile_f2584469fe.wprgo.sha1
@@ -0,0 +1 @@ +f2584469fe9e114e903bfe67317920fe692a204a \ No newline at end of file
diff --git a/tools/perf/page_sets/system_health/browsing_stories.py b/tools/perf/page_sets/system_health/browsing_stories.py index 4657dd4..c44d81a 100644 --- a/tools/perf/page_sets/system_health/browsing_stories.py +++ b/tools/perf/page_sets/system_health/browsing_stories.py
@@ -161,6 +161,22 @@ action_runner.NavigateBack() +class InstagramMobileStory2019(_ArticleBrowsingStory): + NAME = 'browse:social:instagram:2019' + URL = 'https://www.instagram.com/badgalriri/' + ITEM_SELECTOR = '[class="v1Nh3 kIKUG _bz0w"] a' + ITEMS_TO_VISIT = 8 + + SUPPORTED_PLATFORMS = platforms.MOBILE_ONLY + TAGS = [story_tags.EMERGING_MARKET, story_tags.YEAR_2019] + + def _WaitForNavigation(self, action_runner): + action_runner.WaitForElement(selector='[title="badgalriri"]') + + def _NavigateBack(self, action_runner): + action_runner.NavigateBack() + + class FlipboardDesktopStory2018(_ArticleBrowsingStory): NAME = 'browse:news:flipboard:2018' URL = 'https://flipboard.com/explore' @@ -222,6 +238,30 @@ SUPPORTED_PLATFORMS = platforms.MOBILE_ONLY TAGS = [story_tags.YEAR_2016] +class RedditMobileStory2019(_ArticleBrowsingStory): + NAME = 'browse:news:reddit:2019' + URL = 'https://www.reddit.com/r/news/top/?sort=top&t=week' + IS_SINGLE_PAGE_APP = True + ITEM_SELECTOR = '.PostHeader__post-title-line' + SUPPORTED_PLATFORMS = platforms.MOBILE_ONLY + TAGS = [story_tags.YEAR_2019] + + def _DidLoadDocument(self, action_runner): + # We encountered ads disguised as articles on the Reddit one so far. The + # following code skips that ad. + # If we encounter it more often it will make sense to have a more generic + # approach, e.g an OFFSET to start iterating from, or an index to skip. + + # Add one to the items to visit since we are going to skip the ad and we + # want to still visit the same amount of articles. + for i in xrange(self.ITEMS_TO_VISIT + 1): + # Skip the ad disguised as an article. + if i == 1: + continue + self._NavigateToItem(action_runner, i) + self._ReadNextArticle(action_runner) + self._NavigateBack(action_runner) + self._ScrollMainPage(action_runner) class TwitterMobileStory(_ArticleBrowsingStory): NAME = 'browse:social:twitter' @@ -1270,6 +1310,116 @@ ############################################################################## +# Google sheets browsing story. +############################################################################## + + +class GoogleSheetsDesktopStory(system_health_story.SystemHealthStory): + NAME = 'browse:tools:sheets:2019' + URL = ('https://docs.google.com/spreadsheets/d/' + + '16jfsJs14QrWKhsbxpdJXgoYumxNpnDt08DTK82Puc2A/' + + 'edit#gid=896027318&range=C:C') + SUPPORTED_PLATFORMS = platforms.DESKTOP_ONLY + TAGS = [story_tags.JAVASCRIPT_HEAVY, story_tags.YEAR_2019] + + # This map translates page-specific event names to event names needed for + # the reported_by_page:* metric. + EVENTS_REPORTED_BY_PAGE = ''' + window.__telemetry_reported_page_events = { + 'ccv': + 'telemetry:reported_by_page:viewable', + 'fcoe': + 'telemetry:reported_by_page:interactive', + 'first_meaningful_calc_begin': + 'telemetry:reported_by_page:benchmark_begin', + 'first_meaningful_calc_end': + 'telemetry:reported_by_page:benchmark_end' + }; + ''' + + # Patch performance.mark to get notified about page events. + PERFOMANCE_MARK = ''' + window.__telemetry_observed_page_events = new Set(); + (function () { + let reported = window.__telemetry_reported_page_events; + let observed = window.__telemetry_observed_page_events; + let performance_mark = window.performance.mark; + window.performance.mark = function (label) { + performance_mark.call(window.performance, label); + if (reported.hasOwnProperty(label)) { + performance_mark.call( + window.performance, reported[label]); + observed.add(reported[label]); + } + } + })(); + ''' + + # Page event queries. + INTERACTIVE_EVENT = ''' + (window.__telemetry_observed_page_events.has( + "telemetry:reported_by_page:interactive")) + ''' + CALC_BEGIN_EVENT = ''' + (window.__telemetry_observed_page_events.has( + "telemetry:reported_by_page:benchmark_begin")) + ''' + CALC_END_EVENT = ''' + (window.__telemetry_observed_page_events.has( + "telemetry:reported_by_page:benchmark_end")) + ''' + CLEAR_EVENTS = 'window.__telemetry_observed_page_events.clear()' + + # Start recalculation of the current column by invoking + # trixApp.module$contents$waffle$DesktopRitzApp_DesktopRitzApp$actionRegistry_ + # .f_actions__com_google_apps_docs_xplat_controller_ActionRegistryImpl_ + # ['trix-fill-right'].fireAction() + RECALCULATE_COLUMN = "trixApp.Cb.D['trix-fill-right'].Eb();" + + # Patch the goog$Uri.prototype.setParameterValue to fix the + # session parameters that depend on Math.random and Date.now. + DETERMINISITIC_SESSION = ''' + if (window.xk) { + window.xk.prototype.wc = function (a, b) { + if (a === "rand") { b = "1566829321650"; } + if (a === "zx") { b = "9azccr4i1bz5"; } + if (a === "ssfi") { b = "0"; } + this.C.set(a, b); + return this; + } + } + ''' + + def __init__(self, story_set, take_memory_measurement): + super(GoogleSheetsDesktopStory, self).__init__(story_set, + take_memory_measurement) + self.script_to_evaluate_on_commit = js_template.Render( + '''{{@events_reported_by_page}} + {{@performance_mark}} + document.addEventListener('readystatechange', event => { + if (event.target.readyState === 'interactive') { + {{@deterministic_session}} + } + });''', + events_reported_by_page=self.EVENTS_REPORTED_BY_PAGE, + performance_mark=self.PERFOMANCE_MARK, + deterministic_session=self.DETERMINISITIC_SESSION) + + def _DidLoadDocument(self, action_runner): + # 1. Wait until the spreadsheet loads. + action_runner.WaitForJavaScriptCondition(self.INTERACTIVE_EVENT) + # 2. Idle for 5 seconds for Chrome's timeToInteractive metric. + action_runner.Wait(5) + # 3. Prepare for observing calcuation events. + action_runner.EvaluateJavaScript(self.CLEAR_EVENTS) + # 4. Recalculate the column. + action_runner.EvaluateJavaScript(self.RECALCULATE_COLUMN) + # 5. Wait for calculation completion. + action_runner.WaitForJavaScriptCondition(self.CALC_BEGIN_EVENT) + action_runner.WaitForJavaScriptCondition(self.CALC_END_EVENT) + + +############################################################################## # Browsing stories with infinite scrolling ##############################################################################
diff --git a/tools/perf/page_sets/system_health/loading_stories.py b/tools/perf/page_sets/system_health/loading_stories.py index a4a2e2b..fa0e8f7 100644 --- a/tools/perf/page_sets/system_health/loading_stories.py +++ b/tools/perf/page_sets/system_health/loading_stories.py
@@ -9,6 +9,8 @@ from page_sets.login_helpers import dropbox_login from page_sets.login_helpers import google_login +from telemetry.util import js_template + class _LoadingStory(system_health_story.SystemHealthStory): """Abstract base class for single-page System Health user stories.""" @@ -241,6 +243,33 @@ if has_button: action_runner.ClickElement(selector=self._CLOSE_BUTTON_SELECTOR) +class LoadWashingtonPostMobileStory2019(_LoadingStory): + NAME = 'load:news:washingtonpost:2019' + URL = 'https://www.washingtonpost.com/pwa' + SUPPORTED_PLATFORMS = platforms.MOBILE_ONLY + TAGS = [story_tags.HEALTH_CHECK, story_tags.YEAR_2019] + _CONTINUE_FREE_BUTTON_SELECTOR = '.continue-btn.button.free' + _ACCEPT_GDPR_SELECTOR = '.agree-ckb' + _CONTINUE_TO_SITE_SELECTOR = '.continue-btn.button.accept-consent' + + def _DidLoadDocument(self, action_runner): + # Close the popup window. On Nexus 9 (and probably other tables) the popup + # window does not have a "Close" button, instead it has only a "Send link + # to phone" button. So on tablets we run with the popup window open. The + # popup is transparent, so this is mostly an aesthetical issue. + has_button = action_runner.EvaluateJavaScript( + '!!document.querySelector({{ selector }})', + selector=self._CONTINUE_FREE_BUTTON_SELECTOR) + if has_button: + action_runner.ClickElement(selector=self._CONTINUE_FREE_BUTTON_SELECTOR) + action_runner.ScrollPageToElement(selector=self._ACCEPT_GDPR_SELECTOR) + action_runner.ClickElement(selector=self._ACCEPT_GDPR_SELECTOR) + element_function = js_template.Render( + 'document.querySelectorAll({{ selector }})[{{ index }}]', + selector=self._CONTINUE_TO_SITE_SELECTOR, index=0) + action_runner.ClickElement(element_function=element_function) + + class LoadWikipediaStory2018(_LoadingStory): NAME = 'load:news:wikipedia:2018'
diff --git a/ui/accessibility/ax_range.h b/ui/accessibility/ax_range.h index 612516d1..f84ff61 100644 --- a/ui/accessibility/ax_range.h +++ b/ui/accessibility/ax_range.h
@@ -50,7 +50,7 @@ focus_.swap(other.focus_); } - virtual ~AXRange() {} + virtual ~AXRange() = default; AXPositionType* anchor() const { DCHECK(anchor_); @@ -62,15 +62,10 @@ return focus_.get(); } - bool IsNull() const { - DCHECK(anchor_ && focus_); - return anchor_->IsNullPosition() || focus_->IsNullPosition(); - } - AXRange& operator=(const AXRange& other) = delete; - AXRange& operator=(const AXRange&& other) { - if (this != other) { + AXRange& operator=(AXRange&& other) { + if (this != &other) { anchor_ = AXPositionType::CreateNullPosition(); focus_ = AXPositionType::CreateNullPosition(); anchor_.swap(other.anchor_); @@ -88,7 +83,7 @@ bool operator!=(const AXRange& other) const { return !(*this == other); } - AXRange GetForwardRange() const { + AXRange AsForwardRange() const { // When we have a range with an empty text representation, its endpoints // would be considered equal as text positions, but they could be located in // different anchors of the AXTree. Compare them as tree positions first to @@ -102,6 +97,8 @@ : AXRange(anchor_->Clone(), focus_->Clone()); } + bool IsCollapsed() const { return !IsNull() && *anchor_ == *focus_; } + // We define a "leaf text range" as an AXRange whose endpoints are leaf text // positions located within the same anchor of the AXTree. bool IsLeafTextRange() const { @@ -109,6 +106,11 @@ anchor_->IsLeafTextPosition() && focus_->IsLeafTextPosition(); } + bool IsNull() const { + DCHECK(anchor_ && focus_); + return anchor_->IsNullPosition() || focus_->IsNullPosition(); + } + // We can decompose any given AXRange into multiple "leaf text ranges". // As an example, consider the following HTML code: // @@ -208,13 +210,13 @@ }; Iterator begin() const { - AXRange forward_range = GetForwardRange(); + AXRange forward_range = AsForwardRange(); return Iterator(std::move(forward_range.anchor_), std::move(forward_range.focus_)); } Iterator end() const { - AXRange forward_range = GetForwardRange(); + AXRange forward_range = AsForwardRange(); return Iterator(nullptr, std::move(forward_range.focus_)); }
diff --git a/ui/accessibility/ax_range_unittest.cc b/ui/accessibility/ax_range_unittest.cc index 2145f4b..2df467ce 100644 --- a/ui/accessibility/ax_range_unittest.cc +++ b/ui/accessibility/ax_range_unittest.cc
@@ -377,6 +377,100 @@ EXPECT_EQ(test_positions_1_and_2, test_positions_1_and_3); } +TEST_F(AXRangeTest, AsForwardRange) { + TestPositionRange null_range(AXNodePosition::CreateNullPosition(), + AXNodePosition::CreateNullPosition()); + null_range = null_range.AsForwardRange(); + EXPECT_TRUE(null_range.IsNull()); + + TestPositionInstance tree_position = AXNodePosition::CreateTreePosition( + tree_->data().tree_id, button_.id, 0 /* child_index */); + TestPositionInstance text_position1 = AXNodePosition::CreateTextPosition( + tree_->data().tree_id, line_break1_.id, 1 /* text_offset */, + ax::mojom::TextAffinity::kDownstream); + TestPositionInstance text_position2 = AXNodePosition::CreateTextPosition( + tree_->data().tree_id, inline_box2_.id, 0 /* text_offset */, + ax::mojom::TextAffinity::kDownstream); + + TestPositionRange tree_to_text_range(text_position1->Clone(), + tree_position->Clone()); + tree_to_text_range = tree_to_text_range.AsForwardRange(); + EXPECT_EQ(*tree_position, *tree_to_text_range.anchor()); + EXPECT_EQ(*text_position1, *tree_to_text_range.focus()); + + TestPositionRange text_to_text_range(text_position2->Clone(), + text_position1->Clone()); + text_to_text_range = text_to_text_range.AsForwardRange(); + EXPECT_EQ(*text_position1, *text_to_text_range.anchor()); + EXPECT_EQ(*text_position2, *text_to_text_range.focus()); +} + +TEST_F(AXRangeTest, IsCollapsed) { + TestPositionRange null_range(AXNodePosition::CreateNullPosition(), + AXNodePosition::CreateNullPosition()); + null_range = null_range.AsForwardRange(); + EXPECT_FALSE(null_range.IsCollapsed()); + + TestPositionInstance tree_position1 = AXNodePosition::CreateTreePosition( + tree_->data().tree_id, text_field_.id, 0 /* child_index */); + // Since there are no children in inline_box1_, the following is essentially + // an "after text" position which should not compare as equivalent to the + // above tree position which is a "before text" position inside the text + // field. + TestPositionInstance tree_position2 = AXNodePosition::CreateTreePosition( + tree_->data().tree_id, inline_box1_.id, 0 /* child_index */); + + TestPositionInstance text_position1 = AXNodePosition::CreateTextPosition( + tree_->data().tree_id, static_text1_.id, 0 /* text_offset */, + ax::mojom::TextAffinity::kDownstream); + TestPositionInstance text_position2 = AXNodePosition::CreateTextPosition( + tree_->data().tree_id, inline_box1_.id, 0 /* text_offset */, + ax::mojom::TextAffinity::kDownstream); + TestPositionInstance text_position3 = AXNodePosition::CreateTextPosition( + tree_->data().tree_id, inline_box2_.id, 1 /* text_offset */, + ax::mojom::TextAffinity::kDownstream); + + TestPositionRange tree_to_null_range(tree_position1->Clone(), + AXNodePosition::CreateNullPosition()); + EXPECT_TRUE(tree_to_null_range.IsNull()); + EXPECT_FALSE(tree_to_null_range.IsCollapsed()); + + TestPositionRange null_to_text_range(AXNodePosition::CreateNullPosition(), + text_position1->Clone()); + EXPECT_TRUE(null_to_text_range.IsNull()); + EXPECT_FALSE(null_to_text_range.IsCollapsed()); + + TestPositionRange tree_to_tree_range(tree_position2->Clone(), + tree_position1->Clone()); + EXPECT_TRUE(tree_to_tree_range.IsCollapsed()); + + // A tree and a text position that essentially point to the same text offset + // are equivalent, even if they are anchored to a different node. + TestPositionRange tree_to_text_range(tree_position1->Clone(), + text_position1->Clone()); + EXPECT_TRUE(tree_to_text_range.IsCollapsed()); + + // The following positions are not equivalent since tree_position2 is an + // "after text" position. + tree_to_text_range = + TestPositionRange(tree_position2->Clone(), text_position2->Clone()); + EXPECT_FALSE(tree_to_text_range.IsCollapsed()); + + TestPositionRange text_to_text_range(text_position1->Clone(), + text_position1->Clone()); + EXPECT_TRUE(text_to_text_range.IsCollapsed()); + + // Two text positions that essentially point to the same text offset are + // equivalent, even if they are anchored to a different node. + text_to_text_range = + TestPositionRange(text_position1->Clone(), text_position2->Clone()); + EXPECT_TRUE(text_to_text_range.IsCollapsed()); + + text_to_text_range = + TestPositionRange(text_position1->Clone(), text_position3->Clone()); + EXPECT_FALSE(text_to_text_range.IsCollapsed()); +} + TEST_F(AXRangeTest, BeginAndEndIterators) { TestPositionInstance null_position = AXNodePosition::CreateNullPosition(); TestPositionInstance test_position1 = AXNodePosition::CreateTextPosition(
diff --git a/ui/accessibility/ax_tree_unittest.cc b/ui/accessibility/ax_tree_unittest.cc index 644722b..1244a46 100644 --- a/ui/accessibility/ax_tree_unittest.cc +++ b/ui/accessibility/ax_tree_unittest.cc
@@ -674,9 +674,9 @@ AXTree tree(initial_state); // Index in parent correct. - EXPECT_EQ(tree.GetFromId(2)->GetUnignoredIndexInParent(), (size_t)0); - EXPECT_EQ(tree.GetFromId(3)->GetUnignoredIndexInParent(), (size_t)1); - EXPECT_EQ(tree.GetFromId(4)->GetUnignoredIndexInParent(), (size_t)2); + EXPECT_EQ(0U, tree.GetFromId(2)->GetUnignoredIndexInParent()); + EXPECT_EQ(1U, tree.GetFromId(3)->GetUnignoredIndexInParent()); + EXPECT_EQ(2U, tree.GetFromId(4)->GetUnignoredIndexInParent()); // Perform an update where we reorder children to [ 4 3 2 ] AXTreeUpdate update; @@ -694,9 +694,73 @@ ASSERT_TRUE(tree.Unserialize(update)); // Index in parent should have changed as well. - EXPECT_EQ((size_t)0, tree.GetFromId(4)->GetUnignoredIndexInParent()); - EXPECT_EQ((size_t)1, tree.GetFromId(3)->GetUnignoredIndexInParent()); - EXPECT_EQ((size_t)2, tree.GetFromId(2)->GetUnignoredIndexInParent()); + EXPECT_EQ(0U, tree.GetFromId(4)->GetUnignoredIndexInParent()); + EXPECT_EQ(1U, tree.GetFromId(3)->GetUnignoredIndexInParent()); + EXPECT_EQ(2U, tree.GetFromId(2)->GetUnignoredIndexInParent()); +} + +TEST(AXTreeTest, IndexInParentAfterReorderIgnoredNode) { + // This test covers another case where an AXTreeUpdate includes + // reordered children. If one of the reordered nodes is ignored, its + // children's unignored index in parent should also be updated. + + // Setup initial tree state. + // Tree: + // 1 + // 2 3i 4 + // 5 6 + AXTreeUpdate initial_state; + initial_state.root_id = 1; + initial_state.nodes.resize(6); + initial_state.nodes[0].id = 1; + initial_state.nodes[0].child_ids.resize(3); + initial_state.nodes[0].child_ids[0] = 2; + initial_state.nodes[0].child_ids[1] = 3; + initial_state.nodes[0].child_ids[2] = 4; + initial_state.nodes[1].id = 2; + initial_state.nodes[2].id = 3; + initial_state.nodes[2].AddState(ax::mojom::State::kIgnored); + initial_state.nodes[2].child_ids.resize(2); + initial_state.nodes[2].child_ids[0] = 5; + initial_state.nodes[2].child_ids[1] = 6; + initial_state.nodes[3].id = 4; + initial_state.nodes[4].id = 5; + initial_state.nodes[5].id = 6; + AXTree tree(initial_state); + + // Index in parent correct. + EXPECT_EQ(0U, tree.GetFromId(2)->GetUnignoredIndexInParent()); + EXPECT_EQ(1U, tree.GetFromId(5)->GetUnignoredIndexInParent()); + EXPECT_EQ(2U, tree.GetFromId(6)->GetUnignoredIndexInParent()); + EXPECT_EQ(3U, tree.GetFromId(4)->GetUnignoredIndexInParent()); + + // Perform an update where we reorder children to [ 3i 2 4 ]. The + // unignored index in parent for the children of the ignored node (3) should + // be updated. + AXTreeUpdate update; + update.root_id = 1; + update.nodes.resize(6); + update.nodes[0].id = 1; + update.nodes[0].child_ids.resize(3); + update.nodes[0].child_ids[0] = 3; + update.nodes[0].child_ids[1] = 2; + update.nodes[0].child_ids[2] = 4; + update.nodes[1].id = 2; + update.nodes[2].id = 3; + update.nodes[2].AddState(ax::mojom::State::kIgnored); + update.nodes[2].child_ids.resize(2); + update.nodes[2].child_ids[0] = 5; + update.nodes[2].child_ids[1] = 6; + update.nodes[3].id = 4; + update.nodes[4].id = 5; + update.nodes[5].id = 6; + + ASSERT_TRUE(tree.Unserialize(update)); + + EXPECT_EQ(2U, tree.GetFromId(2)->GetUnignoredIndexInParent()); + EXPECT_EQ(0U, tree.GetFromId(5)->GetUnignoredIndexInParent()); + EXPECT_EQ(1U, tree.GetFromId(6)->GetUnignoredIndexInParent()); + EXPECT_EQ(3U, tree.GetFromId(4)->GetUnignoredIndexInParent()); } TEST(AXTreeTest, ImplicitAttributeDelete) {
diff --git a/ui/gfx/canvas.cc b/ui/gfx/canvas.cc index b65334e..955bbba 100644 --- a/ui/gfx/canvas.cc +++ b/ui/gfx/canvas.cc
@@ -168,10 +168,6 @@ canvas_->clipPath(path, SkClipOp::kIntersect, do_anti_alias); } -bool Canvas::IsClipEmpty() const { - return canvas_->isClipEmpty(); -} - bool Canvas::GetClipBounds(Rect* bounds) { SkRect out; if (canvas_->getLocalClipBounds(&out)) {
diff --git a/ui/gfx/canvas.h b/ui/gfx/canvas.h index a5273e1..87504bf5 100644 --- a/ui/gfx/canvas.h +++ b/ui/gfx/canvas.h
@@ -190,9 +190,6 @@ // should be antialiased. void ClipPath(const SkPath& path, bool do_anti_alias); - // Returns true if the current clip is empty. - bool IsClipEmpty() const; - // Returns the bounds of the current clip (in local coordinates) in the // |bounds| parameter, and returns true if it is non empty. bool GetClipBounds(Rect* bounds);
diff --git a/ui/ozone/platform/drm/gpu/drm_thread.cc b/ui/ozone/platform/drm/gpu/drm_thread.cc index e941c850..43be05a 100644 --- a/ui/ozone/platform/drm/gpu/drm_thread.cc +++ b/ui/ozone/platform/drm/gpu/drm_thread.cc
@@ -48,7 +48,7 @@ GBM_BO_USE_TEXTURING; break; case gfx::BufferUsage::CAMERA_AND_CPU_READ_WRITE: - return GBM_BO_USE_LINEAR | GBM_BO_USE_CAMERA_WRITE | GBM_BO_USE_TEXTURING; + return GBM_BO_USE_LINEAR | GBM_BO_USE_CAMERA_WRITE; case gfx::BufferUsage::SCANOUT_CPU_READ_WRITE: return GBM_BO_USE_LINEAR | GBM_BO_USE_SCANOUT | GBM_BO_USE_TEXTURING; case gfx::BufferUsage::SCANOUT_VDA_WRITE:
diff --git a/ui/views/controls/button/label_button.cc b/ui/views/controls/button/label_button.cc index 8a5c31c..dd05976 100644 --- a/ui/views/controls/button/label_button.cc +++ b/ui/views/controls/button/label_button.cc
@@ -74,6 +74,16 @@ SetTextInternal(text); } +void LabelButton::ShrinkDownThenClearText() { + if (GetText().empty()) + return; + // First, we recalculate preferred size for the new mode (without the label). + shrinking_down_label_ = true; + PreferredSizeChanged(); + // Second, we clear the label right away if the button is already small. + ClearTextIfShrunkDown(); +} + void LabelButton::SetTextColor(ButtonState for_state, SkColor color) { button_state_colors_[for_state] = color; if (for_state == STATE_DISABLED) @@ -178,16 +188,26 @@ ResetCachedPreferredSize(); } +void LabelButton::OnBoundsChanged(const gfx::Rect& previous_bounds) { + ClearTextIfShrunkDown(); + Button::OnBoundsChanged(previous_bounds); +} + gfx::Size LabelButton::CalculatePreferredSize() const { // Cache the computed size, as recomputing it is an expensive operation. if (!cached_preferred_size_) { - const gfx::Size preferred_label_size = label_->GetPreferredSize(); gfx::Size size = GetUnclampedSizeWithoutLabel(); - size.Enlarge(preferred_label_size.width(), 0); - // Increase the height of the label (with insets) if larger. - size.set_height(std::max( - preferred_label_size.height() + GetInsets().height(), size.height())); + // Disregard label in the preferred size if the button is shrinking down to + // show no label soon. + if (!shrinking_down_label_) { + const gfx::Size preferred_label_size = label_->GetPreferredSize(); + size.Enlarge(preferred_label_size.width(), 0); + + // Increase the height of the label (with insets) if larger. + size.set_height(std::max( + preferred_label_size.height() + GetInsets().height(), size.height())); + } size.SetToMax(GetMinSize()); @@ -475,11 +495,30 @@ void LabelButton::SetTextInternal(const base::string16& text) { SetAccessibleName(text); label_->SetText(text); + + // Setting text cancels ShrinkDownThenClearText(). + if (shrinking_down_label_) { + shrinking_down_label_ = false; + PreferredSizeChanged(); + } + // TODO(pkasting): Remove this and forward callback subscriptions to the // underlying label property when Label is converted to properties. OnPropertyChanged(label_, kPropertyEffectsNone); } +void LabelButton::ClearTextIfShrunkDown() { + if (!cached_preferred_size_) + CalculatePreferredSize(); + if (shrinking_down_label_ && width() <= cached_preferred_size_->width() && + height() <= cached_preferred_size_->height()) { + // Once the button shrinks down to its preferred size (that disregards the + // current text), we finish the operation by clearing the text. + shrinking_down_label_ = false; + SetTextInternal(base::string16()); + } +} + void LabelButton::ResetCachedPreferredSize() { cached_preferred_size_ = base::nullopt; }
diff --git a/ui/views/controls/button/label_button.h b/ui/views/controls/button/label_button.h index 2162f9e..cac6b57 100644 --- a/ui/views/controls/button/label_button.h +++ b/ui/views/controls/button/label_button.h
@@ -48,6 +48,15 @@ base::string16 GetText() const; virtual void SetText(const base::string16& text); + // Makes the button report its preferred size without the label. This lets + // AnimatingLayoutManager gradually shrink the button until the text is + // invisible, at which point the text gets cleared. Think of this as + // transitioning from the current text to SetText(""). + // Note that the layout manager (or manual SetBounds calls) need to be + // configured to eventually hit the the button's preferred size (or smaller) + // or the text will never be cleared. + void ShrinkDownThenClearText(); + // Sets the text color shown for the specified button |for_state| to |color|. void SetTextColor(ButtonState for_state, SkColor color); @@ -88,6 +97,7 @@ // Button: void SetBorder(std::unique_ptr<Border> border) override; + void OnBoundsChanged(const gfx::Rect& previous_bounds) override; gfx::Size CalculatePreferredSize() const override; int GetHeightForWidth(int w) const override; void Layout() override; @@ -157,6 +167,8 @@ private: void SetTextInternal(const base::string16& text); + void ClearTextIfShrunkDown(); + // Resets |cached_preferred_size_|. void ResetCachedPreferredSize(); @@ -202,6 +214,11 @@ // Cache the last computed preferred size. mutable base::Optional<gfx::Size> cached_preferred_size_; + // A flag indicating that this button should not include the label in its + // desired size. Furthermore, once the bounds of the button adapt to this + // desired size, the text in the label should get cleared. + bool shrinking_down_label_ = false; + // Flag indicating default handling of the return key via an accelerator. // Whether or not the button appears or behaves as the default button in its // current context;
diff --git a/ui/views/controls/button/label_button_unittest.cc b/ui/views/controls/button/label_button_unittest.cc index 0e8d81e..a4c789c 100644 --- a/ui/views/controls/button/label_button_unittest.cc +++ b/ui/views/controls/button/label_button_unittest.cc
@@ -172,6 +172,92 @@ gfx::Size(long_text_width, font_list.GetHeight() * 2)); } +TEST_F(LabelButtonTest, LabelShrinkDown) { + ASSERT_TRUE(button_->GetText().empty()); + + const gfx::FontList font_list = button_->label()->font_list(); + const base::string16 text(ASCIIToUTF16("abcdefghijklm")); + const int text_width = gfx::GetStringWidth(text, font_list); + + ASSERT_LT(button_->GetPreferredSize().width(), text_width); + button_->SetText(text); + EXPECT_GT(button_->GetPreferredSize().width(), text_width); + button_->SetSize(button_->GetPreferredSize()); + + // When shrinking, the button should report again the size with no label + // (while keeping the label). + button_->ShrinkDownThenClearText(); + EXPECT_EQ(button_->GetText(), text); + EXPECT_LT(button_->GetPreferredSize().width(), text_width); + + // After the layout manager resizes the button to it's desired size, it's text + // should be empty again. + button_->SetSize(button_->GetPreferredSize()); + EXPECT_TRUE(button_->GetText().empty()); +} + +TEST_F(LabelButtonTest, LabelShrinksDownOnManualSetBounds) { + ASSERT_TRUE(button_->GetText().empty()); + ASSERT_GT(button_->GetPreferredSize().width(), 1); + + const base::string16 text(ASCIIToUTF16("abcdefghijklm")); + + button_->SetText(text); + EXPECT_EQ(button_->GetText(), text); + button_->SetSize(button_->GetPreferredSize()); + button_->SetBoundsRect(gfx::Rect(button_->GetPreferredSize())); + + button_->ShrinkDownThenClearText(); + + // Manually setting a smaller size should also clear text. + button_->SetBoundsRect(gfx::Rect(1, 1)); + EXPECT_TRUE(button_->GetText().empty()); +} + +TEST_F(LabelButtonTest, LabelShrinksDownCanceledBySettingText) { + ASSERT_TRUE(button_->GetText().empty()); + + const gfx::FontList font_list = button_->label()->font_list(); + const base::string16 text(ASCIIToUTF16("abcdefghijklm")); + const int text_width = gfx::GetStringWidth(text, font_list); + + ASSERT_LT(button_->GetPreferredSize().width(), text_width); + button_->SetText(text); + EXPECT_GT(button_->GetPreferredSize().width(), text_width); + button_->SetBoundsRect(gfx::Rect(button_->GetPreferredSize())); + + // When shrinking, the button should report again the size with no label + // (while keeping the label). + button_->ShrinkDownThenClearText(); + EXPECT_EQ(button_->GetText(), text); + gfx::Size shrinking_size = button_->GetPreferredSize(); + EXPECT_LT(shrinking_size.width(), text_width); + + // When we SetText() again, the shrinking gets canceled. + button_->SetText(text); + EXPECT_GT(button_->GetPreferredSize().width(), text_width); + + // Even if the layout manager resizes the button to it's size desired for + // shrinking, it's text does not get cleared and it still prefers having space + // for its label. + button_->SetSize(shrinking_size); + EXPECT_FALSE(button_->GetText().empty()); + EXPECT_GT(button_->GetPreferredSize().width(), text_width); +} + +TEST_F( + LabelButtonTest, + LabelShrinksDownImmediatelyIfAlreadySmallerThanPreferredSizeWithoutLabel) { + button_->SetBoundsRect(gfx::Rect(1, 1)); + button_->SetText(ASCIIToUTF16("abcdefghijklm")); + + // Shrinking the text down when it's already shrunk down (its size is smaller + // than preferred without label) should clear the text immediately. + EXPECT_FALSE(button_->GetText().empty()); + button_->ShrinkDownThenClearText(); + EXPECT_TRUE(button_->GetText().empty()); +} + // Test behavior of View::GetAccessibleNodeData() for buttons when setting a // label. TEST_F(LabelButtonTest, AccessibleState) {
diff --git a/ui/views/controls/tabbed_pane/tabbed_pane.cc b/ui/views/controls/tabbed_pane/tabbed_pane.cc index 65da8107..43f77bb 100644 --- a/ui/views/controls/tabbed_pane/tabbed_pane.cc +++ b/ui/views/controls/tabbed_pane/tabbed_pane.cc
@@ -29,7 +29,9 @@ #include "ui/views/controls/tabbed_pane/tabbed_pane_listener.h" #include "ui/views/layout/box_layout.h" #include "ui/views/layout/fill_layout.h" +#include "ui/views/layout/flex_layout.h" #include "ui/views/layout/layout_manager.h" +#include "ui/views/view_class_properties.h" #include "ui/views/widget/widget.h" namespace views { @@ -307,6 +309,80 @@ TabStrip::~TabStrip() = default; +void TabStrip::AnimationProgressed(const gfx::Animation* animation) { + SchedulePaint(); +} + +void TabStrip::AnimationEnded(const gfx::Animation* animation) { + if (animation == expand_animation_.get()) + contract_animation_->Start(); +} + +void TabStrip::OnSelectedTabChanged(Tab* from_tab, Tab* to_tab) { + DCHECK(!from_tab->selected()); + DCHECK(to_tab->selected()); + + if (GetOrientation() == TabbedPane::Orientation::kHorizontal) { + animating_from_ = gfx::Range(from_tab->GetMirroredX(), + from_tab->GetMirroredX() + from_tab->width()); + animating_to_ = gfx::Range(to_tab->GetMirroredX(), + to_tab->GetMirroredX() + to_tab->width()); + } else { + animating_from_ = gfx::Range(from_tab->bounds().y(), + from_tab->bounds().y() + from_tab->height()); + animating_to_ = gfx::Range(to_tab->bounds().y(), + to_tab->bounds().y() + to_tab->height()); + } + + contract_animation_->Stop(); + expand_animation_->Start(); +} + +Tab* TabStrip::GetSelectedTab() const { + size_t index = GetSelectedTabIndex(); + return index == kNoSelectedTab ? nullptr : GetTabAtIndex(index); +} + +Tab* TabStrip::GetTabAtDeltaFromSelected(int delta) const { + const size_t selected_tab_index = GetSelectedTabIndex(); + DCHECK_NE(kNoSelectedTab, selected_tab_index); + const size_t num_children = children().size(); + // Clamping |delta| here ensures that even a large negative |delta| will not + // cause the addition in the next statement to wrap below 0. + delta %= static_cast<int>(num_children); + return GetTabAtIndex((selected_tab_index + num_children + delta) % + num_children); +} + +Tab* TabStrip::GetTabAtIndex(size_t index) const { + DCHECK_LT(index, children().size()); + return static_cast<Tab*>(children()[index]); +} + +size_t TabStrip::GetSelectedTabIndex() const { + for (size_t i = 0; i < children().size(); ++i) + if (GetTabAtIndex(i)->selected()) + return i; + return kNoSelectedTab; +} + +TabbedPane::Orientation TabStrip::GetOrientation() const { + return orientation_; +} + +TabbedPane::TabStripStyle TabStrip::GetStyle() const { + return style_; +} + +gfx::Size TabStrip::CalculatePreferredSize() const { + // Tabstrips don't require any minimum space along their main axis, and can + // shrink all the way to zero size. Only the cross axis thickness matters. + const gfx::Size size = GetLayoutManager()->GetPreferredSize(this); + return (GetOrientation() == TabbedPane::Orientation::kHorizontal) + ? gfx::Size(0, size.height()) + : gfx::Size(size.width(), 0); +} + void TabStrip::OnPaintBorder(gfx::Canvas* canvas) { // Do not draw border line in kHighlight mode. if (GetStyle() == TabbedPane::TabStripStyle::kHighlight) @@ -394,71 +470,6 @@ SK_AlphaOPAQUE)); } -void TabStrip::AnimationProgressed(const gfx::Animation* animation) { - SchedulePaint(); -} - -void TabStrip::AnimationEnded(const gfx::Animation* animation) { - if (animation == expand_animation_.get()) - contract_animation_->Start(); -} - -void TabStrip::OnSelectedTabChanged(Tab* from_tab, Tab* to_tab) { - DCHECK(!from_tab->selected()); - DCHECK(to_tab->selected()); - - if (GetOrientation() == TabbedPane::Orientation::kHorizontal) { - animating_from_ = gfx::Range(from_tab->GetMirroredX(), - from_tab->GetMirroredX() + from_tab->width()); - animating_to_ = gfx::Range(to_tab->GetMirroredX(), - to_tab->GetMirroredX() + to_tab->width()); - } else { - animating_from_ = gfx::Range(from_tab->bounds().y(), - from_tab->bounds().y() + from_tab->height()); - animating_to_ = gfx::Range(to_tab->bounds().y(), - to_tab->bounds().y() + to_tab->height()); - } - - contract_animation_->Stop(); - expand_animation_->Start(); -} - -Tab* TabStrip::GetSelectedTab() const { - size_t index = GetSelectedTabIndex(); - return index == kNoSelectedTab ? nullptr : GetTabAtIndex(index); -} - -Tab* TabStrip::GetTabAtDeltaFromSelected(int delta) const { - const size_t selected_tab_index = GetSelectedTabIndex(); - DCHECK_NE(kNoSelectedTab, selected_tab_index); - const size_t num_children = children().size(); - // Clamping |delta| here ensures that even a large negative |delta| will not - // cause the addition in the next statement to wrap below 0. - delta %= static_cast<int>(num_children); - return GetTabAtIndex((selected_tab_index + num_children + delta) % - num_children); -} - -Tab* TabStrip::GetTabAtIndex(size_t index) const { - DCHECK_LT(index, children().size()); - return static_cast<Tab*>(children()[index]); -} - -size_t TabStrip::GetSelectedTabIndex() const { - for (size_t i = 0; i < children().size(); ++i) - if (GetTabAtIndex(i)->selected()) - return i; - return kNoSelectedTab; -} - -TabbedPane::Orientation TabStrip::GetOrientation() const { - return orientation_; -} - -TabbedPane::TabStripStyle TabStrip::GetStyle() const { - return style_; -} - DEFINE_ENUM_CONVERTERS(TabbedPane::Orientation, {TabbedPane::Orientation::kHorizontal, base::ASCIIToUTF16("HORIZONTAL")}, @@ -482,8 +493,16 @@ TabbedPane::TabStripStyle style) { DCHECK(orientation != TabbedPane::Orientation::kHorizontal || style != TabbedPane::TabStripStyle::kHighlight); + auto* layout = SetLayoutManager(std::make_unique<views::FlexLayout>()); + if (orientation == TabbedPane::Orientation::kHorizontal) + layout->SetOrientation(views::LayoutOrientation::kVertical); tab_strip_ = AddChildView(std::make_unique<TabStrip>(orientation, style)); contents_ = AddChildView(std::make_unique<View>()); + contents_->SetProperty(views::kFlexBehaviorKey, + views::FlexSpecification::ForSizeRule( + views::MinimumFlexSizeRule::kScaleToZero, + views::MaximumFlexSizeRule::kUnbounded)); + contents_->SetLayoutManager(std::make_unique<views::FillLayout>()); } TabbedPane::~TabbedPane() = default; @@ -546,17 +565,6 @@ SelectTab(tab); } -gfx::Size TabbedPane::CalculatePreferredSize() const { - gfx::Size size; - for (const View* child : contents_->children()) - size.SetToMax(child->GetPreferredSize()); - if (GetOrientation() == Orientation::kHorizontal) - size.Enlarge(0, tab_strip_->GetPreferredSize().height()); - else - size.Enlarge(tab_strip_->GetPreferredSize().width(), 0); - return size; -} - TabbedPane::Orientation TabbedPane::GetOrientation() const { return tab_strip_->GetOrientation(); } @@ -584,21 +592,6 @@ return true; } -void TabbedPane::Layout() { - const gfx::Size size = tab_strip_->GetPreferredSize(); - if (GetOrientation() == Orientation::kHorizontal) { - tab_strip_->SetBounds(0, 0, width(), size.height()); - contents_->SetBounds(0, tab_strip_->bounds().bottom(), width(), - std::max(0, height() - size.height())); - } else { - tab_strip_->SetBounds(0, 0, size.width(), height()); - contents_->SetBounds(tab_strip_->bounds().width(), 0, - std::max(0, width() - size.width()), height()); - } - for (View* child : contents_->children()) - child->SetSize(contents_->size()); -} - void TabbedPane::ViewHierarchyChanged( const ViewHierarchyChangedDetails& details) { if (details.is_add) {
diff --git a/ui/views/controls/tabbed_pane/tabbed_pane.h b/ui/views/controls/tabbed_pane/tabbed_pane.h index f48d440..5a565691 100644 --- a/ui/views/controls/tabbed_pane/tabbed_pane.h +++ b/ui/views/controls/tabbed_pane/tabbed_pane.h
@@ -86,9 +86,6 @@ // Selects |tab| (the tabstrip view, not its content) if it is valid. void SelectTab(Tab* tab); - // Overridden from View: - gfx::Size CalculatePreferredSize() const override; - // Gets the orientation of the tab alignment. Orientation GetOrientation() const; @@ -125,7 +122,6 @@ bool MoveSelectionBy(int delta); // Overridden from View: - void Layout() override; void ViewHierarchyChanged( const ViewHierarchyChangedDetails& details) override; bool AcceleratorPressed(const ui::Accelerator& accelerator) override; @@ -207,10 +203,7 @@ TabbedPane::TabStripStyle style); ~TabStrip() override; - // Overridden from View: - void OnPaintBorder(gfx::Canvas* canvas) override; - - // Overridden from AnimationDelegate: + // AnimationDelegate: void AnimationProgressed(const gfx::Animation* animation) override; void AnimationEnded(const gfx::Animation* animation) override; @@ -228,6 +221,11 @@ TabbedPane::TabStripStyle GetStyle() const; + protected: + // View: + gfx::Size CalculatePreferredSize() const override; + void OnPaintBorder(gfx::Canvas* canvas) override; + private: // The orientation of the tab alignment. const TabbedPane::Orientation orientation_;
diff --git a/ui/views/focus/focus_traversal_unittest.cc b/ui/views/focus/focus_traversal_unittest.cc index 0664155..342532f 100644 --- a/ui/views/focus/focus_traversal_unittest.cc +++ b/ui/views/focus/focus_traversal_unittest.cc
@@ -489,86 +489,90 @@ y += 40; // Left bottom box with style checkboxes. - auto contents = std::make_unique<View>(); - contents->SetBackground(CreateSolidBackground(SK_ColorWHITE)); + auto tabbed_pane_contents = std::make_unique<View>(); + tabbed_pane_contents->SetBackground(CreateSolidBackground(SK_ColorWHITE)); cb = std::make_unique<Checkbox>(ASCIIToUTF16("Bold")); - cb_ptr = contents->AddChildView(std::move(cb)); + cb_ptr = tabbed_pane_contents->AddChildView(std::move(cb)); cb_ptr->SetBounds(10, 10, 50, 20); cb_ptr->SetID(BOLD_CHECKBOX_ID); cb = std::make_unique<Checkbox>(ASCIIToUTF16("Italic")); - cb_ptr = contents->AddChildView(std::move(cb)); + cb_ptr = tabbed_pane_contents->AddChildView(std::move(cb)); cb_ptr->SetBounds(70, 10, 50, 20); cb_ptr->SetID(ITALIC_CHECKBOX_ID); cb = std::make_unique<Checkbox>(ASCIIToUTF16("Underlined")); - cb_ptr = contents->AddChildView(std::move(cb)); + cb_ptr = tabbed_pane_contents->AddChildView(std::move(cb)); cb_ptr->SetBounds(130, 10, 70, 20); cb_ptr->SetID(UNDERLINED_CHECKBOX_ID); auto link = std::make_unique<Link>(ASCIIToUTF16("Help")); - auto* link_ptr = contents->AddChildView(std::move(link)); + auto* link_ptr = tabbed_pane_contents->AddChildView(std::move(link)); link_ptr->SetBounds(10, 35, 70, 10); link_ptr->SetID(STYLE_HELP_LINK_ID); text_field = std::make_unique<Textfield>(); - text_field_ptr = contents->AddChildView(std::move(text_field)); + text_field_ptr = tabbed_pane_contents->AddChildView(std::move(text_field)); text_field_ptr->SetBounds(10, 50, 100, 20); text_field_ptr->SetID(STYLE_TEXT_EDIT_ID); auto style_tab = std::make_unique<TabbedPane>(); style_tab_ = GetContentsView()->AddChildView(std::move(style_tab)); style_tab_->SetBounds(10, y, 210, 100); - style_tab_->AddTab(ASCIIToUTF16("Style"), std::move(contents)); + style_tab_->AddTab(ASCIIToUTF16("Style"), std::move(tabbed_pane_contents)); style_tab_->GetSelectedTab()->SetID(STYLE_CONTAINER_ID); style_tab_->AddTab(ASCIIToUTF16("Other"), std::make_unique<View>()); // Right bottom box with search. - contents = std::make_unique<View>(); - contents->SetBackground(CreateSolidBackground(SK_ColorWHITE)); + auto border_contents = std::make_unique<View>(); + border_contents->SetBackground(CreateSolidBackground(SK_ColorWHITE)); text_field = std::make_unique<Textfield>(); - text_field_ptr = contents->AddChildView(std::move(text_field)); + text_field_ptr = border_contents->AddChildView(std::move(text_field)); text_field_ptr->SetBounds(10, 10, 100, 20); text_field_ptr->SetID(SEARCH_TEXTFIELD_ID); button = MdTextButton::Create(nullptr, ASCIIToUTF16("Search")); button->SetBounds(112, 5, 60, 30); button->SetID(SEARCH_BUTTON_ID); - contents->AddChildView(std::move(button)); + border_contents->AddChildView(std::move(button)); link = std::make_unique<Link>(ASCIIToUTF16("Help")); link->SetHorizontalAlignment(gfx::ALIGN_LEFT); link->SetID(HELP_LINK_ID); - link_ptr = contents->AddChildView(std::move(link)); + link_ptr = border_contents->AddChildView(std::move(link)); link_ptr->SetBounds(175, 10, 30, 20); - auto search_border_view = std::make_unique<BorderView>(contents.release()); + auto search_border_view = + std::make_unique<BorderView>(border_contents.release()); search_border_view->SetID(SEARCH_CONTAINER_ID); - search_border_view_ = GetContentsView()->AddChildView(std::move(search_border_view)); search_border_view_->SetBounds(300, y, 240, 50); y += 60; - contents = std::make_unique<View>(); - contents->SetFocusBehavior(View::FocusBehavior::ALWAYS); - contents->SetBackground(CreateSolidBackground(SK_ColorBLUE)); - contents->SetID(THUMBNAIL_CONTAINER_ID); + auto view_contents = std::make_unique<View>(); + view_contents->SetFocusBehavior(View::FocusBehavior::ALWAYS); + view_contents->SetBackground(CreateSolidBackground(SK_ColorBLUE)); + view_contents->SetID(THUMBNAIL_CONTAINER_ID); button = MdTextButton::Create(nullptr, ASCIIToUTF16("Star")); button->SetBounds(5, 5, 50, 30); button->SetID(THUMBNAIL_STAR_ID); - contents->AddChildView(std::move(button)); + view_contents->AddChildView(std::move(button)); button = MdTextButton::Create(nullptr, ASCIIToUTF16("SuperStar")); button->SetBounds(60, 5, 100, 30); button->SetID(THUMBNAIL_SUPER_STAR_ID); - contents->AddChildView(std::move(button)); + view_contents->AddChildView(std::move(button)); - auto* contents_ptr = GetContentsView()->AddChildView(std::move(contents)); + auto* contents_ptr = + GetContentsView()->AddChildView(std::move(view_contents)); contents_ptr->SetBounds(250, y, 200, 50); // We can only call RadioButton::SetChecked() on the radio-button is part of // the view hierarchy. radio_button_to_check->SetChecked(true); + + // Perform any pending layouts. + GetWidget()->LayoutRootViewIfNecessary(); } TEST_F(FocusTraversalTest, NormalTraversal) {
diff --git a/ui/views/layout/flex_layout.cc b/ui/views/layout/flex_layout.cc index 11286efc..a8215e3b 100644 --- a/ui/views/layout/flex_layout.cc +++ b/ui/views/layout/flex_layout.cc
@@ -421,8 +421,7 @@ // Keep track of non-hidden flex controls. const bool can_flex = - (flex_child.flex.weight() > 0 && - flex_child.preferred_size.main() > 0) || + flex_child.flex.weight() > 0 || flex_child.current_size.main() < flex_child.preferred_size.main(); if (can_flex) (*flex_order_to_index)[flex_child.flex.order()].push_back(view_index);