diff --git a/DEPS b/DEPS index 73e06bf..ee1ef0a 100644 --- a/DEPS +++ b/DEPS
@@ -79,11 +79,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': 'e168c3e8f9a13472983a567ecd679226c9d0d186', + 'skia_revision': '3ba3fa72ae2fd4102cff22b947d124f72ce0f880', # 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': '4918c096158e63a0d264b0a2b0fcbebae44a2207', + 'v8_revision': '030cf69a95f91d45843ea7ad2f2a1139f15ac68a', # 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. @@ -91,7 +91,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': '3c424b489c25552878a52c0fcb5305618221708e', + 'angle_revision': '0e99b7a3bc8b474cba091ef65bb53264e6384ce2', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling build tools # and whatever else without interference from each other. @@ -103,7 +103,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': '5ca283f376816522065c0ea35644fcb684f9572f', + 'pdfium_revision': '1fa1b1f771dd077b0fb4056c7b84f701ba733a8c', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling openmax_dl # and whatever else without interference from each other. @@ -135,7 +135,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': 'c4b36e2d9b77e6ae89274fa33a982f8efea1b948', + 'catapult_revision': '0a20f3ce6c4d6802892cbaa7489cde394eaa6fac', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -649,7 +649,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'd458ada06171a85af00367251a4ed55db7fe2018', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '58daf40bad33535ea1e931c9fc6ed409aee3e865', # commit position 20628 + Var('webrtc_git') + '/src.git' + '@' + '393e2664703351833948a30802e50d4ce101662a', # commit position 20628 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
diff --git a/android_webview/test/shell/src/org/chromium/android_webview/shell/AwShellApplication.java b/android_webview/test/shell/src/org/chromium/android_webview/shell/AwShellApplication.java index cea82bc..ab0f33e 100644 --- a/android_webview/test/shell/src/org/chromium/android_webview/shell/AwShellApplication.java +++ b/android_webview/test/shell/src/org/chromium/android_webview/shell/AwShellApplication.java
@@ -4,14 +4,13 @@ package org.chromium.android_webview.shell; +import org.chromium.base.BaseChromiumApplication; import org.chromium.base.CommandLine; -import org.chromium.content.app.ContentApplication; /** * The android_webview shell Application subclass. */ -public class AwShellApplication extends ContentApplication { - +public class AwShellApplication extends BaseChromiumApplication { public void initCommandLine() { if (!CommandLine.isInitialized()) { CommandLine.initFromFile("/data/local/tmp/android-webview-command-line");
diff --git a/base/allocator/partition_allocator/spin_lock.cc b/base/allocator/partition_allocator/spin_lock.cc index c30d6cd..fd062c3 100644 --- a/base/allocator/partition_allocator/spin_lock.cc +++ b/base/allocator/partition_allocator/spin_lock.cc
@@ -10,6 +10,8 @@ #include <sched.h> #endif +#include "base/threading/platform_thread.h" + // The YIELD_PROCESSOR macro wraps an architecture specific-instruction that // informs the processor we're in a busy wait, so it can handle the branch more // intelligently and e.g. reduce power to our core or give more resources to the @@ -67,6 +69,9 @@ // critical section defaults, and various other recommendations. // TODO(jschuh): Further tuning may be warranted. static const int kYieldProcessorTries = 1000; + // The value of |kYieldThreadTries| is completely made up. + static const int kYieldThreadTries = 10; + int yield_thread_count = 0; do { do { for (int count = 0; count < kYieldProcessorTries; ++count) { @@ -77,8 +82,17 @@ return; } - // Give the OS a chance to schedule something on this core. - YIELD_THREAD; + if (yield_thread_count < kYieldThreadTries) { + ++yield_thread_count; + // Give the OS a chance to schedule something on this core. + YIELD_THREAD; + } else { + // At this point, it's likely that the lock is held by a lower priority + // thread that is unavailable to finish its work because of higher + // priority threads spinning here. Sleeping should ensure that they make + // progress. + PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1)); + } } while (lock_.load(std::memory_order_relaxed)); } while (UNLIKELY(lock_.exchange(true, std::memory_order_acquire))); }
diff --git a/base/debug/activity_tracker.cc b/base/debug/activity_tracker.cc index 1b3aaeec..99dcdb8 100644 --- a/base/debug/activity_tracker.cc +++ b/base/debug/activity_tracker.cc
@@ -1457,12 +1457,12 @@ ProcessId process_id, const FilePath::StringType& exe, const FilePath::StringType& args) { - const int64_t pid = process_id; if (exe.find(FILE_PATH_LITERAL(" "))) { - RecordProcessLaunch(pid, FilePath::StringType(FILE_PATH_LITERAL("\"")) + - exe + FILE_PATH_LITERAL("\" ") + args); + RecordProcessLaunch(process_id, + FilePath::StringType(FILE_PATH_LITERAL("\"")) + exe + + FILE_PATH_LITERAL("\" ") + args); } else { - RecordProcessLaunch(pid, exe + FILE_PATH_LITERAL(' ') + args); + RecordProcessLaunch(process_id, exe + FILE_PATH_LITERAL(' ') + args); } }
diff --git a/base/strings/pattern.cc b/base/strings/pattern.cc index 5a0a055..c1abf5d 100644 --- a/base/strings/pattern.cc +++ b/base/strings/pattern.cc
@@ -10,126 +10,114 @@ namespace { -static bool IsWildcard(base_icu::UChar32 character) { +bool IsWildcard(base_icu::UChar32 character) { return character == '*' || character == '?'; } -// Move the strings pointers to the point where they start to differ. +// Searches for the next subpattern of |pattern| in |string|, up to the given +// |maximum_distance|. The subpattern extends from the start of |pattern| up to +// the first wildcard character (or the end of the string). If the value of +// |maximum_distance| is negative, the maximum distance is considered infinite. template <typename CHAR, typename NEXT> -static void EatSameChars(const CHAR** pattern, const CHAR* pattern_end, - const CHAR** string, const CHAR* string_end, - NEXT next) { - const CHAR* escape = nullptr; - while (*pattern != pattern_end && *string != string_end) { - if (!escape && IsWildcard(**pattern)) { - // We don't want to match wildcard here, except if it's escaped. - return; - } - - // Check if the escapement char is found. If so, skip it and move to the - // next character. - if (!escape && **pattern == '\\') { - escape = *pattern; - next(pattern, pattern_end); - continue; - } - - // Check if the chars match, if so, increment the ptrs. - const CHAR* pattern_next = *pattern; - const CHAR* string_next = *string; - base_icu::UChar32 pattern_char = next(&pattern_next, pattern_end); - if (pattern_char == next(&string_next, string_end) && - pattern_char != CBU_SENTINEL) { - *pattern = pattern_next; - *string = string_next; +bool SearchForChars(const CHAR** pattern, + const CHAR* pattern_end, + const CHAR** string, + const CHAR* string_end, + int maximum_distance, + NEXT next) { + const CHAR* pattern_start = *pattern; + const CHAR* string_start = *string; + bool escape = false; + while (true) { + if (*pattern == pattern_end) { + // If this is the end of the pattern, only accept the end of the string; + // anything else falls through to the mismatch case. + if (*string == string_end) + return true; } else { - // Uh oh, it did not match, we are done. If the last char was an - // escapement, that means that it was an error to advance the ptr here, - // let's put it back where it was. This also mean that the MatchPattern - // function will return false because if we can't match an escape char - // here, then no one will. - if (escape) { - *pattern = escape; + // If we have found a wildcard, we're done. + if (!escape && IsWildcard(**pattern)) + return true; + + // Check if the escape character is found. If so, skip it and move to the + // next character. + if (!escape && **pattern == '\\') { + escape = true; + next(pattern, pattern_end); + continue; } - return; + + escape = false; + + if (*string == string_end) + return false; + + // Check if the chars match, if so, increment the ptrs. + const CHAR* pattern_next = *pattern; + const CHAR* string_next = *string; + base_icu::UChar32 pattern_char = next(&pattern_next, pattern_end); + if (pattern_char == next(&string_next, string_end) && + pattern_char != CBU_SENTINEL) { + *pattern = pattern_next; + *string = string_next; + continue; + } } - escape = nullptr; + // Mismatch. If we have reached the maximum distance, return false, + // otherwise restart at the beginning of the pattern with the next character + // in the string. + // TODO(bauerb): This is a naive implementation of substring search, which + // could be implemented with a more efficient algorithm, e.g. + // Knuth-Morris-Pratt (at the expense of requiring preprocessing). + if (maximum_distance == 0) + return false; + + // Because unlimited distance is represented as -1, this will never reach 0 + // and therefore fail the match above. + maximum_distance--; + *pattern = pattern_start; + next(&string_start, string_end); + *string = string_start; } } +// Consumes consecutive wildcard characters (? or *). Returns the maximum number +// of characters matched by the sequence of wildcards, or -1 if the wildcards +// match an arbitrary number of characters (which is the case if it contains at +// least one *). template <typename CHAR, typename NEXT> -static void EatWildcard(const CHAR** pattern, const CHAR* end, NEXT next) { +int EatWildcards(const CHAR** pattern, const CHAR* end, NEXT next) { + int num_question_marks = 0; + bool has_asterisk = false; while (*pattern != end) { - if (!IsWildcard(**pattern)) - return; + if (**pattern == '?') { + num_question_marks++; + } else if (**pattern == '*') { + has_asterisk = true; + } else { + break; + } + next(pattern, end); } + return has_asterisk ? -1 : num_question_marks; } template <typename CHAR, typename NEXT> -static bool MatchPatternT(const CHAR* eval, const CHAR* eval_end, - const CHAR* pattern, const CHAR* pattern_end, - int depth, - NEXT next) { - const int kMaxDepth = 16; - if (depth > kMaxDepth) - return false; - - // Eat all the matching chars. - EatSameChars(&pattern, pattern_end, &eval, eval_end, next); - - // If the string is empty, then the pattern must be empty too, or contains - // only wildcards. - if (eval == eval_end) { - EatWildcard(&pattern, pattern_end, next); - return pattern == pattern_end; - } - - // Pattern is empty but not string, this is not a match. - if (pattern == pattern_end) - return false; - - // If this is a question mark, then we need to compare the rest with - // the current string or the string with one character eaten. - const CHAR* next_pattern = pattern; - next(&next_pattern, pattern_end); - if (pattern[0] == '?') { - if (MatchPatternT(eval, eval_end, next_pattern, pattern_end, - depth + 1, next)) - return true; - const CHAR* next_eval = eval; - next(&next_eval, eval_end); - if (MatchPatternT(next_eval, eval_end, next_pattern, pattern_end, - depth + 1, next)) - return true; - } - - // This is a *, try to match all the possible substrings with the remainder - // of the pattern. - if (pattern[0] == '*') { - // Collapse duplicate wild cards (********** into *) so that the - // method does not recurse unnecessarily. http://crbug.com/52839 - EatWildcard(&next_pattern, pattern_end, next); - - while (eval != eval_end) { - if (MatchPatternT(eval, eval_end, next_pattern, pattern_end, - depth + 1, next)) - return true; - eval++; +bool MatchPatternT(const CHAR* eval, + const CHAR* eval_end, + const CHAR* pattern, + const CHAR* pattern_end, + NEXT next) { + do { + int maximum_wildcard_length = EatWildcards(&pattern, pattern_end, next); + if (!SearchForChars(&pattern, pattern_end, &eval, eval_end, + maximum_wildcard_length, next)) { + return false; } - - // We reached the end of the string, let see if the pattern contains only - // wildcards. - if (eval == eval_end) { - EatWildcard(&pattern, pattern_end, next); - if (pattern != pattern_end) - return false; - return true; - } - } - - return false; + } while (pattern != pattern_end); + return true; } struct NextCharUTF8 { @@ -155,15 +143,13 @@ } // namespace bool MatchPattern(StringPiece eval, StringPiece pattern) { - return MatchPatternT(eval.data(), eval.data() + eval.size(), - pattern.data(), pattern.data() + pattern.size(), - 0, NextCharUTF8()); + return MatchPatternT(eval.data(), eval.data() + eval.size(), pattern.data(), + pattern.data() + pattern.size(), NextCharUTF8()); } bool MatchPattern(StringPiece16 eval, StringPiece16 pattern) { - return MatchPatternT(eval.data(), eval.data() + eval.size(), - pattern.data(), pattern.data() + pattern.size(), - 0, NextCharUTF16()); + return MatchPatternT(eval.data(), eval.data() + eval.size(), pattern.data(), + pattern.data() + pattern.size(), NextCharUTF16()); } } // namespace base
diff --git a/base/strings/pattern.h b/base/strings/pattern.h index 15f96e2..b5172ab 100644 --- a/base/strings/pattern.h +++ b/base/strings/pattern.h
@@ -10,11 +10,10 @@ namespace base { -// Returns true if the string passed in matches the pattern. The pattern -// string can contain wildcards like * and ? +// Returns true if the |string| passed in matches the |pattern|. The pattern +// string can contain wildcards like * and ?. // -// The backslash character (\) is an escape character for * and ? -// We limit the patterns to having a max of 16 * or ? characters. +// The backslash character (\) is an escape character for * and ?. // ? matches 0 or 1 character, while * matches 0 or more characters. BASE_EXPORT bool MatchPattern(StringPiece string, StringPiece pattern); BASE_EXPORT bool MatchPattern(StringPiece16 string, StringPiece16 pattern);
diff --git a/base/strings/pattern_unittest.cc b/base/strings/pattern_unittest.cc index 9e82b3cb..8ec54954 100644 --- a/base/strings/pattern_unittest.cc +++ b/base/strings/pattern_unittest.cc
@@ -22,8 +22,10 @@ EXPECT_TRUE(MatchPattern("", "")); EXPECT_FALSE(MatchPattern("Hello", "")); EXPECT_TRUE(MatchPattern("Hello*", "Hello*")); - // Stop after a certain recursion depth. - EXPECT_FALSE(MatchPattern("123456789012345678", "?????????????????*")); + EXPECT_TRUE(MatchPattern("abcd", "*???")); + EXPECT_FALSE(MatchPattern("abcd", "???")); + EXPECT_TRUE(MatchPattern("abcb", "a*b")); + EXPECT_FALSE(MatchPattern("abcb", "a?b")); // Test UTF8 matching. EXPECT_TRUE(MatchPattern("heart: \xe2\x99\xa0", "*\xe2\x99\xa0")); @@ -40,11 +42,11 @@ EXPECT_TRUE(MatchPattern(UTF8ToUTF16("Hello*1234"), UTF8ToUTF16("He??o\\*1*"))); - // This test verifies that consecutive wild cards are collapsed into 1 - // wildcard (when this doesn't occur, MatchPattern reaches it's maximum - // recursion depth). - EXPECT_TRUE(MatchPattern(UTF8ToUTF16("Hello"), - UTF8ToUTF16("He********************************o"))); + // Some test cases that might cause naive implementations to exhibit + // exponential run time or fail. + EXPECT_TRUE(MatchPattern("Hello", "He********************************o")); + EXPECT_TRUE(MatchPattern("123456789012345678", "?????????????????*")); + EXPECT_TRUE(MatchPattern("aaaaaaaaaaab", "a*a*a*a*a*a*a*a*a*a*a*b")); } } // namespace base
diff --git a/base/win/windows_types.h b/base/win/windows_types.h index 091e47f..8060f03 100644 --- a/base/win/windows_types.h +++ b/base/win/windows_types.h
@@ -78,6 +78,7 @@ CHROME_DECLARE_HANDLE(HICON); CHROME_DECLARE_HANDLE(HINSTANCE); CHROME_DECLARE_HANDLE(HKEY); +CHROME_DECLARE_HANDLE(HKL); CHROME_DECLARE_HANDLE(HMENU); CHROME_DECLARE_HANDLE(HWND); typedef HINSTANCE HMODULE; @@ -102,6 +103,7 @@ typedef struct tagMENUITEMINFOW MENUITEMINFOW, MENUITEMINFO; +typedef struct tagNMHDR NMHDR; // Declare Chrome versions of some Windows structures. These are needed for // when we need a concrete type but don't want to pull in Windows.h. We can't
diff --git a/build/android/gyp/dist_aar.py b/build/android/gyp/dist_aar.py index 51515fa..6dc38c4 100755 --- a/build/android/gyp/dist_aar.py +++ b/build/android/gyp/dist_aar.py
@@ -72,13 +72,23 @@ '--android-manifest', help='Path to AndroidManifest.xml to include.', default=os.path.join(_ANDROID_BUILD_DIR, 'AndroidManifest.xml')) + parser.add_argument('--native-libraries', default='', + help='GN list of native libraries. If non-empty then ' + 'ABI must be specified.') + parser.add_argument('--abi', + help='ABI (e.g. armeabi-v7a) for native libraries.') options = parser.parse_args(args) + + if options.native_libraries and not options.abi: + parser.error('You must provide --abi if you have native libs') + options.jars = build_utils.ParseGnList(options.jars) options.dependencies_res_zips = build_utils.ParseGnList( options.dependencies_res_zips) options.r_text_files = build_utils.ParseGnList(options.r_text_files) options.proguard_configs = build_utils.ParseGnList(options.proguard_configs) + options.native_libraries = build_utils.ParseGnList(options.native_libraries) with tempfile.NamedTemporaryFile(delete=False) as staging_file: try: @@ -100,6 +110,12 @@ data=_MergeProguardConfigs(options.proguard_configs)) _AddResources(z, options.dependencies_res_zips) + + for native_library in options.native_libraries: + libname = os.path.basename(native_library) + build_utils.AddToZipHermetic( + z, os.path.join('jni', options.abi, libname), + src_path=native_library) except: os.unlink(staging_file.name) raise
diff --git a/build/android/gyp/javac.py b/build/android/gyp/javac.py index 79815a83..79e47e1 100755 --- a/build/android/gyp/javac.py +++ b/build/android/gyp/javac.py
@@ -35,8 +35,22 @@ 'NarrowingCompoundAssignment', # TODO(crbug.com/802073): Follow steps in bug. 'TypeParameterUnusedInFormals', - # TODO(crbug.com/802075): Follow steps in bug + # TODO(crbug.com/802075): Follow steps in bug. 'ReferenceEquality', + # TODO(crbug.com/803482): Follow steps in bug. + 'UseCorrectAssertInTests', + # TODO(crbug.com/803484): Follow steps in bug. + 'CatchFail', + # TODO(crbug.com/803485): Follow steps in bug. + 'JUnitAmbiguousTestClass', + # TODO(crbug.com/803486): Follow steps in bug. + 'AssertionFailureIgnored', + # TODO(crbug.com/803587): Follow steps in bug. + 'MissingOverride', + # TODO(crbug.com/803589): Follow steps in bug. + 'MissingFail', + # TODO(crbug.com/803625): Follow steps in bug. + 'StaticGuardedByInstance', # Android platform default is always UTF-8. # https://developer.android.com/reference/java/nio/charset/Charset.html#defaultCharset() 'DefaultCharset', @@ -78,6 +92,14 @@ 'TypeParameterShadowing', # Good to have immutable enums, also low priority. 'ImmutableEnumChecker', + # False positives for testing. + 'InputStreamSlowMultibyteRead', + # Nice to have better primitives. + 'BoxedPrimitiveConstructor', + # Not necessary for tests. + 'OverrideThrowableToString', + # Nice to have better type safety. + 'CollectionToArraySafeParameter', ] ERRORPRONE_WARNINGS_TO_ERROR = [
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni index 33ea74a..06b0968 100644 --- a/build/config/android/rules.gni +++ b/build/config/android/rules.gni
@@ -1480,6 +1480,7 @@ # Currently supports: # * AndroidManifest.xml # * classes.jar + # * jni/ # * res/ # * R.txt # * proguard.txt @@ -1487,13 +1488,13 @@ # * public.txt # * annotations.zip # * assets/ - # * jni/ # See: https://developer.android.com/studio/projects/android-library.html#aar-contents # # Variables: # output: Path to the output .aar. # proguard_configs: List of proguard configs (optional). # android_manifest: Path to AndroidManifest.xml (optional). + # native_libraries: list of native libraries (optional). # # Example # dist_aar("my_aar") { @@ -1554,6 +1555,16 @@ rebase_path(invoker.android_manifest, root_build_dir), ] } + if (defined(invoker.native_libraries) && invoker.native_libraries != []) { + inputs += invoker.native_libraries + _rebased_native_libraries = + rebase_path(invoker.native_libraries, root_build_dir) + + args += [ + "--native-libraries=$_rebased_native_libraries", + "--abi=$android_app_abi", + ] + } } }
diff --git a/cc/ipc/cc_param_traits_macros.h b/cc/ipc/cc_param_traits_macros.h index ae5ae805..afc513e 100644 --- a/cc/ipc/cc_param_traits_macros.h +++ b/cc/ipc/cc_param_traits_macros.h
@@ -24,7 +24,6 @@ #include "components/viz/common/resources/transferable_resource.h" #include "components/viz/common/surfaces/surface_id.h" #include "components/viz/common/surfaces/surface_info.h" -#include "components/viz/common/surfaces/surface_sequence.h" #include "ui/gfx/ipc/buffer_types/gfx_param_traits.h" #include "ui/gfx/ipc/color/gfx_param_traits.h" #include "ui/gfx/ipc/gfx_param_traits.h" @@ -45,11 +44,6 @@ // TODO(fsamuel): This trait belongs with skia code. IPC_ENUM_TRAITS_MAX_VALUE(SkBlendMode, SkBlendMode::kLastMode) -IPC_STRUCT_TRAITS_BEGIN(viz::SurfaceSequence) - IPC_STRUCT_TRAITS_MEMBER(frame_sink_id) - IPC_STRUCT_TRAITS_MEMBER(sequence) -IPC_STRUCT_TRAITS_END() - IPC_STRUCT_TRAITS_BEGIN(viz::DrawQuad) IPC_STRUCT_TRAITS_MEMBER(material) IPC_STRUCT_TRAITS_MEMBER(rect)
diff --git a/cc/layers/surface_layer.cc b/cc/layers/surface_layer.cc index 018af160..2b7b759 100644 --- a/cc/layers/surface_layer.cc +++ b/cc/layers/surface_layer.cc
@@ -8,58 +8,17 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" -#include "base/single_thread_task_runner.h" #include "base/trace_event/trace_event.h" #include "cc/layers/surface_layer_impl.h" #include "cc/trees/layer_tree_host.h" -#include "cc/trees/swap_promise.h" -#include "cc/trees/swap_promise_manager.h" -#include "cc/trees/task_runner_provider.h" -#include "components/viz/common/surfaces/surface_sequence_generator.h" namespace cc { -class SatisfySwapPromise : public SwapPromise { - public: - SatisfySwapPromise( - base::Closure reference_returner, - scoped_refptr<base::SingleThreadTaskRunner> main_task_runner) - : reference_returner_(reference_returner), - main_task_runner_(std::move(main_task_runner)) {} - - ~SatisfySwapPromise() override = default; - - private: - void DidActivate() override {} - - void WillSwap(viz::CompositorFrameMetadata* compositor_frame_metadata, - RenderFrameMetadata* render_frame_metadata) override {} - - void DidSwap() override { - main_task_runner_->PostTask(FROM_HERE, reference_returner_); - } - - DidNotSwapAction DidNotSwap(DidNotSwapReason reason) override { - main_task_runner_->PostTask(FROM_HERE, reference_returner_); - return DidNotSwapAction::BREAK_PROMISE; - } - - int64_t TraceId() const override { return 0; } - - base::Closure reference_returner_; - scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; - - DISALLOW_COPY_AND_ASSIGN(SatisfySwapPromise); -}; - -scoped_refptr<SurfaceLayer> SurfaceLayer::Create( - scoped_refptr<viz::SurfaceReferenceFactory> ref_factory) { - return base::WrapRefCounted(new SurfaceLayer(std::move(ref_factory))); +scoped_refptr<SurfaceLayer> SurfaceLayer::Create() { + return base::WrapRefCounted(new SurfaceLayer()); } -SurfaceLayer::SurfaceLayer( - scoped_refptr<viz::SurfaceReferenceFactory> ref_factory) - : ref_factory_(std::move(ref_factory)) {} +SurfaceLayer::SurfaceLayer() = default; SurfaceLayer::~SurfaceLayer() { DCHECK(!layer_tree_host()); @@ -82,17 +41,14 @@ if (fallback_surface_id_ == surface_id) return; - RemoveReference(std::move(fallback_reference_returner_)); if (layer_tree_host()) layer_tree_host()->RemoveSurfaceLayerId(fallback_surface_id_); fallback_surface_id_ = surface_id; - if (layer_tree_host() && fallback_surface_id_.is_valid()) { - fallback_reference_returner_ = - ref_factory_->CreateReference(layer_tree_host(), fallback_surface_id_); + if (layer_tree_host() && fallback_surface_id_.is_valid()) layer_tree_host()->AddSurfaceLayerId(fallback_surface_id_); - } + SetNeedsCommit(); } @@ -121,14 +77,10 @@ if (layer_tree_host() && fallback_surface_id_.is_valid()) layer_tree_host()->RemoveSurfaceLayerId(fallback_surface_id_); - RemoveReference(std::move(fallback_reference_returner_)); Layer::SetLayerTreeHost(host); - if (layer_tree_host() && fallback_surface_id_.is_valid()) { - fallback_reference_returner_ = - ref_factory_->CreateReference(layer_tree_host(), fallback_surface_id_); + if (layer_tree_host() && fallback_surface_id_.is_valid()) layer_tree_host()->AddSurfaceLayerId(fallback_surface_id_); - } } void SurfaceLayer::PushPropertiesTo(LayerImpl* layer) { @@ -142,14 +94,4 @@ layer_impl->SetStretchContentToFillBounds(stretch_content_to_fill_bounds_); } -void SurfaceLayer::RemoveReference(base::Closure reference_returner) { - if (!reference_returner) - return; - auto swap_promise = std::make_unique<SatisfySwapPromise>( - std::move(reference_returner), - layer_tree_host()->GetTaskRunnerProvider()->MainThreadTaskRunner()); - layer_tree_host()->GetSwapPromiseManager()->QueueSwapPromise( - std::move(swap_promise)); -} - } // namespace cc
diff --git a/cc/layers/surface_layer.h b/cc/layers/surface_layer.h index 0e084dd..a627a94 100644 --- a/cc/layers/surface_layer.h +++ b/cc/layers/surface_layer.h
@@ -9,7 +9,6 @@ #include "cc/cc_export.h" #include "cc/layers/layer.h" #include "components/viz/common/surfaces/surface_info.h" -#include "components/viz/common/surfaces/surface_reference_factory.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/gfx/geometry/size.h" @@ -19,8 +18,7 @@ // instance or client. class CC_EXPORT SurfaceLayer : public Layer { public: - static scoped_refptr<SurfaceLayer> Create( - scoped_refptr<viz::SurfaceReferenceFactory> ref_factory); + static scoped_refptr<SurfaceLayer> Create(); void SetPrimarySurfaceId(const viz::SurfaceId& surface_id, base::Optional<uint32_t> deadline_in_frames); @@ -35,11 +33,6 @@ void SetLayerTreeHost(LayerTreeHost* host) override; void PushPropertiesTo(LayerImpl* layer) override; - scoped_refptr<viz::SurfaceReferenceFactory> surface_reference_factory() - const { - return ref_factory_; - } - const viz::SurfaceId& primary_surface_id() const { return primary_surface_id_; } @@ -49,20 +42,16 @@ } protected: - explicit SurfaceLayer( - scoped_refptr<viz::SurfaceReferenceFactory> ref_factory); + SurfaceLayer(); bool HasDrawableContent() const override; private: ~SurfaceLayer() override; - void RemoveReference(base::Closure reference_returner); viz::SurfaceId primary_surface_id_; viz::SurfaceId fallback_surface_id_; - base::Closure fallback_reference_returner_; base::Optional<uint32_t> deadline_in_frames_; - scoped_refptr<viz::SurfaceReferenceFactory> ref_factory_; bool stretch_content_to_fill_bounds_ = false; DISALLOW_COPY_AND_ASSIGN(SurfaceLayer);
diff --git a/cc/layers/surface_layer_unittest.cc b/cc/layers/surface_layer_unittest.cc index d32696cb..e5aacb6 100644 --- a/cc/layers/surface_layer_unittest.cc +++ b/cc/layers/surface_layer_unittest.cc
@@ -24,7 +24,6 @@ #include "cc/test/test_task_graph_runner.h" #include "cc/trees/layer_tree_host.h" #include "components/viz/common/quads/compositor_frame.h" -#include "components/viz/common/surfaces/sequence_surface_reference_factory.h" #include "components/viz/common/surfaces/surface_info.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -75,95 +74,10 @@ FakeLayerTreeHostImpl host_impl_; }; -class MockSurfaceReferenceFactory - : public viz::SequenceSurfaceReferenceFactory { - public: - MockSurfaceReferenceFactory() = default; - - // SequenceSurfaceReferenceFactory implementation. - MOCK_CONST_METHOD1(SatisfySequence, void(const viz::SurfaceSequence&)); - MOCK_CONST_METHOD2(RequireSequence, - void(const viz::SurfaceId&, const viz::SurfaceSequence&)); - - protected: - ~MockSurfaceReferenceFactory() override = default; - - private: - DISALLOW_COPY_AND_ASSIGN(MockSurfaceReferenceFactory); -}; - -// Check that one surface can be referenced by multiple LayerTreeHosts, and -// each will create its own viz::SurfaceSequence that's satisfied on -// destruction. -TEST_F(SurfaceLayerTest, MultipleFramesOneSurface) { - const base::UnguessableToken kArbitraryToken = - base::UnguessableToken::Create(); - const viz::SurfaceId surface_id(kArbitraryFrameSinkId, - viz::LocalSurfaceId(1, kArbitraryToken)); - const viz::SurfaceSequence expected_seq1(viz::FrameSinkId(1, 1), 1u); - const viz::SurfaceSequence expected_seq2(viz::FrameSinkId(2, 2), 1u); - const viz::SurfaceId expected_id(kArbitraryFrameSinkId, - viz::LocalSurfaceId(1, kArbitraryToken)); - - scoped_refptr<MockSurfaceReferenceFactory> ref_factory = - new testing::StrictMock<MockSurfaceReferenceFactory>(); - - // We are going to set up the SurfaceLayers and LayerTreeHosts. Each layer - // will require a sequence and no sequence should be satisfied for now. - EXPECT_CALL(*ref_factory, RequireSequence(Eq(expected_id), Eq(expected_seq1))) - .Times(1); - EXPECT_CALL(*ref_factory, RequireSequence(Eq(expected_id), Eq(expected_seq2))) - .Times(1); - EXPECT_CALL(*ref_factory, SatisfySequence(_)).Times(0); - - auto layer = SurfaceLayer::Create(ref_factory); - layer->SetPrimarySurfaceId(surface_id, base::nullopt); - layer->SetFallbackSurfaceId(surface_id); - layer_tree_host_->GetSurfaceSequenceGenerator()->set_frame_sink_id( - viz::FrameSinkId(1, 1)); - layer_tree_host_->SetRootLayer(layer); - - auto animation_host2 = AnimationHost::CreateForTesting(ThreadInstance::MAIN); - std::unique_ptr<FakeLayerTreeHost> layer_tree_host2 = - FakeLayerTreeHost::Create(&fake_client_, &task_graph_runner_, - animation_host2.get()); - auto layer2 = SurfaceLayer::Create(ref_factory); - layer2->SetPrimarySurfaceId(surface_id, base::nullopt); - layer2->SetFallbackSurfaceId(surface_id); - layer_tree_host2->GetSurfaceSequenceGenerator()->set_frame_sink_id( - viz::FrameSinkId(2, 2)); - layer_tree_host2->SetRootLayer(layer2); - - testing::Mock::VerifyAndClearExpectations(ref_factory.get()); - - // Destroy the second LayerTreeHost. The sequence generated by its - // SurfaceLayer must be satisfied and no new sequences must be required. - EXPECT_CALL(*ref_factory, SatisfySequence(Eq(expected_seq2))).Times(1); - layer_tree_host2->SetRootLayer(nullptr); - layer_tree_host2.reset(); - animation_host2 = nullptr; - base::RunLoop().RunUntilIdle(); - testing::Mock::VerifyAndClearExpectations(ref_factory.get()); - - // Destroy the first LayerTreeHost. The sequence generated by its - // SurfaceLayer must be satisfied and no new sequences must be required. - EXPECT_CALL(*ref_factory, SatisfySequence(expected_seq1)).Times(1); - EXPECT_CALL(*ref_factory, RequireSequence(_, _)).Times(0); - layer_tree_host_->SetRootLayer(nullptr); - layer_tree_host_.reset(); - base::RunLoop().RunUntilIdle(); - testing::Mock::VerifyAndClearExpectations(ref_factory.get()); -} - // This test verifies that SurfaceLayer properties are pushed across to // SurfaceLayerImpl. TEST_F(SurfaceLayerTest, PushProperties) { - // We use a nice mock here because we are not really interested in calls to - // MockSurfaceReferenceFactory and we don't want warnings printed. - scoped_refptr<viz::SurfaceReferenceFactory> ref_factory = - new testing::NiceMock<MockSurfaceReferenceFactory>(); - - scoped_refptr<SurfaceLayer> layer = SurfaceLayer::Create(ref_factory); + scoped_refptr<SurfaceLayer> layer = SurfaceLayer::Create(); layer_tree_host_->SetRootLayer(layer); viz::SurfaceId primary_id( kArbitraryFrameSinkId, @@ -229,25 +143,20 @@ // surface layers. This emulates the flow of maximize and minimize animations on // Chrome OS. TEST_F(SurfaceLayerTest, CheckSurfaceReferencesForClonedLayer) { - // We use a nice mock here because we are not really interested in calls to - // MockSurfaceReferenceFactory and we don't want warnings printed. - scoped_refptr<viz::SurfaceReferenceFactory> ref_factory = - new testing::NiceMock<MockSurfaceReferenceFactory>(); - const viz::SurfaceId old_surface_id( kArbitraryFrameSinkId, viz::LocalSurfaceId(1, base::UnguessableToken::Create())); // This layer will always contain the old surface id and will be deleted when // animation is done. - scoped_refptr<SurfaceLayer> layer1 = SurfaceLayer::Create(ref_factory); + scoped_refptr<SurfaceLayer> layer1 = SurfaceLayer::Create(); layer1->SetLayerTreeHost(layer_tree_host_.get()); layer1->SetPrimarySurfaceId(old_surface_id, base::nullopt); layer1->SetFallbackSurfaceId(old_surface_id); // This layer will eventually be switched be switched to show the new surface // id and will be retained when animation is done. - scoped_refptr<SurfaceLayer> layer2 = SurfaceLayer::Create(ref_factory); + scoped_refptr<SurfaceLayer> layer2 = SurfaceLayer::Create(); layer2->SetLayerTreeHost(layer_tree_host_.get()); layer2->SetPrimarySurfaceId(old_surface_id, base::nullopt); layer2->SetFallbackSurfaceId(old_surface_id); @@ -297,16 +206,11 @@ // This test verifies LayerTreeHost::needs_surface_ids_sync() is correct when // there are cloned surface layers. TEST_F(SurfaceLayerTest, CheckNeedsSurfaceIdsSyncForClonedLayers) { - // We use a nice mock here because we are not really interested in calls to - // MockSurfaceReferenceFactory and we don't want warnings printed. - scoped_refptr<viz::SurfaceReferenceFactory> ref_factory = - new testing::NiceMock<MockSurfaceReferenceFactory>(); - const viz::SurfaceId surface_id( kArbitraryFrameSinkId, viz::LocalSurfaceId(1, base::UnguessableToken::Create())); - scoped_refptr<SurfaceLayer> layer1 = SurfaceLayer::Create(ref_factory); + scoped_refptr<SurfaceLayer> layer1 = SurfaceLayer::Create(); layer1->SetLayerTreeHost(layer_tree_host_.get()); layer1->SetPrimarySurfaceId(surface_id, base::nullopt); layer1->SetFallbackSurfaceId(surface_id); @@ -324,7 +228,7 @@ EXPECT_FALSE(layer_tree_host_->needs_surface_ids_sync()); // Create the second layer that is a clone of the first. - scoped_refptr<SurfaceLayer> layer2 = SurfaceLayer::Create(ref_factory); + scoped_refptr<SurfaceLayer> layer2 = SurfaceLayer::Create(); layer2->SetLayerTreeHost(layer_tree_host_.get()); layer2->SetPrimarySurfaceId(surface_id, base::nullopt); layer2->SetFallbackSurfaceId(surface_id); @@ -355,127 +259,5 @@ EXPECT_THAT(layer_tree_host_->SurfaceLayerIds(), SizeIs(0)); } -// Check that viz::SurfaceSequence is sent through swap promise. -class SurfaceLayerSwapPromise : public LayerTreeTest { - public: - SurfaceLayerSwapPromise() - : commit_count_(0), sequence_was_satisfied_(false) {} - - void BeginTest() override { - layer_tree_host()->GetSurfaceSequenceGenerator()->set_frame_sink_id( - viz::FrameSinkId(1, 1)); - ref_factory_ = new testing::StrictMock<MockSurfaceReferenceFactory>(); - - // Create a SurfaceLayer but don't add it to the tree yet. No sequence - // should be required / satisfied. - EXPECT_CALL(*ref_factory_, SatisfySequence(_)).Times(0); - EXPECT_CALL(*ref_factory_, RequireSequence(_, _)).Times(0); - layer_ = SurfaceLayer::Create(ref_factory_); - viz::SurfaceId surface_id(kArbitraryFrameSinkId, - viz::LocalSurfaceId(1, kArbitraryToken)); - layer_->SetPrimarySurfaceId(surface_id, base::nullopt); - layer_->SetFallbackSurfaceId(surface_id); - testing::Mock::VerifyAndClearExpectations(ref_factory_.get()); - - // Add the layer to the tree. A sequence must be required. - viz::SurfaceSequence expected_seq(kArbitraryFrameSinkId, 1u); - viz::SurfaceId expected_id(kArbitraryFrameSinkId, - viz::LocalSurfaceId(1, kArbitraryToken)); - EXPECT_CALL(*ref_factory_, SatisfySequence(_)).Times(0); - EXPECT_CALL(*ref_factory_, - RequireSequence(Eq(expected_id), Eq(expected_seq))) - .Times(1); - layer_tree_host()->SetRootLayer(layer_); - testing::Mock::VerifyAndClearExpectations(ref_factory_.get()); - - // By the end of the test, the required sequence must be satisfied and no - // more sequence must be required. - EXPECT_CALL(*ref_factory_, SatisfySequence(Eq(expected_seq))).Times(1); - EXPECT_CALL(*ref_factory_, RequireSequence(_, _)).Times(0); - - gfx::Size bounds(100, 100); - layer_tree_host()->SetViewportSize(bounds); - - blank_layer_ = SolidColorLayer::Create(); - blank_layer_->SetIsDrawable(true); - blank_layer_->SetBounds(gfx::Size(10, 10)); - - PostSetNeedsCommitToMainThread(); - } - - virtual void ChangeTree() = 0; - - void DidCommitAndDrawFrame() override { - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(&SurfaceLayerSwapPromise::ChangeTree, - base::Unretained(this))); - } - - void AfterTest() override {} - - protected: - int commit_count_; - bool sequence_was_satisfied_; - scoped_refptr<SurfaceLayer> layer_; - scoped_refptr<Layer> blank_layer_; - scoped_refptr<MockSurfaceReferenceFactory> ref_factory_; - - const base::UnguessableToken kArbitraryToken = - base::UnguessableToken::Create(); -}; - -// Check that viz::SurfaceSequence is sent through swap promise. -class SurfaceLayerSwapPromiseWithDraw : public SurfaceLayerSwapPromise { - public: - void ChangeTree() override { - ++commit_count_; - switch (commit_count_) { - case 1: - // Remove SurfaceLayer from tree to cause SwapPromise to be created. - layer_tree_host()->SetRootLayer(blank_layer_); - break; - case 2: - EndTest(); - break; - default: - NOTREACHED(); - break; - } - } -}; - -SINGLE_AND_MULTI_THREAD_TEST_F(SurfaceLayerSwapPromiseWithDraw); - -// Check that viz::SurfaceSequence is sent through swap promise and resolved -// when swap fails. -class SurfaceLayerSwapPromiseWithoutDraw : public SurfaceLayerSwapPromise { - public: - SurfaceLayerSwapPromiseWithoutDraw() : SurfaceLayerSwapPromise() {} - - DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, - LayerTreeHostImpl::FrameData* frame, - DrawResult draw_result) override { - return DRAW_ABORTED_MISSING_HIGH_RES_CONTENT; - } - - void ChangeTree() override { - ++commit_count_; - switch (commit_count_) { - case 1: - // Remove SurfaceLayer from tree to cause SwapPromise to be created. - layer_tree_host()->SetRootLayer(blank_layer_); - break; - case 2: - layer_tree_host()->SetNeedsCommit(); - break; - default: - EndTest(); - break; - } - } -}; - -MULTI_THREAD_TEST_F(SurfaceLayerSwapPromiseWithoutDraw); - } // namespace } // namespace cc
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc index 85872e62..ecab8f5 100644 --- a/cc/trees/layer_tree_host.cc +++ b/cc/trees/layer_tree_host.cc
@@ -226,10 +226,6 @@ return settings_; } -void LayerTreeHost::SetFrameSinkId(const viz::FrameSinkId& frame_sink_id) { - surface_sequence_generator_.set_frame_sink_id(frame_sink_id); -} - void LayerTreeHost::QueueSwapPromise( std::unique_ptr<SwapPromise> swap_promise) { swap_promise_manager_.QueueSwapPromise(std::move(swap_promise)); @@ -243,10 +239,6 @@ SetNeedsAnimate(); } -viz::SurfaceSequenceGenerator* LayerTreeHost::GetSurfaceSequenceGenerator() { - return &surface_sequence_generator_; -} - void LayerTreeHost::WillBeginMainFrame() { inside_main_frame_ = true; devtools_instrumentation::WillBeginMainThreadFrame(GetId(),
diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h index 600ac2b..77be794 100644 --- a/cc/trees/layer_tree_host.h +++ b/cc/trees/layer_tree_host.h
@@ -44,8 +44,6 @@ #include "cc/trees/swap_promise_manager.h" #include "cc/trees/target_property.h" #include "components/viz/common/resources/resource_format.h" -#include "components/viz/common/surfaces/surface_reference_owner.h" -#include "components/viz/common/surfaces/surface_sequence_generator.h" #include "services/metrics/public/cpp/ukm_source_id.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/gfx/geometry/rect.h" @@ -69,8 +67,7 @@ struct RenderingStats; struct ScrollAndScaleSet; -class CC_EXPORT LayerTreeHost : public viz::SurfaceReferenceOwner, - public MutatorHostClient { +class CC_EXPORT LayerTreeHost : public MutatorHostClient { public: struct CC_EXPORT InitParams { LayerTreeHostClient* client = nullptr; @@ -98,7 +95,7 @@ LayerTreeHostSingleThreadClient* single_thread_client, InitParams* params); - ~LayerTreeHost() override; + virtual ~LayerTreeHost(); // Returns the process global unique identifier for this LayerTreeHost. int GetId() const; @@ -118,10 +115,6 @@ // Returns the settings used by this host. const LayerTreeSettings& GetSettings() const; - // Sets the client id used to generate the viz::SurfaceId that uniquely - // identifies the Surfaces produced by this compositor. - void SetFrameSinkId(const viz::FrameSinkId& frame_sink_id); - // Sets the LayerTreeMutator interface used to directly mutate the compositor // state on the compositor thread. (Compositor-Worker) void SetLayerTreeMutator(std::unique_ptr<LayerTreeMutator> mutator); @@ -481,9 +474,6 @@ // are always already built and so cc doesn't have to build them. bool IsUsingLayerLists() const; - // viz::SurfaceReferenceOwner implementation. - viz::SurfaceSequenceGenerator* GetSurfaceSequenceGenerator() override; - // MutatorHostClient implementation. bool IsElementInList(ElementId element_id, ElementListType list_type) const override; @@ -615,7 +605,6 @@ TaskGraphRunner* task_graph_runner_; - viz::SurfaceSequenceGenerator surface_sequence_generator_; uint32_t num_consecutive_frames_without_slow_paths_ = 0; scoped_refptr<Layer> root_layer_;
diff --git a/chrome/android/java/DEPS b/chrome/android/java/DEPS index 12478ec..44a304f 100644 --- a/chrome/android/java/DEPS +++ b/chrome/android/java/DEPS
@@ -18,7 +18,6 @@ "-content/public/android", "+content/public/android/java/src/org/chromium/content_public", - "!content/public/android/java/src/org/chromium/content/app/ContentApplication.java", "!content/public/android/java/src/org/chromium/content/app/ContentChildProcessServiceDelegate.java", "!content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibility.java", "!content/public/android/java/src/org/chromium/content/browser/ActivityContentVideoViewEmbedder.java",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeApplication.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeApplication.java index 8105a3a..3f9e13b7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeApplication.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeApplication.java
@@ -9,6 +9,7 @@ import org.chromium.base.ActivityState; import org.chromium.base.ApplicationStatus; +import org.chromium.base.BaseChromiumApplication; import org.chromium.base.CommandLineInitUtil; import org.chromium.base.ContextUtils; import org.chromium.base.DiscardableReferencePool; @@ -29,14 +30,13 @@ import org.chromium.chrome.browser.tabmodel.document.DocumentTabModelSelector; import org.chromium.chrome.browser.tabmodel.document.StorageDelegate; import org.chromium.chrome.browser.tabmodel.document.TabDelegate; -import org.chromium.content.app.ContentApplication; /** * Basic application functionality that should be shared among all browser applications that use * chrome layer. */ @MainDex -public class ChromeApplication extends ContentApplication { +public class ChromeApplication extends BaseChromiumApplication { public static final String COMMAND_LINE_FILE = "chrome-command-line"; private static final String TAG = "ChromiumApplication";
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 8e62617..b305cd2 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
@@ -33,8 +33,6 @@ import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.metrics.RecordHistogram; import org.chromium.chrome.R; -import org.chromium.chrome.browser.PasswordManagerHandler.PasswordListObserver; -import org.chromium.chrome.browser.PasswordUIView; import org.chromium.chrome.browser.sync.ProfileSyncService; import org.chromium.chrome.browser.widget.TintedImageButton; import org.chromium.components.sync.AndroidSyncSettings; @@ -207,7 +205,8 @@ // Delete was clicked. private void removeItem() { - final PasswordListObserver passwordDeleter = new PasswordListObserver() { + final PasswordManagerHandler.PasswordListObserver + passwordDeleter = new PasswordManagerHandler.PasswordListObserver() { @Override public void passwordListAvailable(int count) { if (!mException) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/PasswordManagerHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordManagerHandler.java similarity index 80% rename from chrome/android/java/src/org/chromium/chrome/browser/PasswordManagerHandler.java rename to chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordManagerHandler.java index 2860dd3..abbdbba 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/PasswordManagerHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordManagerHandler.java
@@ -2,7 +2,7 @@ // 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; +package org.chromium.chrome.browser.preferences.password; import org.chromium.base.Callback; @@ -15,7 +15,7 @@ * An interface which a client can use to listen to changes to password and password exception * lists. */ - public interface PasswordListObserver { + interface PasswordListObserver { /** * Called when passwords list is updated. * @param count Number of entries in the password list. @@ -32,7 +32,7 @@ /** * Called to start fetching password and exception lists. */ - public void updatePasswordLists(); + void updatePasswordLists(); /** * Get the saved password entry at index. @@ -40,7 +40,7 @@ * @param index Index of Password. * @return SavedPasswordEntry at index. */ - public SavedPasswordEntry getSavedPasswordEntry(int index); + SavedPasswordEntry getSavedPasswordEntry(int index); /** * Get saved password exception at index. @@ -48,26 +48,26 @@ * @param index of exception * @return Origin of password exception. */ - public String getSavedPasswordException(int index); + String getSavedPasswordException(int index); /** * Remove saved password entry at index. * * @param index of password entry to remove. */ - public void removeSavedPasswordEntry(int index); + void removeSavedPasswordEntry(int index); /** * Remove saved exception entry at index. * * @param index of exception entry. */ - public void removeSavedPasswordException(int index); + void removeSavedPasswordException(int index); /** * Trigger serializing the saved passwords in the background. * * @param callback is called on completion, with the serialized passwords as argument. */ - public void serializePasswords(Callback<String> callback); + void serializePasswords(Callback<String> callback); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordManagerHandlerProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordManagerHandlerProvider.java index 52341247..0e2da16 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordManagerHandlerProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordManagerHandlerProvider.java
@@ -7,8 +7,6 @@ import org.chromium.base.ObserverList; import org.chromium.base.ThreadUtils; import org.chromium.base.VisibleForTesting; -import org.chromium.chrome.browser.PasswordManagerHandler; -import org.chromium.chrome.browser.PasswordUIView; /** * A provider for PasswordManagerHandler implementations, handling the choice of the proper one
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/PasswordUIView.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordUIView.java similarity index 92% rename from chrome/android/java/src/org/chromium/chrome/browser/PasswordUIView.java rename to chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordUIView.java index 57972ed..76fa6a1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/PasswordUIView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/PasswordUIView.java
@@ -2,7 +2,7 @@ // 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; +package org.chromium.chrome.browser.preferences.password; import org.chromium.base.Callback; import org.chromium.base.annotations.CalledByNative; @@ -102,16 +102,14 @@ private native SavedPasswordEntry nativeGetSavedPasswordEntry( long nativePasswordUIViewAndroid, int index); - private native String nativeGetSavedPasswordException(long nativePasswordUIViewAndroid, - int index); + private native String nativeGetSavedPasswordException( + long nativePasswordUIViewAndroid, int index); private native void nativeHandleRemoveSavedPasswordEntry( - long nativePasswordUIViewAndroid, - int index); + long nativePasswordUIViewAndroid, int index); private native void nativeHandleRemoveSavedPasswordException( - long nativePasswordUIViewAndroid, - int index); + long nativePasswordUIViewAndroid, int index); private static native String nativeGetAccountDashboardURL();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferences.java index 8811486..3699689 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferences.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferences.java
@@ -24,9 +24,6 @@ import org.chromium.base.Callback; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeFeatureList; -import org.chromium.chrome.browser.PasswordManagerHandler; -import org.chromium.chrome.browser.PasswordUIView; -import org.chromium.chrome.browser.SavedPasswordEntry; import org.chromium.chrome.browser.preferences.ChromeBaseCheckBoxPreference; import org.chromium.chrome.browser.preferences.ChromeBasePreference; import org.chromium.chrome.browser.preferences.ChromeSwitchPreference;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/SavedPasswordEntry.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/SavedPasswordEntry.java similarity index 95% rename from chrome/android/java/src/org/chromium/chrome/browser/SavedPasswordEntry.java rename to chrome/android/java/src/org/chromium/chrome/browser/preferences/password/SavedPasswordEntry.java index 032ba7d..932359f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/SavedPasswordEntry.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/password/SavedPasswordEntry.java
@@ -2,7 +2,7 @@ // 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; +package org.chromium.chrome.browser.preferences.password; /** * A class representing information about a saved password entry in Chrome's settngs.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataPreferences.java index 45ad652..7d86fae8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataPreferences.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataPreferences.java
@@ -404,7 +404,7 @@ if (MultiWindowUtils.isActivityVisible(getActivity()) && getSelectedOptions().contains(DialogOption.CLEAR_HISTORY) && mIsDialogAboutOtherFormsOfBrowsingHistoryEnabled - && !OtherFormsOfHistoryDialogFragment.wasDialogShown(getActivity())) { + && !OtherFormsOfHistoryDialogFragment.wasDialogShown()) { mDialogAboutOtherFormsOfBrowsingHistory = new OtherFormsOfHistoryDialogFragment(); mDialogAboutOtherFormsOfBrowsingHistory.show(getActivity()); dismissProgressDialog(); @@ -500,7 +500,8 @@ mDialogOpened = SystemClock.elapsedRealtime(); mMaxImportantSites = BrowsingDataBridge.getMaxImportantSites(); - BrowsingDataBridge.getInstance().requestInfoAboutOtherFormsOfBrowsingHistory(this); + if (!OtherFormsOfHistoryDialogFragment.wasDialogShown()) + BrowsingDataBridge.getInstance().requestInfoAboutOtherFormsOfBrowsingHistory(this); getActivity().setTitle(R.string.clear_browsing_data_title); PreferenceUtils.addPreferencesFromResource(this, getPreferenceXmlId()); DialogOption[] options = getDialogOptions();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/OtherFormsOfHistoryDialogFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/OtherFormsOfHistoryDialogFragment.java index e419f431..1424678 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/OtherFormsOfHistoryDialogFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/OtherFormsOfHistoryDialogFragment.java
@@ -7,7 +7,6 @@ import android.app.Activity; import android.app.Dialog; import android.app.DialogFragment; -import android.content.Context; import android.content.DialogInterface; import android.content.SharedPreferences; import android.os.Bundle; @@ -109,7 +108,7 @@ /** * @return Whether the dialog has already been shown to the user before. */ - static boolean wasDialogShown(Context context) { + static boolean wasDialogShown() { return ContextUtils.getAppSharedPreferences().getBoolean( PREF_OTHER_FORMS_OF_HISTORY_DIALOG_SHOWN, false); }
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index 6fbc269c..447b586 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -55,11 +55,8 @@ "java/src/org/chromium/chrome/browser/NativePageHost.java", "java/src/org/chromium/chrome/browser/NavigationPopup.java", "java/src/org/chromium/chrome/browser/NearOomMonitor.java", - "java/src/org/chromium/chrome/browser/PasswordManagerHandler.java", - "java/src/org/chromium/chrome/browser/PasswordUIView.java", "java/src/org/chromium/chrome/browser/PowerBroadcastReceiver.java", "java/src/org/chromium/chrome/browser/RepostFormWarningDialog.java", - "java/src/org/chromium/chrome/browser/SavedPasswordEntry.java", "java/src/org/chromium/chrome/browser/SearchGeolocationDisclosureTabHelper.java", "java/src/org/chromium/chrome/browser/ServiceTabLauncher.java", "java/src/org/chromium/chrome/browser/SingleTabActivity.java", @@ -984,9 +981,12 @@ "java/src/org/chromium/chrome/browser/preferences/languages/LanguageListPreference.java", "java/src/org/chromium/chrome/browser/preferences/password/ExportWarningDialogFragment.java", "java/src/org/chromium/chrome/browser/preferences/password/PasswordEntryEditor.java", + "java/src/org/chromium/chrome/browser/preferences/password/PasswordManagerHandler.java", "java/src/org/chromium/chrome/browser/preferences/password/PasswordManagerHandlerProvider.java", "java/src/org/chromium/chrome/browser/preferences/password/PasswordReauthenticationFragment.java", + "java/src/org/chromium/chrome/browser/preferences/password/PasswordUIView.java", "java/src/org/chromium/chrome/browser/preferences/password/ReauthenticationManager.java", + "java/src/org/chromium/chrome/browser/preferences/password/SavedPasswordEntry.java", "java/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferences.java", "java/src/org/chromium/chrome/browser/preferences/privacy/BandwidthType.java", "java/src/org/chromium/chrome/browser/preferences/privacy/BrowsingDataBridge.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadTestRule.java b/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadTestRule.java index f00ff8c8..ead6545 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadTestRule.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadTestRule.java
@@ -22,7 +22,6 @@ import org.chromium.base.test.util.CallbackHelper; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.test.ChromeActivityTestRule; -import org.chromium.content.browser.test.util.ApplicationUtils; import java.io.File; import java.io.FileInputStream; @@ -212,7 +211,6 @@ cleanUpAllDownloads(); - ApplicationUtils.waitForLibraryDependencies(InstrumentationRegistry.getInstrumentation()); final Context context = InstrumentationRegistry.getTargetContext().getApplicationContext(); ThreadUtils.runOnUiThreadBlocking(() -> {
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 8d056bc..10bd6a8 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
@@ -35,8 +35,6 @@ import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.Feature; import org.chromium.chrome.R; -import org.chromium.chrome.browser.PasswordManagerHandler; -import org.chromium.chrome.browser.SavedPasswordEntry; import org.chromium.chrome.browser.preferences.ChromeBaseCheckBoxPreference; import org.chromium.chrome.browser.preferences.ChromeSwitchPreference; import org.chromium.chrome.browser.preferences.PrefServiceBridge;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/UndoTabModelTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/UndoTabModelTest.java index 290e532..f4d53d9 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/UndoTabModelTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/UndoTabModelTest.java
@@ -116,9 +116,8 @@ }); } - private void closeTabOnUiThread( - final TabModel model, final Tab tab, final boolean undoable) - throws InterruptedException { + private void closeTabOnUiThread(final TabModel model, final Tab tab, final boolean undoable) + throws InterruptedException, TimeoutException { // Check preconditions. Assert.assertFalse(tab.isClosing()); Assert.assertTrue(tab.isInitialized()); @@ -144,13 +143,7 @@ boolean didUndo = undoable && model.supportsPendingClosures(); // Make sure the TabModel throws a tabPendingClosure callback if necessary. - if (didUndo) { - try { - didReceivePendingClosureHelper.waitForCallback(0); - } catch (TimeoutException e) { - Assert.fail(); - } - } + if (didUndo) didReceivePendingClosureHelper.waitForCallback(0); // Check post conditions Assert.assertEquals(didUndo, model.isClosurePending(tab.getId())); @@ -178,7 +171,7 @@ } private void cancelTabClosureOnUiThread(final TabModel model, final Tab tab) - throws InterruptedException { + throws InterruptedException, TimeoutException { // Check preconditions. Assert.assertTrue(tab.isClosing()); Assert.assertTrue(tab.isInitialized()); @@ -202,11 +195,7 @@ }); // Make sure the TabModel throws a tabClosureUndone. - try { - didReceiveClosureCancelledHelper.waitForCallback(0); - } catch (TimeoutException e) { - Assert.fail(); - } + didReceiveClosureCancelledHelper.waitForCallback(0); // Check post conditions. Assert.assertFalse(model.isClosurePending(tab.getId())); @@ -216,7 +205,7 @@ } private void cancelAllTabClosuresOnUiThread(final TabModel model, final Tab[] expectedToClose) - throws InterruptedException { + throws InterruptedException, TimeoutException { final CallbackHelper tabClosureUndoneHelper = new CallbackHelper(); for (int i = 0; i < expectedToClose.length; i++) { @@ -245,11 +234,7 @@ } }); - try { - tabClosureUndoneHelper.waitForCallback(0, expectedToClose.length); - } catch (TimeoutException e) { - Assert.fail(); - } + tabClosureUndoneHelper.waitForCallback(0, expectedToClose.length); for (int i = 0; i < expectedToClose.length; i++) { final Tab tab = expectedToClose[i]; @@ -261,7 +246,7 @@ } private void commitTabClosureOnUiThread(final TabModel model, final Tab tab) - throws InterruptedException { + throws InterruptedException, TimeoutException { // Check preconditions. Assert.assertTrue(tab.isClosing()); Assert.assertTrue(tab.isInitialized()); @@ -285,11 +270,7 @@ }); // Make sure the TabModel throws a tabClosureCommitted. - try { - didReceiveClosureCommittedHelper.waitForCallback(0); - } catch (TimeoutException e) { - Assert.fail(); - } + didReceiveClosureCommittedHelper.waitForCallback(0); // Check post conditions Assert.assertFalse(model.isClosurePending(tab.getId())); @@ -299,7 +280,7 @@ } private void commitAllTabClosuresOnUiThread(final TabModel model, Tab[] expectedToClose) - throws InterruptedException { + throws InterruptedException, TimeoutException { final CallbackHelper tabClosureCommittedHelper = new CallbackHelper(); for (int i = 0; i < expectedToClose.length; i++) { @@ -324,11 +305,7 @@ } }); - try { - tabClosureCommittedHelper.waitForCallback(0, expectedToClose.length); - } catch (TimeoutException e) { - Assert.fail(); - } + tabClosureCommittedHelper.waitForCallback(0, expectedToClose.length); for (int i = 0; i < expectedToClose.length; i++) { final Tab tab = expectedToClose[i]; Assert.assertTrue(tab.isClosing()); @@ -396,7 +373,7 @@ @Test @MediumTest @RetryOnFailure - public void testSingleTab() throws InterruptedException { + public void testSingleTab() throws InterruptedException, TimeoutException { TabModel model = mActivityTestRule.getActivity().getTabModelSelector().getModel(false); ChromeTabCreator tabCreator = mActivityTestRule.getActivity().getTabCreator(false); @@ -490,7 +467,7 @@ // Flaky on tablets, crbug.com/620014. @Restriction(UiRestriction.RESTRICTION_TYPE_PHONE) @RetryOnFailure - public void testTwoTabs() throws InterruptedException { + public void testTwoTabs() throws InterruptedException, TimeoutException { TabModel model = mActivityTestRule.getActivity().getTabModelSelector().getModel(false); ChromeTabCreator tabCreator = mActivityTestRule.getActivity().getTabCreator(false); createTabOnUiThread(tabCreator); @@ -639,7 +616,7 @@ @Test @MediumTest @RetryOnFailure - public void testInOrderRestore() throws InterruptedException { + public void testInOrderRestore() throws InterruptedException, TimeoutException { TabModel model = mActivityTestRule.getActivity().getTabModelSelector().getModel(false); ChromeTabCreator tabCreator = mActivityTestRule.getActivity().getTabCreator(false); createTabOnUiThread(tabCreator); @@ -800,7 +777,7 @@ @Test @MediumTest @Restriction(UiRestriction.RESTRICTION_TYPE_PHONE) // See crbug.com/633607 - public void testReverseOrderRestore() throws InterruptedException { + public void testReverseOrderRestore() throws InterruptedException, TimeoutException { TabModel model = mActivityTestRule.getActivity().getTabModelSelector().getModel(false); ChromeTabCreator tabCreator = mActivityTestRule.getActivity().getTabCreator(false); createTabOnUiThread(tabCreator); @@ -953,7 +930,7 @@ @Test @MediumTest @RetryOnFailure - public void testOutOfOrder1() throws InterruptedException { + public void testOutOfOrder1() throws InterruptedException, TimeoutException { TabModel model = mActivityTestRule.getActivity().getTabModelSelector().getModel(false); ChromeTabCreator tabCreator = mActivityTestRule.getActivity().getTabCreator(false); createTabOnUiThread(tabCreator); @@ -1070,7 +1047,7 @@ @Test @MediumTest @FlakyTest(message = "crbug.com/592969") - public void testOutOfOrder2() throws InterruptedException { + public void testOutOfOrder2() throws InterruptedException, TimeoutException { TabModel model = mActivityTestRule.getActivity().getTabModelSelector().getModel(false); ChromeTabCreator tabCreator = mActivityTestRule.getActivity().getTabCreator(false); createTabOnUiThread(tabCreator); @@ -1168,7 +1145,7 @@ @Test @MediumTest @DisabledTest(message = "crbug.com/633607") - public void testCloseAll() throws InterruptedException { + public void testCloseAll() throws InterruptedException, TimeoutException { TabModel model = mActivityTestRule.getActivity().getTabModelSelector().getModel(false); ChromeTabCreator tabCreator = mActivityTestRule.getActivity().getTabCreator(false); createTabOnUiThread(tabCreator); @@ -1243,7 +1220,7 @@ */ @Test @MediumTest - public void testCloseTab() throws InterruptedException { + public void testCloseTab() throws InterruptedException, TimeoutException { TabModel model = mActivityTestRule.getActivity().getTabModelSelector().getModel(false); ChromeTabCreator tabCreator = mActivityTestRule.getActivity().getTabCreator(false); createTabOnUiThread(tabCreator); @@ -1291,7 +1268,7 @@ @Test @MediumTest @RetryOnFailure - public void testMoveTab() throws InterruptedException { + public void testMoveTab() throws InterruptedException, TimeoutException { TabModel model = mActivityTestRule.getActivity().getTabModelSelector().getModel(false); ChromeTabCreator tabCreator = mActivityTestRule.getActivity().getTabCreator(false); createTabOnUiThread(tabCreator); @@ -1344,7 +1321,7 @@ // Disabled due to flakiness on linux_android_rel_ng (crbug.com/661429) @Test @DisabledTest - public void testAddTab() throws InterruptedException { + public void testAddTab() throws InterruptedException, TimeoutException { TabModel model = mActivityTestRule.getActivity().getTabModelSelector().getModel(false); ChromeTabCreator tabCreator = mActivityTestRule.getActivity().getTabCreator(false); createTabOnUiThread(tabCreator); @@ -1418,7 +1395,7 @@ @Test @MediumTest @RetryOnFailure - public void testUndoNotSupported() throws InterruptedException { + public void testUndoNotSupported() throws InterruptedException, TimeoutException { TabModel model = mActivityTestRule.getActivity().getTabModelSelector().getModel(true); ChromeTabCreator tabCreator = mActivityTestRule.getActivity().getTabCreator(true); createTabOnUiThread(tabCreator); @@ -1465,7 +1442,7 @@ @Test @MediumTest @Restriction(UiRestriction.RESTRICTION_TYPE_PHONE) // See crbug.com/633607 - public void testSaveStateCommitsUndos() throws InterruptedException { + public void testSaveStateCommitsUndos() throws InterruptedException, TimeoutException { TabModelSelector selector = mActivityTestRule.getActivity().getTabModelSelector(); TabModel model = selector.getModel(false); ChromeTabCreator tabCreator = mActivityTestRule.getActivity().getTabCreator(false); @@ -1498,7 +1475,7 @@ @Test @MediumTest @RetryOnFailure - public void testOpenRecentlyClosedTab() throws InterruptedException { + public void testOpenRecentlyClosedTab() throws InterruptedException, TimeoutException { TabModelSelector selector = mActivityTestRule.getActivity().getTabModelSelector(); TabModel model = selector.getModel(false); ChromeTabCreator tabCreator = mActivityTestRule.getActivity().getTabCreator(false); @@ -1523,7 +1500,7 @@ */ @Test @MediumTest - public void testOpenRecentlyClosedTabNative() throws InterruptedException { + public void testOpenRecentlyClosedTabNative() throws InterruptedException, TimeoutException { final TabModelSelector selector = mActivityTestRule.getActivity().getTabModelSelector(); final TabModel model = selector.getModel(false); @@ -1569,7 +1546,8 @@ @MinAndroidSdkLevel(24) @TargetApi(Build.VERSION_CODES.LOLLIPOP) @CommandLineFlags.Add(ChromeSwitches.DISABLE_TAB_MERGING_FOR_TESTING) - public void testOpenRecentlyClosedTabMultiWindow() throws InterruptedException { + public void testOpenRecentlyClosedTabMultiWindow() + throws InterruptedException, TimeoutException { final ChromeTabbedActivity2 secondActivity = MultiWindowTestHelper.createSecondChromeTabbedActivity( mActivityTestRule.getActivity()); @@ -1650,7 +1628,8 @@ @MinAndroidSdkLevel(24) @TargetApi(Build.VERSION_CODES.LOLLIPOP) @CommandLineFlags.Add(ChromeSwitches.DISABLE_TAB_MERGING_FOR_TESTING) - public void testOpenRecentlyClosedTabMultiWindowFallback() throws InterruptedException { + public void testOpenRecentlyClosedTabMultiWindowFallback() + throws InterruptedException, TimeoutException { final ChromeTabbedActivity2 secondActivity = MultiWindowTestHelper.createSecondChromeTabbedActivity( mActivityTestRule.getActivity()); @@ -1683,7 +1662,7 @@ try { closedCallback.waitForCallback(0); } catch (TimeoutException | InterruptedException e) { - Assert.fail("Failed to close the tab on the second window."); + throw new AssertionError("Failed to close the tab on the second window.", e); } Assert.assertEquals("Window 2 should have 1 tab.", 1, secondModel.getCount());
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 8fbc3229..59cc684 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -11068,9 +11068,12 @@ <message name="IDS_VR_BUTTON_TRACKPAD" desc="The label for the trackpad on the VR controller."> Scroll / Click </message> - <message name="IDS_VR_BUTTON_EXIT" desc="The label for the exit button on the VR controller."> + <message name="IDS_VR_BUTTON_EXIT" desc="The label for the exit button on the VR controller -- shown when in fullscreen mode."> Exit Fullscreen </message> + <message name="IDS_VR_BUTTON_BACK" desc="The label for the back button on the VR controller -- shown when the keyboard is visible."> + Back + </message> </if> </messages> </release>
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index d9b6063..d2bac0e2 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -4182,7 +4182,6 @@ "../android/java/src/org/chromium/chrome/browser/IntentHelper.java", "../android/java/src/org/chromium/chrome/browser/JavascriptAppModalDialog.java", "../android/java/src/org/chromium/chrome/browser/NearOomMonitor.java", - "../android/java/src/org/chromium/chrome/browser/PasswordUIView.java", "../android/java/src/org/chromium/chrome/browser/SSLClientCertificateRequest.java", "../android/java/src/org/chromium/chrome/browser/SearchGeolocationDisclosureTabHelper.java", "../android/java/src/org/chromium/chrome/browser/ServiceTabLauncher.java", @@ -4351,6 +4350,7 @@ "../android/java/src/org/chromium/chrome/browser/preferences/PrefServiceBridge.java", "../android/java/src/org/chromium/chrome/browser/preferences/PreferencesLauncher.java", "../android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillProfileBridge.java", + "../android/java/src/org/chromium/chrome/browser/preferences/password/PasswordUIView.java", "../android/java/src/org/chromium/chrome/browser/preferences/privacy/BrowsingDataBridge.java", "../android/java/src/org/chromium/chrome/browser/preferences/privacy/BrowsingDataCounterBridge.java", "../android/java/src/org/chromium/chrome/browser/preferences/website/WebsitePreferenceBridge.java",
diff --git a/chrome/browser/browsing_data/browsing_data_flash_lso_helper.cc b/chrome/browser/browsing_data/browsing_data_flash_lso_helper.cc index a71ca51..ffd081e 100644 --- a/chrome/browser/browsing_data/browsing_data_flash_lso_helper.cc +++ b/chrome/browser/browsing_data/browsing_data_flash_lso_helper.cc
@@ -24,9 +24,9 @@ content::BrowserContext* browser_context); // BrowsingDataFlashLSOHelper implementation: - void StartFetching(const GetSitesWithFlashDataCallback& callback) override; + void StartFetching(GetSitesWithFlashDataCallback callback) override; void DeleteFlashLSOsForSite(const std::string& site, - const base::Closure& callback) override; + base::OnceClosure callback) override; // PepperFlashSettingsManager::Client overrides: void OnGetSitesWithDataCompleted( @@ -37,11 +37,11 @@ private: struct DeleteFlashLSOTask { DeleteFlashLSOTask() {} - DeleteFlashLSOTask(const std::string& site, const base::Closure& callback) - : site(site), callback(callback) {} + DeleteFlashLSOTask(const std::string& site, base::OnceClosure callback) + : site(site), callback(std::move(callback)) {} std::string site; - base::Closure callback; + base::OnceClosure callback; }; ~BrowsingDataFlashLSOHelperImpl() override; @@ -73,26 +73,26 @@ } void BrowsingDataFlashLSOHelperImpl::StartFetching( - const GetSitesWithFlashDataCallback& callback) { + GetSitesWithFlashDataCallback callback) { DCHECK(callback_.is_null()); - callback_ = callback; + callback_ = std::move(callback); get_sites_with_data_request_id_ = settings_manager_.GetSitesWithData(); } void BrowsingDataFlashLSOHelperImpl::DeleteFlashLSOsForSite( - const std::string& site, const base::Closure& callback) { + const std::string& site, + base::OnceClosure callback) { const uint64_t kClearAllData = 0; uint32_t id = settings_manager_.ClearSiteData( site, kClearAllData, std::numeric_limits<uint64_t>::max()); - clear_site_data_ids_[id] = DeleteFlashLSOTask(site, callback); + clear_site_data_ids_[id] = DeleteFlashLSOTask(site, std::move(callback)); } void BrowsingDataFlashLSOHelperImpl::OnGetSitesWithDataCompleted( uint32_t request_id, const std::vector<std::string>& sites) { DCHECK_EQ(get_sites_with_data_request_id_, request_id); - callback_.Run(sites); - callback_ = GetSitesWithFlashDataCallback(); + std::move(callback_).Run(sites); } void BrowsingDataFlashLSOHelperImpl::OnClearSiteDataCompleted( @@ -104,7 +104,7 @@ LOG_IF(ERROR, !success) << "Couldn't clear Flash LSO data for " << entry->second.site; if (!entry->second.callback.is_null()) - entry->second.callback.Run(); + std::move(entry->second.callback).Run(); clear_site_data_ids_.erase(entry); }
diff --git a/chrome/browser/browsing_data/browsing_data_flash_lso_helper.h b/chrome/browser/browsing_data/browsing_data_flash_lso_helper.h index 3922c44b..40ba100d 100644 --- a/chrome/browser/browsing_data/browsing_data_flash_lso_helper.h +++ b/chrome/browser/browsing_data/browsing_data_flash_lso_helper.h
@@ -20,15 +20,15 @@ class BrowsingDataFlashLSOHelper : public base::RefCounted<BrowsingDataFlashLSOHelper> { public: - typedef base::Callback<void(const std::vector<std::string>&)> + typedef base::OnceCallback<void(const std::vector<std::string>&)> GetSitesWithFlashDataCallback; static BrowsingDataFlashLSOHelper* Create( content::BrowserContext* browser_context); - virtual void StartFetching(const GetSitesWithFlashDataCallback& callback) = 0; + virtual void StartFetching(GetSitesWithFlashDataCallback callback) = 0; virtual void DeleteFlashLSOsForSite(const std::string& site, - const base::Closure& callback) = 0; + base::OnceClosure callback) = 0; protected: friend class base::RefCounted<BrowsingDataFlashLSOHelper>;
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc index 763af68..2da8e1f 100644 --- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc +++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
@@ -11,7 +11,9 @@ #include <utility> #include <vector> +#include "base/barrier_closure.h" #include "base/callback.h" +#include "base/callback_helpers.h" #include "base/metrics/user_metrics.h" #include "base/task_scheduler/post_task.h" #include "build/build_config.h" @@ -136,33 +138,33 @@ namespace { -void UIThreadTrampolineHelper(const base::Closure& callback) { - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback); +void UIThreadTrampolineHelper(base::OnceClosure callback) { + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, std::move(callback)); } // Convenience method to create a callback that can be run on any thread and // will post the given |callback| back to the UI thread. -base::Closure UIThreadTrampoline(const base::Closure& callback) { +base::OnceClosure UIThreadTrampoline(base::OnceClosure callback) { // We could directly bind &BrowserThread::PostTask, but that would require // evaluating FROM_HERE when this method is called, as opposed to when the // task is actually posted. - return base::Bind(&UIThreadTrampolineHelper, callback); + return base::BindOnce(&UIThreadTrampolineHelper, std::move(callback)); } template <typename T> -void IgnoreArgumentHelper(const base::Closure& callback, T unused_argument) { - callback.Run(); +void IgnoreArgumentHelper(base::OnceClosure callback, T unused_argument) { + std::move(callback).Run(); } // Another convenience method to turn a callback without arguments into one that // accepts (and ignores) a single argument. template <typename T> -base::Callback<void(T)> IgnoreArgument(const base::Closure& callback) { - return base::Bind(&IgnoreArgumentHelper<T>, callback); +base::OnceCallback<void(T)> IgnoreArgument(base::OnceClosure callback) { + return base::BindOnce(&IgnoreArgumentHelper<T>, std::move(callback)); } bool WebsiteSettingsFilterAdapter( - const base::Callback<bool(const GURL&)> predicate, + const base::RepeatingCallback<bool(const GURL&)> predicate, const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern) { // Ignore the default setting. @@ -198,12 +200,14 @@ void ClearCookiesOnIOThread(base::Time delete_begin, base::Time delete_end, net::URLRequestContextGetter* rq_context, - const base::Closure& callback) { + base::OnceClosure callback) { DCHECK_CURRENTLY_ON(BrowserThread::IO); net::CookieStore* cookie_store = rq_context->GetURLRequestContext()->cookie_store(); cookie_store->DeleteAllCreatedBetweenAsync( - delete_begin, delete_end, IgnoreArgument<uint32_t>(callback)); + delete_begin, delete_end, + base::AdaptCallbackForRepeating( + IgnoreArgument<uint32_t>(std::move(callback)))); } void ClearCookiesWithPredicateOnIOThread( @@ -211,12 +215,14 @@ base::Time delete_end, net::CookieStore::CookiePredicate predicate, net::URLRequestContextGetter* rq_context, - const base::Closure& callback) { + base::OnceClosure callback) { DCHECK_CURRENTLY_ON(BrowserThread::IO); net::CookieStore* cookie_store = rq_context->GetURLRequestContext()->cookie_store(); cookie_store->DeleteAllCreatedBetweenWithPredicateAsync( - delete_begin, delete_end, predicate, IgnoreArgument<uint32_t>(callback)); + delete_begin, delete_end, predicate, + base::AdaptCallbackForRepeating( + IgnoreArgument<uint32_t>(std::move(callback)))); } void ClearNetworkPredictorOnIOThread(chrome_browser_net::Predictor* predictor) { @@ -229,7 +235,7 @@ void ClearHostnameResolutionCacheOnIOThread( IOThread* io_thread, - base::Callback<bool(const std::string&)> host_filter) { + base::RepeatingCallback<bool(const std::string&)> host_filter) { DCHECK_CURRENTLY_ON(BrowserThread::IO); io_thread->ClearHostCache(host_filter); @@ -252,7 +258,7 @@ void ClearReportingCacheOnIOThread( net::URLRequestContextGetter* context, int data_type_mask, - const base::Callback<bool(const GURL&)>& origin_filter) { + const base::RepeatingCallback<bool(const GURL&)>& origin_filter) { DCHECK_CURRENTLY_ON(BrowserThread::IO); net::ReportingService* service = @@ -311,70 +317,9 @@ } // namespace -ChromeBrowsingDataRemoverDelegate::SubTask::SubTask( - const base::Closure& forward_callback) - : is_pending_(false), - forward_callback_(forward_callback), - weak_ptr_factory_(this) { - DCHECK(!forward_callback_.is_null()); -} - -ChromeBrowsingDataRemoverDelegate::SubTask::~SubTask() {} - -void ChromeBrowsingDataRemoverDelegate::SubTask::Start() { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - DCHECK(!is_pending_); - is_pending_ = true; -} - -base::Closure -ChromeBrowsingDataRemoverDelegate::SubTask::GetCompletionCallback() { - return base::Bind(&SubTask::CompletionCallback, - weak_ptr_factory_.GetWeakPtr()); -} - -void ChromeBrowsingDataRemoverDelegate::SubTask::CompletionCallback() { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - DCHECK(is_pending_); - is_pending_ = false; - forward_callback_.Run(); -} - ChromeBrowsingDataRemoverDelegate::ChromeBrowsingDataRemoverDelegate( BrowserContext* browser_context) : profile_(Profile::FromBrowserContext(browser_context)), - sub_task_forward_callback_( - base::Bind(&ChromeBrowsingDataRemoverDelegate::NotifyIfDone, - base::Unretained(this))), - synchronous_clear_operations_(sub_task_forward_callback_), - clear_autofill_origin_urls_(sub_task_forward_callback_), - clear_flash_content_licenses_(sub_task_forward_callback_), - clear_media_drm_licenses_(sub_task_forward_callback_), - clear_domain_reliability_monitor_(sub_task_forward_callback_), - clear_form_(sub_task_forward_callback_), - clear_history_(sub_task_forward_callback_), - clear_keyword_data_(sub_task_forward_callback_), -#if BUILDFLAG(ENABLE_NACL) - clear_nacl_cache_(sub_task_forward_callback_), - clear_pnacl_cache_(sub_task_forward_callback_), -#endif - clear_hostname_resolution_cache_(sub_task_forward_callback_), - clear_network_predictor_(sub_task_forward_callback_), - clear_passwords_(sub_task_forward_callback_), - clear_passwords_stats_(sub_task_forward_callback_), - clear_http_auth_cache_(sub_task_forward_callback_), - clear_platform_keys_(sub_task_forward_callback_), -#if defined(OS_ANDROID) - clear_precache_history_(sub_task_forward_callback_), - clear_offline_page_data_(sub_task_forward_callback_), -#endif -#if BUILDFLAG(ENABLE_WEBRTC) - clear_webrtc_logs_(sub_task_forward_callback_), -#endif - clear_auto_sign_in_(sub_task_forward_callback_), - clear_reporting_cache_(sub_task_forward_callback_), - clear_network_error_logging_(sub_task_forward_callback_), - clear_video_perf_history_(sub_task_forward_callback_), #if BUILDFLAG(ENABLE_PLUGINS) flash_lso_helper_(BrowsingDataFlashLSOHelper::Create(browser_context)), #endif @@ -392,7 +337,7 @@ content::BrowsingDataRemoverDelegate::EmbedderOriginTypeMatcher ChromeBrowsingDataRemoverDelegate::GetOriginTypeMatcher() const { - return base::Bind(&DoesOriginMatchEmbedderMask); + return base::BindRepeating(&DoesOriginMatchEmbedderMask); } bool ChromeBrowsingDataRemoverDelegate::MayRemoveDownloadHistory() const { @@ -447,20 +392,22 @@ ////////////////////////////////////////////////////////////////////////////// // INITIALIZATION - synchronous_clear_operations_.Start(); + base::ScopedClosureRunner synchronous_clear_operations( + CreatePendingTaskCompletionClosure()); callback_ = std::move(callback); delete_begin_ = delete_begin; delete_end_ = delete_end; - base::Callback<bool(const GURL& url)> filter = + base::RepeatingCallback<bool(const GURL& url)> filter = filter_builder.BuildGeneralFilter(); // Some backends support a filter that |is_null()| to make complete deletion // more efficient. - base::Callback<bool(const GURL&)> nullable_filter = - filter_builder.IsEmptyBlacklist() ? base::Callback<bool(const GURL&)>() - : filter; + base::RepeatingCallback<bool(const GURL&)> nullable_filter = + filter_builder.IsEmptyBlacklist() + ? base::RepeatingCallback<bool(const GURL&)>() + : filter; // Managed devices and supervised users can have restrictions on history // deletion. @@ -487,11 +434,10 @@ if (history_service) { // TODO(dmurph): Support all backends with filter (crbug.com/113621). base::RecordAction(UserMetricsAction("ClearBrowsingData_History")); - clear_history_.Start(); history_service->ExpireLocalAndRemoteHistoryBetween( WebHistoryServiceFactory::GetForProfile(profile_), std::set<GURL>(), delete_begin_, delete_end_, - clear_history_.GetCompletionCallback(), + base::AdaptCallbackForRepeating(CreatePendingTaskCompletionClosure()), &history_task_tracker_); } if (ClipboardRecentContent::GetInstance()) @@ -546,22 +492,20 @@ // as the hostname resolution cache, key their entries by hostname. Rename // BuildPluginFilter() to something more general to reflect this use. if (g_browser_process->io_thread()) { - clear_hostname_resolution_cache_.Start(); BrowserThread::PostTaskAndReply( BrowserThread::IO, FROM_HERE, base::BindOnce(&ClearHostnameResolutionCacheOnIOThread, g_browser_process->io_thread(), filter_builder.BuildPluginFilter()), - clear_hostname_resolution_cache_.GetCompletionCallback()); + CreatePendingTaskCompletionClosure()); } if (profile_->GetNetworkPredictor()) { // TODO(dmurph): Support all backends with filter (crbug.com/113621). - clear_network_predictor_.Start(); BrowserThread::PostTaskAndReply( BrowserThread::IO, FROM_HERE, base::BindOnce(&ClearNetworkPredictorOnIOThread, profile_->GetNetworkPredictor()), - clear_network_predictor_.GetCompletionCallback()); + CreatePendingTaskCompletionClosure()); profile_->GetNetworkPredictor()->ClearPrefsOnUIThread(); } @@ -573,10 +517,11 @@ // TODO(msramek): Store filters from the currently executed task on the // object to avoid having to copy them to callback methods. template_url_sub_ = keywords_model->RegisterOnLoadedCallback( - base::Bind(&ChromeBrowsingDataRemoverDelegate::OnKeywordsLoaded, - weak_ptr_factory_.GetWeakPtr(), filter)); + base::AdaptCallbackForRepeating(base::BindOnce( + &ChromeBrowsingDataRemoverDelegate::OnKeywordsLoaded, + weak_ptr_factory_.GetWeakPtr(), filter, + CreatePendingTaskCompletionClosure()))); keywords_model->Load(); - clear_keyword_data_.Start(); } else if (keywords_model) { keywords_model->RemoveAutoGeneratedForUrlsBetween(filter, delete_begin_, delete_end_); @@ -624,13 +569,12 @@ WebDataServiceFactory::GetAutofillWebDataForProfile( profile_, ServiceAccessType::EXPLICIT_ACCESS); if (web_data_service.get()) { - clear_autofill_origin_urls_.Start(); web_data_service->RemoveOriginURLsModifiedBetween( delete_begin_, delete_end_); // Ask for a call back when the above call is finished. web_data_service->GetDBTaskRunner()->PostTaskAndReply( FROM_HERE, base::BindOnce(&base::DoNothing), - clear_autofill_origin_urls_.GetCompletionCallback()); + CreatePendingTaskCompletionClosure()); autofill::PersonalDataManager* data_manager = autofill::PersonalDataManagerFactory::GetForProfile(profile_); @@ -639,7 +583,6 @@ } #if BUILDFLAG(ENABLE_WEBRTC) - clear_webrtc_logs_.Start(); base::PostTaskWithTraitsAndReply( FROM_HERE, {base::TaskPriority::USER_VISIBLE, base::MayBlock()}, base::BindOnce( @@ -647,15 +590,14 @@ webrtc_logging::LogList::GetWebRtcLogDirectoryForBrowserContextPath( profile_->GetPath()), delete_begin_), - clear_webrtc_logs_.GetCompletionCallback()); + CreatePendingTaskCompletionClosure()); #endif #if defined(OS_ANDROID) - clear_precache_history_.Start(); base::PostTaskWithTraitsAndReply( FROM_HERE, {base::TaskPriority::USER_VISIBLE, base::MayBlock()}, base::BindOnce(&ClearPrecacheInBackground, profile_), - clear_precache_history_.GetCompletionCallback()); + CreatePendingTaskCompletionClosure()); // Clear the history information (last launch time and origin URL) of any // registered webapps. @@ -700,7 +642,7 @@ if (profile_->GetSSLHostStateDelegate()) { profile_->GetSSLHostStateDelegate()->Clear( filter_builder.IsEmptyBlacklist() - ? base::Callback<bool(const std::string&)>() + ? base::RepeatingCallback<bool(const std::string&)>() : filter_builder.BuildPluginFilter()); } @@ -713,9 +655,8 @@ media::VideoDecodePerfHistory* video_decode_perf_history = profile_->GetVideoDecodePerfHistory(); if (video_decode_perf_history) { - clear_video_perf_history_.Start(); video_decode_perf_history->ClearHistory( - clear_video_perf_history_.GetCompletionCallback()); + CreatePendingTaskCompletionClosure()); } } } @@ -743,7 +684,7 @@ host_content_settings_map_->ClearSettingsForOneTypeWithPredicate( CONTENT_SETTINGS_TYPE_CLIENT_HINTS, base::Time(), - base::Bind(&WebsiteSettingsFilterAdapter, filter)); + base::BindRepeating(&WebsiteSettingsFilterAdapter, filter)); // Clear the safebrowsing cookies only if time period is for "all time". It // doesn't make sense to apply the time period of deleting in the last X @@ -755,16 +696,17 @@ if (sb_service) { scoped_refptr<net::URLRequestContextGetter> sb_context = sb_service->url_request_context(); - ++clear_cookies_count_; + if (filter_builder.IsEmptyBlacklist()) { BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, base::BindOnce( &ClearCookiesOnIOThread, delete_begin_, delete_end_, base::RetainedRef(std::move(sb_context)), - UIThreadTrampoline(base::Bind( + UIThreadTrampoline(base::BindOnce( &ChromeBrowsingDataRemoverDelegate::OnClearedCookies, - weak_ptr_factory_.GetWeakPtr())))); + weak_ptr_factory_.GetWeakPtr(), + CreatePendingTaskCompletionClosure())))); } else { BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, @@ -772,9 +714,10 @@ &ClearCookiesWithPredicateOnIOThread, delete_begin_, delete_end_, filter_builder.BuildCookieFilter(), base::RetainedRef(std::move(sb_context)), - UIThreadTrampoline(base::Bind( + UIThreadTrampoline(base::BindOnce( &ChromeBrowsingDataRemoverDelegate::OnClearedCookies, - weak_ptr_factory_.GetWeakPtr())))); + weak_ptr_factory_.GetWeakPtr(), + CreatePendingTaskCompletionClosure())))); } } } @@ -810,7 +753,7 @@ if (remove_mask & DATA_TYPE_DURABLE_PERMISSION) { host_content_settings_map_->ClearSettingsForOneTypeWithPredicate( CONTENT_SETTINGS_TYPE_DURABLE_STORAGE, base::Time(), - base::Bind(&WebsiteSettingsFilterAdapter, filter)); + base::BindRepeating(&WebsiteSettingsFilterAdapter, filter)); } ////////////////////////////////////////////////////////////////////////////// @@ -820,7 +763,7 @@ host_content_settings_map_->ClearSettingsForOneTypeWithPredicate( CONTENT_SETTINGS_TYPE_SITE_ENGAGEMENT, base::Time(), - base::Bind(&WebsiteSettingsFilterAdapter, filter)); + base::BindRepeating(&WebsiteSettingsFilterAdapter, filter)); if (MediaEngagementService::IsEnabled()) { MediaEngagementService::Get(profile_)->ClearDataBetweenTime(delete_begin_, @@ -832,7 +775,7 @@ (remove_mask & DATA_TYPE_HISTORY)) { host_content_settings_map_->ClearSettingsForOneTypeWithPredicate( CONTENT_SETTINGS_TYPE_APP_BANNER, base::Time(), - base::Bind(&WebsiteSettingsFilterAdapter, filter)); + base::BindRepeating(&WebsiteSettingsFilterAdapter, filter)); PermissionDecisionAutoBlocker::GetForProfile(profile_)->RemoveCountsByUrl( filter); @@ -847,21 +790,20 @@ profile_, ServiceAccessType::EXPLICIT_ACCESS).get(); if (password_store) { - clear_passwords_.Start(); password_store->RemoveLoginsByURLAndTime( filter, delete_begin_, delete_end_, - clear_passwords_.GetCompletionCallback()); + base::AdaptCallbackForRepeating( + CreatePendingTaskCompletionClosure())); } scoped_refptr<net::URLRequestContextGetter> request_context = BrowserContext::GetDefaultStoragePartition(profile_) ->GetURLRequestContext(); - clear_http_auth_cache_.Start(); BrowserThread::PostTaskAndReply( BrowserThread::IO, FROM_HERE, base::BindOnce(&ClearHttpAuthCacheOnIOThread, std::move(request_context), delete_begin_), - clear_http_auth_cache_.GetCompletionCallback()); + CreatePendingTaskCompletionClosure()); } if (remove_mask & content::BrowsingDataRemover::DATA_TYPE_COOKIES) { @@ -871,9 +813,9 @@ .get(); if (password_store) { - clear_auto_sign_in_.Start(); password_store->DisableAutoSignInForOrigins( - filter, clear_auto_sign_in_.GetCompletionCallback()); + filter, base::AdaptCallbackForRepeating( + CreatePendingTaskCompletionClosure())); } } @@ -883,10 +825,10 @@ profile_, ServiceAccessType::EXPLICIT_ACCESS).get(); if (password_store) { - clear_passwords_stats_.Start(); password_store->RemoveStatisticsByOriginAndTime( nullable_filter, delete_begin_, delete_end_, - clear_passwords_stats_.GetCompletionCallback()); + base::AdaptCallbackForRepeating( + CreatePendingTaskCompletionClosure())); } } @@ -900,7 +842,6 @@ profile_, ServiceAccessType::EXPLICIT_ACCESS); if (web_data_service.get()) { - clear_form_.Start(); web_data_service->RemoveFormElementsAddedBetween(delete_begin_, delete_end_); web_data_service->RemoveAutofillDataModifiedBetween( @@ -908,7 +849,7 @@ // Ask for a call back when the above calls are finished. web_data_service->GetDBTaskRunner()->PostTaskAndReply( FROM_HERE, base::BindOnce(&base::DoNothing), - clear_form_.GetCompletionCallback()); + CreatePendingTaskCompletionClosure()); autofill::PersonalDataManager* data_manager = autofill::PersonalDataManagerFactory::GetForProfile(profile_); @@ -929,20 +870,16 @@ web_cache::WebCacheManager::GetInstance()->ClearCache(); #if BUILDFLAG(ENABLE_NACL) - clear_nacl_cache_.Start(); - BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::BindOnce( - &ClearNaClCacheOnIOThread, - UIThreadTrampoline(clear_nacl_cache_.GetCompletionCallback()))); - - clear_pnacl_cache_.Start(); + base::BindOnce(&ClearNaClCacheOnIOThread, + base::AdaptCallbackForRepeating(UIThreadTrampoline( + CreatePendingTaskCompletionClosure())))); BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::BindOnce( - &ClearPnaclCacheOnIOThread, delete_begin_, delete_end_, - UIThreadTrampoline(clear_pnacl_cache_.GetCompletionCallback()))); + base::BindOnce(&ClearPnaclCacheOnIOThread, delete_begin_, delete_end_, + base::AdaptCallbackForRepeating(UIThreadTrampoline( + CreatePendingTaskCompletionClosure())))); #endif // The PrerenderManager may have a page actively being prerendered, which @@ -977,12 +914,13 @@ // For now we're considering offline pages as cache, so if we're removing // cache we should remove offline pages as well. if ((remove_mask & content::BrowsingDataRemover::DATA_TYPE_CACHE)) { - clear_offline_page_data_.Start(); offline_pages::OfflinePageModelFactory::GetForBrowserContext(profile_) ->DeleteCachedPagesByURLPredicate( filter, - IgnoreArgument<offline_pages::OfflinePageModel::DeletePageResult>( - clear_offline_page_data_.GetCompletionCallback())); + base::AdaptCallbackForRepeating( + IgnoreArgument< + offline_pages::OfflinePageModel::DeletePageResult>( + CreatePendingTaskCompletionClosure()))); } #endif } @@ -1004,7 +942,6 @@ (origin_type_mask & content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB)) { base::RecordAction(UserMetricsAction("ClearBrowsingData_LSOData")); - clear_plugin_data_count_ = 1; if (filter_builder.IsEmptyBlacklist()) { DCHECK(!plugin_data_remover_); @@ -1016,16 +953,19 @@ base::WaitableEventWatcher::EventCallback watcher_callback = base::BindOnce( &ChromeBrowsingDataRemoverDelegate::OnWaitableEventSignaled, - weak_ptr_factory_.GetWeakPtr()); + weak_ptr_factory_.GetWeakPtr(), + CreatePendingTaskCompletionClosure()); watcher_.StartWatching(event, std::move(watcher_callback), base::SequencedTaskRunnerHandle::Get()); } else { // TODO(msramek): Store filters from the currently executed task on the // object to avoid having to copy them to callback methods. - flash_lso_helper_->StartFetching(base::Bind( - &ChromeBrowsingDataRemoverDelegate::OnSitesWithFlashDataFetched, - weak_ptr_factory_.GetWeakPtr(), - filter_builder.BuildPluginFilter())); + flash_lso_helper_->StartFetching( + base::AdaptCallbackForRepeating(base::BindOnce( + &ChromeBrowsingDataRemoverDelegate::OnSitesWithFlashDataFetched, + weak_ptr_factory_.GetWeakPtr(), + filter_builder.BuildPluginFilter(), + CreatePendingTaskCompletionClosure()))); } } #endif @@ -1038,7 +978,8 @@ base::RecordAction(UserMetricsAction("ClearBrowsingData_ContentLicenses")); #if BUILDFLAG(ENABLE_PLUGINS) - clear_flash_content_licenses_.Start(); + // Will be completed in OnDeauthorizeFlashContentLicensesCompleted() + num_pending_tasks_ += 1; if (!pepper_flash_settings_manager_.get()) { pepper_flash_settings_manager_.reset( new PepperFlashSettingsManager(this, profile_)); @@ -1054,7 +995,6 @@ if (!user) { LOG(WARNING) << "Failed to find user for current profile."; } else { - clear_platform_keys_.Start(); chromeos::DBusThreadManager::Get() ->GetCryptohomeClient() ->TpmAttestationDeleteKeys( @@ -1063,14 +1003,14 @@ chromeos::attestation::kContentProtectionKeyPrefix, base::BindOnce( &ChromeBrowsingDataRemoverDelegate::OnClearPlatformKeys, - weak_ptr_factory_.GetWeakPtr())); + weak_ptr_factory_.GetWeakPtr(), + CreatePendingTaskCompletionClosure())); } #endif // defined(OS_CHROMEOS) #if defined(OS_ANDROID) - clear_media_drm_licenses_.Start(); ClearMediaDrmLicenses(prefs, delete_begin_, delete_end, filter, - clear_media_drm_licenses_.GetCompletionCallback()); + CreatePendingTaskCompletionClosure()); #endif // defined(OS_ANDROID); } @@ -1098,11 +1038,9 @@ else mode = domain_reliability::CLEAR_BEACONS; - clear_domain_reliability_monitor_.Start(); - service->ClearBrowsingData( - mode, - filter, - clear_domain_reliability_monitor_.GetCompletionCallback()); + service->ClearBrowsingData(mode, filter, + base::AdaptCallbackForRepeating( + CreatePendingTaskCompletionClosure())); } } @@ -1117,13 +1055,12 @@ if (remove_mask & content::BrowsingDataRemover::DATA_TYPE_COOKIES) data_type_mask |= net::ReportingBrowsingDataRemover::DATA_TYPE_CLIENTS; - clear_reporting_cache_.Start(); BrowserThread::PostTaskAndReply( BrowserThread::IO, FROM_HERE, base::BindOnce(&ClearReportingCacheOnIOThread, base::RetainedRef(std::move(context)), data_type_mask, filter), - UIThreadTrampoline(clear_reporting_cache_.GetCompletionCallback())); + UIThreadTrampoline(CreatePendingTaskCompletionClosure())); } if ((remove_mask & content::BrowsingDataRemover::DATA_TYPE_COOKIES) || @@ -1131,13 +1068,11 @@ scoped_refptr<net::URLRequestContextGetter> context = profile_->GetRequestContext(); - clear_network_error_logging_.Start(); BrowserThread::PostTaskAndReply( BrowserThread::IO, FROM_HERE, base::BindOnce(&ClearNetworkErrorLoggingOnIOThread, base::RetainedRef(std::move(context)), filter), - UIThreadTrampoline( - clear_network_error_logging_.GetCompletionCallback())); + UIThreadTrampoline(CreatePendingTaskCompletionClosure())); } ////////////////////////////////////////////////////////////////////////////// // DATA_TYPE_WEB_APP_DATA @@ -1151,46 +1086,26 @@ // Remove external protocol data. if (remove_mask & DATA_TYPE_EXTERNAL_PROTOCOL_DATA) ExternalProtocolHandler::ClearData(profile_); - - synchronous_clear_operations_.GetCompletionCallback().Run(); } -void ChromeBrowsingDataRemoverDelegate::NotifyIfDone() { - if (!AllDone()) +void ChromeBrowsingDataRemoverDelegate::OnTaskComplete() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + DCHECK_GT(num_pending_tasks_, 0); + num_pending_tasks_--; + + if (num_pending_tasks_) return; DCHECK(!callback_.is_null()); std::move(callback_).Run(); } -bool ChromeBrowsingDataRemoverDelegate::AllDone() { - return !clear_cookies_count_ && !synchronous_clear_operations_.is_pending() && - !clear_autofill_origin_urls_.is_pending() && - !clear_flash_content_licenses_.is_pending() && - !clear_media_drm_licenses_.is_pending() && - !clear_domain_reliability_monitor_.is_pending() && - !clear_form_.is_pending() && !clear_history_.is_pending() && - !clear_hostname_resolution_cache_.is_pending() && - !clear_keyword_data_.is_pending() && -#if BUILDFLAG(ENABLE_NACL) - !clear_nacl_cache_.is_pending() && !clear_pnacl_cache_.is_pending() && -#endif - !clear_network_predictor_.is_pending() && - !clear_passwords_.is_pending() && - !clear_passwords_stats_.is_pending() && - !clear_http_auth_cache_.is_pending() && - !clear_platform_keys_.is_pending() && -#if defined(OS_ANDROID) - !clear_precache_history_.is_pending() && - !clear_offline_page_data_.is_pending() && -#endif -#if BUILDFLAG(ENABLE_WEBRTC) - !clear_webrtc_logs_.is_pending() && -#endif - !clear_auto_sign_in_.is_pending() && - !clear_reporting_cache_.is_pending() && - !clear_network_error_logging_.is_pending() && - !clear_video_perf_history_.is_pending() && !clear_plugin_data_count_; +base::OnceClosure +ChromeBrowsingDataRemoverDelegate::CreatePendingTaskCompletionClosure() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + num_pending_tasks_++; + return base::BindOnce(&ChromeBrowsingDataRemoverDelegate::OnTaskComplete, + weak_ptr_factory_.GetWeakPtr()); } #if defined(OS_ANDROID) @@ -1208,80 +1123,65 @@ #endif void ChromeBrowsingDataRemoverDelegate::OnKeywordsLoaded( - base::Callback<bool(const GURL&)> url_filter) { + base::RepeatingCallback<bool(const GURL&)> url_filter, + base::OnceClosure done) { // Deletes the entries from the model. TemplateURLService* model = TemplateURLServiceFactory::GetForProfile(profile_); model->RemoveAutoGeneratedForUrlsBetween(url_filter, delete_begin_, delete_end_); template_url_sub_.reset(); - clear_keyword_data_.GetCompletionCallback().Run(); + std::move(done).Run(); } -void ChromeBrowsingDataRemoverDelegate::OnClearedCookies() { +void ChromeBrowsingDataRemoverDelegate::OnClearedCookies( + base::OnceClosure done) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - - DCHECK_GT(clear_cookies_count_, 0); - --clear_cookies_count_; - NotifyIfDone(); + std::move(done).Run(); } #if defined(OS_CHROMEOS) void ChromeBrowsingDataRemoverDelegate::OnClearPlatformKeys( + base::OnceClosure done, base::Optional<bool> result) { LOG_IF(ERROR, !result.has_value() || !result.value()) << "Failed to clear platform keys."; - clear_platform_keys_.GetCompletionCallback().Run(); + std::move(done).Run(); } #endif #if BUILDFLAG(ENABLE_PLUGINS) void ChromeBrowsingDataRemoverDelegate::OnWaitableEventSignaled( + base::OnceClosure done, base::WaitableEvent* waitable_event) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - - DCHECK_EQ(1, clear_plugin_data_count_); - clear_plugin_data_count_ = 0; - plugin_data_remover_.reset(); watcher_.StopWatching(); - NotifyIfDone(); + std::move(done).Run(); } void ChromeBrowsingDataRemoverDelegate::OnSitesWithFlashDataFetched( - base::Callback<bool(const std::string&)> plugin_filter, + base::RepeatingCallback<bool(const std::string&)> plugin_filter, + base::OnceClosure done, const std::vector<std::string>& sites) { - DCHECK_EQ(1, clear_plugin_data_count_); - clear_plugin_data_count_ = 0; - std::vector<std::string> sites_to_delete; for (const std::string& site : sites) { if (plugin_filter.Run(site)) sites_to_delete.push_back(site); } - clear_plugin_data_count_ = sites_to_delete.size(); + base::RepeatingClosure barrier = + base::BarrierClosure(sites_to_delete.size(), std::move(done)); for (const std::string& site : sites_to_delete) { - flash_lso_helper_->DeleteFlashLSOsForSite( - site, - base::Bind(&ChromeBrowsingDataRemoverDelegate::OnFlashDataDeleted, - weak_ptr_factory_.GetWeakPtr())); + flash_lso_helper_->DeleteFlashLSOsForSite(site, barrier); } - - NotifyIfDone(); -} - -void ChromeBrowsingDataRemoverDelegate::OnFlashDataDeleted() { - clear_plugin_data_count_--; - NotifyIfDone(); } void ChromeBrowsingDataRemoverDelegate:: -OnDeauthorizeFlashContentLicensesCompleted( - uint32_t request_id, - bool /* success */) { + OnDeauthorizeFlashContentLicensesCompleted(uint32_t request_id, + bool /* success */) { DCHECK_EQ(request_id, deauthorize_flash_content_licenses_request_id_); - clear_flash_content_licenses_.GetCompletionCallback().Run(); + OnTaskComplete(); } #endif
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.h b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.h index 57f7227..617b2f93 100644 --- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.h +++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.h
@@ -147,32 +147,6 @@ static_assert((IMPORTANT_SITES_DATA_TYPES & ~FILTERABLE_DATA_TYPES) == 0, "All important sites datatypes must be filterable."); - // Used to track the deletion of a single data storage backend. - class SubTask { - public: - // Creates a SubTask that calls |forward_callback| when completed. - // |forward_callback| is only kept as a reference and must outlive SubTask. - explicit SubTask(const base::Closure& forward_callback); - ~SubTask(); - - // Indicate that the task is in progress and we're waiting. - void Start(); - - // Returns a callback that should be called to indicate that the task - // has been finished. - base::Closure GetCompletionCallback(); - - // Whether the task is still in progress. - bool is_pending() const { return is_pending_; } - - private: - void CompletionCallback(); - - bool is_pending_; - const base::Closure& forward_callback_; - base::WeakPtrFactory<SubTask> weak_ptr_factory_; - }; - ChromeBrowsingDataRemoverDelegate(content::BrowserContext* browser_context); ~ChromeBrowsingDataRemoverDelegate() override; @@ -203,30 +177,36 @@ #endif private: - // If AllDone(), calls the callback provided in RemoveEmbedderData(). - void NotifyIfDone(); + // Called by the closures returned by CreatePendingTaskCompletionClosure(). + // Checks if all tasks have completed, and if so, calls callback_. + void OnTaskComplete(); - // Whether there are no running deletion tasks. - bool AllDone(); + // Increments the number of pending tasks by one, and returns a OnceClosure + // that calls OnTaskComplete(). The Remover is complete once all the closures + // created by this method have been invoked. + base::OnceClosure CreatePendingTaskCompletionClosure(); // Callback for when TemplateURLService has finished loading. Clears the data, // clears the respective waiting flag, and invokes NotifyIfDone. - void OnKeywordsLoaded(base::Callback<bool(const GURL&)> url_filter); + void OnKeywordsLoaded(base::RepeatingCallback<bool(const GURL&)> url_filter, + base::OnceClosure done); #if defined (OS_CHROMEOS) - void OnClearPlatformKeys(base::Optional<bool> result); + void OnClearPlatformKeys(base::OnceClosure done, base::Optional<bool> result); #endif // Callback for when cookies have been deleted. Invokes NotifyIfDone. - void OnClearedCookies(); + void OnClearedCookies(base::OnceClosure done); #if BUILDFLAG(ENABLE_PLUGINS) // Called when plugin data has been cleared. Invokes NotifyIfDone. - void OnWaitableEventSignaled(base::WaitableEvent* waitable_event); + void OnWaitableEventSignaled(base::OnceClosure done, + base::WaitableEvent* waitable_event); // Called when the list of |sites| storing Flash LSO cookies is fetched. void OnSitesWithFlashDataFetched( - base::Callback<bool(const std::string&)> plugin_filter, + base::RepeatingCallback<bool(const std::string&)> plugin_filter, + base::OnceClosure done, const std::vector<std::string>& sites); // Indicates that LSO cookies for one website have been deleted. @@ -249,44 +229,8 @@ // Completion callback to call when all data are deleted. base::OnceClosure callback_; - // A callback to NotifyIfDone() used by SubTasks instances. - const base::Closure sub_task_forward_callback_; - - // Keeping track of various subtasks to be completed. - // Non-zero if waiting for SafeBrowsing cookies to be cleared. - int clear_cookies_count_ = 0; - SubTask synchronous_clear_operations_; - SubTask clear_autofill_origin_urls_; - SubTask clear_flash_content_licenses_; - SubTask clear_media_drm_licenses_; - SubTask clear_domain_reliability_monitor_; - SubTask clear_form_; - SubTask clear_history_; - SubTask clear_keyword_data_; -#if BUILDFLAG(ENABLE_NACL) - SubTask clear_nacl_cache_; - SubTask clear_pnacl_cache_; -#endif - SubTask clear_hostname_resolution_cache_; - SubTask clear_network_predictor_; - SubTask clear_passwords_; - SubTask clear_passwords_stats_; - SubTask clear_http_auth_cache_; - SubTask clear_platform_keys_; -#if defined(OS_ANDROID) - SubTask clear_precache_history_; - SubTask clear_offline_page_data_; -#endif -#if BUILDFLAG(ENABLE_WEBRTC) - SubTask clear_webrtc_logs_; -#endif - SubTask clear_auto_sign_in_; - SubTask clear_reporting_cache_; - SubTask clear_network_error_logging_; - SubTask clear_video_perf_history_; - // Counts the number of plugin data tasks. Should be the number of LSO cookies - // to be deleted, or 1 while we're fetching LSO cookies or deleting in bulk. - int clear_plugin_data_count_ = 0; + // Keeps track of number of tasks to be completed. + int num_pending_tasks_ = 0; #if BUILDFLAG(ENABLE_PLUGINS) // Used to delete plugin data.
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc index 06e1787..d4b6bcc 100644 --- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc +++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
@@ -82,7 +82,6 @@ #include "net/cookies/cookie_store.h" #include "net/http/http_transaction_factory.h" #include "net/reporting/reporting_browsing_data_remover.h" -#include "net/reporting/reporting_policy.h" #include "net/reporting/reporting_service.h" #include "net/url_request/network_error_logging_delegate.h" #include "net/url_request/url_request_context.h" @@ -693,8 +692,8 @@ explicit TestBrowsingDataFlashLSOHelper(TestingProfile* profile) : MockBrowsingDataFlashLSOHelper(profile) {} - void StartFetching(const GetSitesWithFlashDataCallback& callback) override { - MockBrowsingDataFlashLSOHelper::StartFetching(callback); + void StartFetching(GetSitesWithFlashDataCallback callback) override { + MockBrowsingDataFlashLSOHelper::StartFetching(std::move(callback)); Notify(); } @@ -951,12 +950,6 @@ return true; } - const net::ReportingPolicy& GetPolicy() const override { - static net::ReportingPolicy dummy_policy_; - NOTREACHED(); - return dummy_policy_; - } - int remove_calls() const { return remove_calls_; } int last_data_type_mask() const { return last_data_type_mask_; } const base::RepeatingCallback<bool(const GURL&)>& last_origin_filter() const {
diff --git a/chrome/browser/browsing_data/mock_browsing_data_flash_lso_helper.cc b/chrome/browser/browsing_data/mock_browsing_data_flash_lso_helper.cc index 8bf64f1..0d88320 100644 --- a/chrome/browser/browsing_data/mock_browsing_data_flash_lso_helper.cc +++ b/chrome/browser/browsing_data/mock_browsing_data_flash_lso_helper.cc
@@ -12,20 +12,21 @@ content::BrowserContext* browser_context) { } void MockBrowsingDataFlashLSOHelper::StartFetching( - const GetSitesWithFlashDataCallback& callback) { + GetSitesWithFlashDataCallback callback) { ASSERT_FALSE(callback.is_null()); ASSERT_TRUE(callback_.is_null()); - callback_ = callback; + callback_ = std::move(callback); } void MockBrowsingDataFlashLSOHelper::DeleteFlashLSOsForSite( - const std::string& site, const base::Closure& callback) { + const std::string& site, + base::OnceClosure callback) { std::vector<std::string>::iterator entry = std::find(domains_.begin(), domains_.end(), site); ASSERT_TRUE(entry != domains_.end()); domains_.erase(entry); if (!callback.is_null()) - callback.Run(); + std::move(callback).Run(); } void MockBrowsingDataFlashLSOHelper::AddFlashLSODomain( @@ -34,7 +35,7 @@ } void MockBrowsingDataFlashLSOHelper::Notify() { - callback_.Run(domains_); + std::move(callback_).Run(domains_); callback_ = GetSitesWithFlashDataCallback(); }
diff --git a/chrome/browser/browsing_data/mock_browsing_data_flash_lso_helper.h b/chrome/browser/browsing_data/mock_browsing_data_flash_lso_helper.h index 2257e20..5a533a29 100644 --- a/chrome/browser/browsing_data/mock_browsing_data_flash_lso_helper.h +++ b/chrome/browser/browsing_data/mock_browsing_data_flash_lso_helper.h
@@ -18,9 +18,9 @@ content::BrowserContext* browser_context); // BrowsingDataFlashLSOHelper implementation: - void StartFetching(const GetSitesWithFlashDataCallback& callback) override; + void StartFetching(GetSitesWithFlashDataCallback callback) override; void DeleteFlashLSOsForSite(const std::string& site, - const base::Closure& callback) override; + base::OnceClosure callback) override; // Adds a domain sample. void AddFlashLSODomain(const std::string& domain);
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index b03f9b6..e52ed15b 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -425,6 +425,8 @@ "arc/process/arc_process.h", "arc/process/arc_process_service.cc", "arc/process/arc_process_service.h", + "arc/screen_capture/arc_screen_capture_bridge.cc", + "arc/screen_capture/arc_screen_capture_bridge.h", "arc/tracing/arc_tracing_bridge.cc", "arc/tracing/arc_tracing_bridge.h", "arc/tts/arc_tts_service.cc",
diff --git a/chrome/browser/chromeos/arc/arc_service_launcher.cc b/chrome/browser/chromeos/arc/arc_service_launcher.cc index b18e4139..ec96a75 100644 --- a/chrome/browser/chromeos/arc/arc_service_launcher.cc +++ b/chrome/browser/chromeos/arc/arc_service_launcher.cc
@@ -30,6 +30,7 @@ #include "chrome/browser/chromeos/arc/policy/arc_policy_util.h" #include "chrome/browser/chromeos/arc/print/arc_print_service.h" #include "chrome/browser/chromeos/arc/process/arc_process_service.h" +#include "chrome/browser/chromeos/arc/screen_capture/arc_screen_capture_bridge.h" #include "chrome/browser/chromeos/arc/tracing/arc_tracing_bridge.h" #include "chrome/browser/chromeos/arc/tts/arc_tts_service.h" #include "chrome/browser/chromeos/arc/user_session/arc_user_session_service.h" @@ -161,6 +162,7 @@ ArcProcessService::GetForBrowserContext(profile); ArcProvisionNotificationService::GetForBrowserContext(profile); ArcRotationLockBridge::GetForBrowserContext(profile); + ArcScreenCaptureBridge::GetForBrowserContext(profile); ArcSettingsService::GetForBrowserContext(profile); ArcTracingBridge::GetForBrowserContext(profile); ArcTtsService::GetForBrowserContext(profile);
diff --git a/chrome/browser/chromeos/arc/screen_capture/arc_screen_capture_bridge.cc b/chrome/browser/chromeos/arc/screen_capture/arc_screen_capture_bridge.cc new file mode 100644 index 0000000..12478bd9 --- /dev/null +++ b/chrome/browser/chromeos/arc/screen_capture/arc_screen_capture_bridge.cc
@@ -0,0 +1,66 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/arc/screen_capture/arc_screen_capture_bridge.h" + +#include "base/memory/singleton.h" +#include "components/arc/arc_bridge_service.h" +#include "components/arc/arc_browser_context_keyed_service_factory_base.h" + +namespace arc { +namespace { + +// Singleton factory for ArcScreenCaptureBridge +class ArcScreenCaptureBridgeFactory + : public internal::ArcBrowserContextKeyedServiceFactoryBase< + ArcScreenCaptureBridge, + ArcScreenCaptureBridgeFactory> { + public: + // Factory name used by ArcBrowserContextKeyedServiceFactoryBase. + static constexpr const char* kName = "ArcScreenCaptureBridgeFactory"; + + static ArcScreenCaptureBridgeFactory* GetInstance() { + return base::Singleton<ArcScreenCaptureBridgeFactory>::get(); + } + + private: + friend base::DefaultSingletonTraits<ArcScreenCaptureBridgeFactory>; + ArcScreenCaptureBridgeFactory() = default; + ~ArcScreenCaptureBridgeFactory() override = default; +}; + +} // namespace + +// static +ArcScreenCaptureBridge* ArcScreenCaptureBridge::GetForBrowserContext( + content::BrowserContext* context) { + return ArcScreenCaptureBridgeFactory::GetForBrowserContext(context); +} + +ArcScreenCaptureBridge::ArcScreenCaptureBridge(content::BrowserContext* context, + ArcBridgeService* bridge_service) + : arc_bridge_service_(bridge_service), weak_factory_(this) { + arc_bridge_service_->screen_capture()->SetHost(this); +} + +ArcScreenCaptureBridge::~ArcScreenCaptureBridge() { + arc_bridge_service_->screen_capture()->SetHost(nullptr); +} + +void ArcScreenCaptureBridge::RequestPermission( + const std::string& display_name, + const std::string& package_name, + RequestPermissionCallback callback) { + NOTREACHED(); +} + +void ArcScreenCaptureBridge::OpenSession( + mojom::ScreenCaptureSessionNotifierPtr notifier, + const std::string& package_name, + const gfx::Size& size, + OpenSessionCallback callback) { + NOTREACHED(); +} + +} // namespace arc
diff --git a/chrome/browser/chromeos/arc/screen_capture/arc_screen_capture_bridge.h b/chrome/browser/chromeos/arc/screen_capture/arc_screen_capture_bridge.h new file mode 100644 index 0000000..617467b8 --- /dev/null +++ b/chrome/browser/chromeos/arc/screen_capture/arc_screen_capture_bridge.h
@@ -0,0 +1,52 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_ARC_SCREEN_CAPTURE_ARC_SCREEN_CAPTURE_BRIDGE_H_ +#define CHROME_BROWSER_CHROMEOS_ARC_SCREEN_CAPTURE_ARC_SCREEN_CAPTURE_BRIDGE_H_ + +#include "base/macros.h" +#include "components/arc/common/screen_capture.mojom.h" +#include "components/keyed_service/core/keyed_service.h" + +namespace content { +class BrowserContext; +} // namespace content + +namespace arc { + +class ArcBridgeService; + +class ArcScreenCaptureBridge : public KeyedService, + public mojom::ScreenCaptureHost { + public: + // Returns singleton instance for the given BrowserContext, + // or nullptr if the browser |context| is not allowed to use ARC. + static ArcScreenCaptureBridge* GetForBrowserContext( + content::BrowserContext* context); + + ArcScreenCaptureBridge(content::BrowserContext* context, + ArcBridgeService* bridge_service); + ~ArcScreenCaptureBridge() override; + + // mojom::ScreenCaptureHost overrides: + void OpenSession(mojom::ScreenCaptureSessionNotifierPtr notifier, + const std::string& package_name, + const gfx::Size& size, + OpenSessionCallback callback) override; + void RequestPermission(const std::string& display_name, + const std::string& package_name, + RequestPermissionCallback callback) override; + + private: + ArcBridgeService* const arc_bridge_service_; // Owned by ArcServiceManager. + + // WeakPtrFactory to use for callbacks. + base::WeakPtrFactory<ArcScreenCaptureBridge> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(ArcScreenCaptureBridge); +}; + +} // namespace arc + +#endif // CHROME_BROWSER_CHROMEOS_ARC_SCREEN_CAPTURE_ARC_SCREEN_CAPTURE_BRIDGE_H_
diff --git a/chrome/browser/chromeos/file_manager/gallery_browsertest.cc b/chrome/browser/chromeos/file_manager/gallery_browsertest.cc index 0c7ee32..bffa077 100644 --- a/chrome/browser/chromeos/file_manager/gallery_browsertest.cc +++ b/chrome/browser/chromeos/file_manager/gallery_browsertest.cc
@@ -150,7 +150,15 @@ StartTest(); } -IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, TraverseSlideThumbnailsOnDrive) { +// http://crbug.com/804364 : Flaky due to crash on linux-chromeos-dbg +#if !defined(NDEBUG) +#define MAYBE_TraverseSlideThumbnailsOnDrive \ + DISABLED_TraverseSlideThumbnailsOnDrive +#else +#define MAYBE_TraverseSlideThumbnailsOnDrive TraverseSlideThumbnailsOnDrive +#endif +IN_PROC_BROWSER_TEST_F(GalleryBrowserTest, + MAYBE_TraverseSlideThumbnailsOnDrive) { set_test_case_name("traverseSlideThumbnailsOnDrive"); StartTest(); }
diff --git a/chrome/browser/download/download_browsertest.cc b/chrome/browser/download/download_browsertest.cc index 0771dc9..6d0b180 100644 --- a/chrome/browser/download/download_browsertest.cc +++ b/chrome/browser/download/download_browsertest.cc
@@ -55,7 +55,6 @@ #include "chrome/browser/history/history_service_factory.h" #include "chrome/browser/infobars/infobar_service.h" #include "chrome/browser/net/url_request_mock_util.h" -#include "chrome/browser/notifications/notification_ui_manager.h" #include "chrome/browser/permissions/permission_request_manager.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/renderer_context_menu/render_view_context_menu_browsertest_util.h" @@ -2087,9 +2086,6 @@ DownloadAndWait(browser(), download_url); - // Close the notifications as they would prevent the browser from quitting. - g_browser_process->notification_ui_manager()->CancelAll(); - content::WindowedNotificationObserver signal( chrome::NOTIFICATION_BROWSER_CLOSED, content::Source<Browser>(browser())); @@ -3075,7 +3071,6 @@ DownloadItem::COMPLETE)); browser()->tab_strip_model()->GetActiveWebContents()->Close(); - g_browser_process->notification_ui_manager()->CancelAll(); } IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadTest_Renaming) {
diff --git a/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl.cc b/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl.cc index a2883146..a8348d7 100644 --- a/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl.cc +++ b/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl.cc
@@ -69,8 +69,8 @@ << " sinks to CastMediaSinkService"; if (dial_sink_added_cb_) { - for (const auto& sink : current_sinks_) - dial_sink_added_cb_.Run(sink); + for (const auto& sink_it : current_sinks_) + dial_sink_added_cb_.Run(sink_it.second); } } @@ -126,7 +126,8 @@ } MediaSinkInternal dial_sink(sink, extra_data); - current_sinks_.insert(dial_sink); + std::string sink_id = dial_sink.sink().id(); + current_sinks_.insert_or_assign(sink_id, dial_sink); if (dial_sink_added_cb_) dial_sink_added_cb_.Run(dial_sink);
diff --git a/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl.h b/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl.h index ff0ca5e..831d917c 100644 --- a/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl.h +++ b/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl.h
@@ -71,6 +71,8 @@ FRIEND_TEST_ALL_PREFIXES(DialMediaSinkServiceImplTest, TestTimer); FRIEND_TEST_ALL_PREFIXES(DialMediaSinkServiceImplTest, TestOnDeviceDescriptionAvailable); + FRIEND_TEST_ALL_PREFIXES(DialMediaSinkServiceImplTest, + TestOnDeviceDescriptionAvailableIPAddressChanged); FRIEND_TEST_ALL_PREFIXES(DialMediaSinkServiceImplTest, TestRestartAfterStop); FRIEND_TEST_ALL_PREFIXES(DialMediaSinkServiceImplTest, OnDialSinkAddedCallback);
diff --git a/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl_unittest.cc b/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl_unittest.cc index 9e014ba..d191ce49 100644 --- a/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl_unittest.cc +++ b/chrome/browser/media/router/discovery/dial/dial_media_sink_service_impl_unittest.cc
@@ -107,6 +107,7 @@ EXPECT_CALL(*mock_description_service_, GetDeviceDescriptions(device_list, _)); + EXPECT_CALL(dial_sink_added_cb_, Run(_)); media_sink_service_->OnDialDeviceEvent(device_list); media_sink_service_->OnDeviceDescriptionAvailable(device_data, device_description); @@ -114,6 +115,38 @@ EXPECT_EQ(1u, media_sink_service_->current_sinks_.size()); } +TEST_F(DialMediaSinkServiceImplTest, + TestOnDeviceDescriptionAvailableIPAddressChanged) { + DialDeviceData device_data("first", GURL("http://127.0.0.1/dd.xml"), + base::Time::Now()); + ParsedDialDeviceDescription device_description; + device_description.model_name = "model name"; + device_description.friendly_name = "friendly name"; + device_description.app_url = GURL("http://192.168.1.1/apps"); + device_description.unique_id = "unique id"; + + std::vector<DialDeviceData> device_list = {device_data}; + EXPECT_CALL(*mock_description_service_, + GetDeviceDescriptions(device_list, _)); + media_sink_service_->OnDialDeviceEvent(device_list); + + EXPECT_CALL(dial_sink_added_cb_, Run(_)); + media_sink_service_->OnDeviceDescriptionAvailable(device_data, + device_description); + EXPECT_EQ(1u, media_sink_service_->current_sinks_.size()); + + EXPECT_CALL(dial_sink_added_cb_, Run(_)); + device_description.app_url = GURL("http://192.168.1.100/apps"); + media_sink_service_->OnDeviceDescriptionAvailable(device_data, + device_description); + + EXPECT_EQ(1u, media_sink_service_->current_sinks_.size()); + for (const auto& dial_sink_it : media_sink_service_->current_sinks_) { + EXPECT_EQ(device_description.app_url, + dial_sink_it.second.dial_data().app_url); + } +} + TEST_F(DialMediaSinkServiceImplTest, TestTimer) { DialDeviceData device_data("first", GURL("http://127.0.0.1/dd.xml"), base::Time::Now()); @@ -128,6 +161,7 @@ GetDeviceDescriptions(device_list, _)); EXPECT_FALSE(mock_timer_->IsRunning()); + EXPECT_CALL(dial_sink_added_cb_, Run(_)); media_sink_service_->OnDialDeviceEvent(device_list); media_sink_service_->OnDeviceDescriptionAvailable(device_data, device_description);
diff --git a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.cc b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.cc index 679ac7d..b3ff166 100644 --- a/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.cc +++ b/chrome/browser/media/router/discovery/mdns/cast_media_sink_service_impl.cc
@@ -256,7 +256,8 @@ << " [name]: " << sink_it.second.sink().name() << " [ip_endpoint]: " << sink_it.second.cast_data().ip_endpoint.ToString(); - current_sinks_.insert(sink_it.second); + std::string sink_id = sink_it.second.sink().id(); + current_sinks_.emplace(sink_id, sink_it.second); } MediaSinkServiceBase::OnDiscoveryComplete();
diff --git a/chrome/browser/metrics/thread_watcher.cc b/chrome/browser/metrics/thread_watcher.cc index 904266f6..6521e76 100644 --- a/chrome/browser/metrics/thread_watcher.cc +++ b/chrome/browser/metrics/thread_watcher.cc
@@ -334,8 +334,9 @@ const int ThreadWatcherList::kUnresponsiveSeconds = 2; // static const int ThreadWatcherList::kUnresponsiveCount = 9; -// static -const int ThreadWatcherList::kLiveThreadsThreshold = 2; +// static, configured high to catch single thread hangs +// TODO(gab): Clean this up, https://crbug.com/804345 +const int ThreadWatcherList::kLiveThreadsThreshold = BrowserThread::ID_COUNT; // static, non-const for tests. int ThreadWatcherList::g_initialize_delay_seconds = 120;
diff --git a/chrome/browser/metrics/ukm_browsertest.cc b/chrome/browser/metrics/ukm_browsertest.cc index 3cd34e8..63c0c46 100644 --- a/chrome/browser/metrics/ukm_browsertest.cc +++ b/chrome/browser/metrics/ukm_browsertest.cc
@@ -249,7 +249,7 @@ } // Make sure that UKM is disabled while an non-sync profile's window is open. -IN_PROC_BROWSER_TEST_F(UkmBrowserTest, NonSyncCheck) { +IN_PROC_BROWSER_TEST_F(UkmBrowserTest, OpenNonSyncCheck) { MetricsConsentOverride metrics_consent(true); Profile* profile = ProfileManager::GetActiveUserProfile(); @@ -491,8 +491,6 @@ CloseBrowserSynchronously(sync_browser); } -// TODO(crbug/745939): Add a tests for disable w/ multiprofiles. - // TODO(crbug/745939): Add a tests for guest profile. // Make sure that pending data is deleted when user deletes history.
diff --git a/chrome/browser/notifications/notification_display_service_impl.cc b/chrome/browser/notifications/notification_display_service_impl.cc index cf8fb8b..7d77fd5a 100644 --- a/chrome/browser/notifications/notification_display_service_impl.cc +++ b/chrome/browser/notifications/notification_display_service_impl.cc
@@ -271,6 +271,31 @@ callback); } +// Callback to run once the profile has been loaded in order to perform a +// given |operation| in a notification. +void NotificationDisplayServiceImpl::ProfileLoadedCallback( + NotificationCommon::Operation operation, + NotificationHandler::Type notification_type, + const GURL& origin, + const std::string& notification_id, + const base::Optional<int>& action_index, + const base::Optional<base::string16>& reply, + const base::Optional<bool>& by_user, + Profile* profile) { + if (!profile) { + // TODO(miguelg): Add UMA for this condition. + // Perhaps propagate this through PersistentNotificationStatus. + LOG(WARNING) << "Profile not loaded correctly"; + return; + } + + NotificationDisplayServiceImpl* display_service = + NotificationDisplayServiceImpl::GetForProfile(profile); + display_service->ProcessNotificationOperation(operation, notification_type, + origin, notification_id, + action_index, reply, by_user); +} + void NotificationDisplayServiceImpl::OnNotificationPlatformBridgeReady( bool success) { if (base::FeatureList::IsEnabled(features::kNativeNotifications)) {
diff --git a/chrome/browser/notifications/notification_display_service_impl.h b/chrome/browser/notifications/notification_display_service_impl.h index 8a8fc6c..c13a7238 100644 --- a/chrome/browser/notifications/notification_display_service_impl.h +++ b/chrome/browser/notifications/notification_display_service_impl.h
@@ -70,6 +70,15 @@ const std::string& notification_id) override; void GetDisplayed(const DisplayedNotificationsCallback& callback) override; + static void ProfileLoadedCallback(NotificationCommon::Operation operation, + NotificationHandler::Type notification_type, + const GURL& origin, + const std::string& notification_id, + const base::Optional<int>& action_index, + const base::Optional<base::string16>& reply, + const base::Optional<bool>& by_user, + Profile* profile); + private: // Called when the NotificationPlatformBridge may have been initialized. void OnNotificationPlatformBridgeReady(bool success);
diff --git a/chrome/browser/notifications/notification_platform_bridge_android.cc b/chrome/browser/notifications/notification_platform_bridge_android.cc index 981bebd..a933acf3 100644 --- a/chrome/browser/notifications/notification_platform_bridge_android.cc +++ b/chrome/browser/notifications/notification_platform_bridge_android.cc
@@ -108,31 +108,6 @@ return ScopedJavaLocalRef<jobjectArray>(env, actions); } -// Callback to run once the profile has been loaded in order to perform a -// given |operation| in a notification. -// TODO(miguelg) move it to notification_common? -void ProfileLoadedCallback(NotificationCommon::Operation operation, - NotificationHandler::Type notification_type, - const GURL& origin, - const std::string& notification_id, - const base::Optional<int>& action_index, - const base::Optional<base::string16>& reply, - const base::Optional<bool>& by_user, - Profile* profile) { - if (!profile) { - // TODO(miguelg): Add UMA for this condition. - // Perhaps propagate this through PersistentNotificationStatus. - LOG(WARNING) << "Profile not loaded correctly"; - return; - } - - NotificationDisplayServiceImpl* display_service = - NotificationDisplayServiceImpl::GetForProfile(profile); - display_service->ProcessNotificationOperation(operation, notification_type, - origin, notification_id, - action_index, reply, by_user); -} - } // namespace // Called by the Java side when a notification event has been received, but the @@ -201,7 +176,8 @@ profile_manager->LoadProfile( profile_id, incognito, - base::Bind(&ProfileLoadedCallback, NotificationCommon::CLICK, + base::Bind(&NotificationDisplayServiceImpl::ProfileLoadedCallback, + NotificationCommon::CLICK, NotificationHandler::Type::WEB_PERSISTENT, origin, notification_id, std::move(action_index), std::move(reply), base::nullopt /* by_user */)); @@ -247,7 +223,8 @@ profile_manager->LoadProfile( profile_id, incognito, - base::Bind(&ProfileLoadedCallback, NotificationCommon::CLOSE, + base::Bind(&NotificationDisplayServiceImpl::ProfileLoadedCallback, + NotificationCommon::CLOSE, NotificationHandler::Type::WEB_PERSISTENT, GURL(ConvertJavaStringToUTF8(env, java_origin)), notification_id, base::nullopt /* action index */,
diff --git a/chrome/browser/notifications/notification_platform_bridge_linux.cc b/chrome/browser/notifications/notification_platform_bridge_linux.cc index e879670..57f933f 100644 --- a/chrome/browser/notifications/notification_platform_bridge_linux.cc +++ b/chrome/browser/notifications/notification_platform_bridge_linux.cc
@@ -170,26 +170,6 @@ height))); } -// Runs once the profile has been loaded in order to perform a given -// |operation| on a notification. -void ProfileLoadedCallback(NotificationCommon::Operation operation, - NotificationHandler::Type notification_type, - const GURL& origin, - const std::string& notification_id, - const base::Optional<int>& action_index, - const base::Optional<base::string16>& reply, - const base::Optional<bool>& by_user, - Profile* profile) { - if (!profile) - return; - - NotificationDisplayServiceImpl* display_service = - NotificationDisplayServiceImpl::GetForProfile(profile); - display_service->ProcessNotificationOperation(operation, notification_type, - origin, notification_id, - action_index, reply, by_user); -} - void ForwardNotificationOperationOnUiThread( NotificationCommon::Operation operation, NotificationHandler::Type notification_type, @@ -202,9 +182,9 @@ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); g_browser_process->profile_manager()->LoadProfile( profile_id, is_incognito, - base::Bind(&ProfileLoadedCallback, operation, notification_type, origin, - notification_id, action_index, base::nullopt /* reply */, - by_user)); + base::Bind(&NotificationDisplayServiceImpl::ProfileLoadedCallback, + operation, notification_type, origin, notification_id, + action_index, base::nullopt /* reply */, by_user)); } class ResourceFile {
diff --git a/chrome/browser/notifications/notification_platform_bridge_mac.mm b/chrome/browser/notifications/notification_platform_bridge_mac.mm index 27424ff..1d4b274c 100644 --- a/chrome/browser/notifications/notification_platform_bridge_mac.mm +++ b/chrome/browser/notifications/notification_platform_bridge_mac.mm
@@ -64,30 +64,6 @@ namespace { -// Callback to run once the profile has been loaded in order to perform a -// given |operation| in a notification. -void ProfileLoadedCallback(NotificationCommon::Operation operation, - NotificationHandler::Type notification_type, - const GURL& origin, - const std::string& notification_id, - const base::Optional<int>& action_index, - const base::Optional<base::string16>& reply, - const base::Optional<bool>& by_user, - Profile* profile) { - if (!profile) { - // TODO(miguelg): Add UMA for this condition. - // Perhaps propagate this through PersistentNotificationStatus. - LOG(WARNING) << "Profile not loaded correctly"; - return; - } - - NotificationDisplayServiceImpl* display_service = - NotificationDisplayServiceImpl::GetForProfile(profile); - display_service->ProcessNotificationOperation(operation, notification_type, - origin, notification_id, - action_index, reply, by_user); -} - // Loads the profile and process the Notification response void DoProcessNotificationResponse(NotificationCommon::Operation operation, NotificationHandler::Type type, @@ -105,8 +81,9 @@ profileManager->LoadProfile( profile_id, incognito, - base::Bind(&ProfileLoadedCallback, operation, type, origin, - notification_id, action_index, reply, by_user)); + base::Bind(&NotificationDisplayServiceImpl::ProfileLoadedCallback, + operation, type, origin, notification_id, action_index, reply, + by_user)); } // This enum backs an UMA histogram, so it should be treated as append-only.
diff --git a/chrome/browser/notifications/notification_platform_bridge_win.cc b/chrome/browser/notifications/notification_platform_bridge_win.cc index 38c0a73..99d286b 100644 --- a/chrome/browser/notifications/notification_platform_bridge_win.cc +++ b/chrome/browser/notifications/notification_platform_bridge_win.cc
@@ -76,25 +76,6 @@ IID_PPV_ARGS(object)); } -// Perform |operation| on a notification once the profile has been loaded. -void ProfileLoadedCallback(NotificationCommon::Operation operation, - NotificationHandler::Type notification_type, - const GURL& origin, - const std::string& notification_id, - const base::Optional<int>& action_index, - const base::Optional<base::string16>& reply, - const base::Optional<bool>& by_user, - Profile* profile) { - if (!profile) - return; - - NotificationDisplayServiceImpl* display_service = - NotificationDisplayServiceImpl::GetForProfile(profile); - display_service->ProcessNotificationOperation(operation, notification_type, - origin, notification_id, - action_index, reply, by_user); -} - void ForwardNotificationOperationOnUiThread( NotificationCommon::Operation operation, NotificationHandler::Type notification_type, @@ -110,9 +91,9 @@ g_browser_process->profile_manager()->LoadProfile( profile_id, incognito, - base::Bind(&ProfileLoadedCallback, operation, notification_type, origin, - notification_id, action_index, base::nullopt /*reply*/, - by_user)); + base::Bind(&NotificationDisplayServiceImpl::ProfileLoadedCallback, + operation, notification_type, origin, notification_id, + action_index, base::nullopt /*reply*/, by_user)); } } // namespace
diff --git a/chrome/browser/password_manager/password_manager_browsertest.cc b/chrome/browser/password_manager/password_manager_browsertest.cc index 8ef430e2..fe2dd393 100644 --- a/chrome/browser/password_manager/password_manager_browsertest.cc +++ b/chrome/browser/password_manager/password_manager_browsertest.cc
@@ -2955,8 +2955,17 @@ "mypassword"); } + +// Flaky on Linux. http://crbug.com/804398 +#if defined(OS_LINUX) +#define MAYBE_InternalsPage_Renderer DISABLED_InternalsPage_Renderer +#else +#define MAYBE_InternalsPage_Renderer InternalsPage_Renderer +#endif + // Check that the internals page contains logs from the renderer. -IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase, InternalsPage_Renderer) { +IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase, + MAYBE_InternalsPage_Renderer) { // Open the internals page. ui_test_utils::NavigateToURLWithDisposition( browser(), GURL("chrome://password-manager-internals"),
diff --git a/chrome/browser/permissions/chooser_context_base.cc b/chrome/browser/permissions/chooser_context_base.cc index f3a3f47..de73a30 100644 --- a/chrome/browser/permissions/chooser_context_base.cc +++ b/chrome/browser/permissions/chooser_context_base.cc
@@ -6,7 +6,6 @@ #include <utility> -#include "base/memory/ptr_util.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "components/content_settings/core/browser/host_content_settings_map.h" @@ -92,7 +91,7 @@ continue; } - results.push_back(base::MakeUnique<Object>( + results.push_back(std::make_unique<Object>( requesting_origin, embedding_origin, object_dict, content_setting.source, content_setting.incognito)); } @@ -114,7 +113,7 @@ base::ListValue* object_list; if (!setting->GetList(kObjectListKey, &object_list)) { object_list = - setting->SetList(kObjectListKey, base::MakeUnique<base::ListValue>()); + setting->SetList(kObjectListKey, std::make_unique<base::ListValue>()); } object_list->AppendIfNotPresent(std::move(object)); SetWebsiteSetting(requesting_origin, embedding_origin, std::move(setting));
diff --git a/chrome/browser/permissions/grouped_permission_infobar_delegate_android.cc b/chrome/browser/permissions/grouped_permission_infobar_delegate_android.cc index 7986f083..f9a2158 100644 --- a/chrome/browser/permissions/grouped_permission_infobar_delegate_android.cc +++ b/chrome/browser/permissions/grouped_permission_infobar_delegate_android.cc
@@ -24,7 +24,7 @@ const base::WeakPtr<PermissionPromptAndroid>& permission_prompt, InfoBarService* infobar_service) { return infobar_service->AddInfoBar( - base::MakeUnique<GroupedPermissionInfoBar>(base::WrapUnique( + std::make_unique<GroupedPermissionInfoBar>(base::WrapUnique( new GroupedPermissionInfoBarDelegate(permission_prompt)))); }
diff --git a/chrome/browser/permissions/permission_blacklist_client.cc b/chrome/browser/permissions/permission_blacklist_client.cc index 8fbaea43..dca26d8 100644 --- a/chrome/browser/permissions/permission_blacklist_client.cc +++ b/chrome/browser/permissions/permission_blacklist_client.cc
@@ -8,7 +8,6 @@ #include <string> #include "base/logging.h" -#include "base/memory/ptr_util.h" #include "base/timer/elapsed_timer.h" #include "base/timer/timer.h" #include "chrome/browser/permissions/permission_uma_util.h" @@ -60,7 +59,7 @@ // Start the timer to interrupt into the client callback method with an // empty response if Safe Browsing times out. safe_browsing::ThreatMetadata empty_metadata; - timer_ = base::MakeUnique<base::OneShotTimer>(); + timer_ = std::make_unique<base::OneShotTimer>(); elapsed_timer_.reset(new base::ElapsedTimer()); timer_->Start( FROM_HERE, base::TimeDelta::FromMilliseconds(timeout_),
diff --git a/chrome/browser/permissions/permission_context_base.cc b/chrome/browser/permissions/permission_context_base.cc index 79f09f5..4fb90ece 100644 --- a/chrome/browser/permissions/permission_context_base.cc +++ b/chrome/browser/permissions/permission_context_base.cc
@@ -11,7 +11,6 @@ #include "base/callback.h" #include "base/logging.h" -#include "base/memory/ptr_util.h" #include "base/strings/stringprintf.h" #include "base/time/time.h" #include "build/build_config.h" @@ -334,7 +333,7 @@ return; std::unique_ptr<PermissionRequest> request_ptr = - base::MakeUnique<PermissionRequestImpl>( + std::make_unique<PermissionRequestImpl>( requesting_origin, content_settings_type_, user_gesture, base::Bind(&PermissionContextBase::PermissionDecided, weak_factory_.GetWeakPtr(), id, requesting_origin,
diff --git a/chrome/browser/permissions/permission_context_base_unittest.cc b/chrome/browser/permissions/permission_context_base_unittest.cc index a8dccba..72a91e06 100644 --- a/chrome/browser/permissions/permission_context_base_unittest.cc +++ b/chrome/browser/permissions/permission_context_base_unittest.cc
@@ -13,7 +13,6 @@ #include "base/bind.h" #include "base/feature_list.h" #include "base/macros.h" -#include "base/memory/ptr_util.h" #include "base/metrics/field_trial.h" #include "base/run_loop.h" #include "base/test/histogram_tester.h" @@ -195,15 +194,15 @@ Profile* profile, const ContentSettingsType content_settings_type) : TestPermissionContext(profile, content_settings_type), - field_trial_list_(base::MakeUnique<base::FieldTrialList>( - base::MakeUnique<base::MockEntropyProvider>())) {} + field_trial_list_(std::make_unique<base::FieldTrialList>( + std::make_unique<base::MockEntropyProvider>())) {} void ResetFieldTrialList() { // Destroy the existing FieldTrialList before creating a new one to avoid // a DCHECK. field_trial_list_.reset(); - field_trial_list_ = base::MakeUnique<base::FieldTrialList>( - base::MakeUnique<base::MockEntropyProvider>()); + field_trial_list_ = std::make_unique<base::FieldTrialList>( + std::make_unique<base::MockEntropyProvider>()); variations::testing::ClearAllVariationParams(); } @@ -448,7 +447,7 @@ kPromptGroupName, params)); std::unique_ptr<base::FeatureList> feature_list = - base::MakeUnique<base::FeatureList>(); + std::make_unique<base::FeatureList>(); feature_list->RegisterFieldTrialOverride( features::kBlockPromptsIfDismissedOften.name, base::FeatureList::OVERRIDE_ENABLE_FEATURE, trial);
diff --git a/chrome/browser/permissions/permission_decision_auto_blocker.cc b/chrome/browser/permissions/permission_decision_auto_blocker.cc index 40916655..8df324d 100644 --- a/chrome/browser/permissions/permission_decision_auto_blocker.cc +++ b/chrome/browser/permissions/permission_decision_auto_blocker.cc
@@ -9,7 +9,6 @@ #include <utility> #include "base/feature_list.h" -#include "base/memory/ptr_util.h" #include "base/strings/string_number_conversions.h" #include "base/values.h" #include "chrome/browser/browser_process.h" @@ -66,7 +65,7 @@ origin_url, GURL(), CONTENT_SETTINGS_TYPE_PERMISSION_AUTOBLOCKER_DATA, std::string(), nullptr)); if (!dict) - return base::MakeUnique<base::DictionaryValue>(); + return std::make_unique<base::DictionaryValue>(); return dict; }
diff --git a/chrome/browser/permissions/permission_decision_auto_blocker_unittest.cc b/chrome/browser/permissions/permission_decision_auto_blocker_unittest.cc index 66cdf001..b875400 100644 --- a/chrome/browser/permissions/permission_decision_auto_blocker_unittest.cc +++ b/chrome/browser/permissions/permission_decision_auto_blocker_unittest.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/permissions/permission_decision_auto_blocker.h" #include <map> +#include <memory> #include "base/bind.h" #include "base/run_loop.h" @@ -93,7 +94,7 @@ {}); last_embargoed_status_ = false; std::unique_ptr<base::SimpleTestClock> clock = - base::MakeUnique<base::SimpleTestClock>(); + std::make_unique<base::SimpleTestClock>(); clock_ = clock.get(); autoblocker_->SetClockForTesting(std::move(clock)); callback_was_run_ = false;
diff --git a/chrome/browser/permissions/permission_manager.cc b/chrome/browser/permissions/permission_manager.cc index 4ac3f55..f8d4ed82 100644 --- a/chrome/browser/permissions/permission_manager.cc +++ b/chrome/browser/permissions/permission_manager.cc
@@ -8,7 +8,6 @@ #include <utility> #include "base/callback.h" -#include "base/memory/ptr_util.h" #include "build/build_config.h" #include "chrome/browser/accessibility/accessibility_permission_context.h" #include "chrome/browser/background_sync/background_sync_permission_context.h" @@ -259,44 +258,44 @@ PermissionManager::PermissionManager(Profile* profile) : profile_(profile) { permission_contexts_[CONTENT_SETTINGS_TYPE_MIDI_SYSEX] = - base::MakeUnique<MidiSysexPermissionContext>(profile); + std::make_unique<MidiSysexPermissionContext>(profile); permission_contexts_[CONTENT_SETTINGS_TYPE_MIDI] = - base::MakeUnique<MidiPermissionContext>(profile); + std::make_unique<MidiPermissionContext>(profile); permission_contexts_[CONTENT_SETTINGS_TYPE_NOTIFICATIONS] = - base::MakeUnique<NotificationPermissionContext>(profile); + std::make_unique<NotificationPermissionContext>(profile); #if !defined(OS_ANDROID) permission_contexts_[CONTENT_SETTINGS_TYPE_GEOLOCATION] = - base::MakeUnique<GeolocationPermissionContext>(profile); + std::make_unique<GeolocationPermissionContext>(profile); #else permission_contexts_[CONTENT_SETTINGS_TYPE_GEOLOCATION] = - base::MakeUnique<GeolocationPermissionContextAndroid>(profile); + std::make_unique<GeolocationPermissionContextAndroid>(profile); #endif #if defined(OS_CHROMEOS) || defined(OS_ANDROID) permission_contexts_[CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER] = - base::MakeUnique<ProtectedMediaIdentifierPermissionContext>(profile); + std::make_unique<ProtectedMediaIdentifierPermissionContext>(profile); #endif permission_contexts_[CONTENT_SETTINGS_TYPE_DURABLE_STORAGE] = - base::MakeUnique<DurableStoragePermissionContext>(profile); + std::make_unique<DurableStoragePermissionContext>(profile); permission_contexts_[CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC] = - base::MakeUnique<MediaStreamDevicePermissionContext>( + std::make_unique<MediaStreamDevicePermissionContext>( profile, CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC); permission_contexts_[CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA] = - base::MakeUnique<MediaStreamDevicePermissionContext>( + std::make_unique<MediaStreamDevicePermissionContext>( profile, CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA); permission_contexts_[CONTENT_SETTINGS_TYPE_BACKGROUND_SYNC] = - base::MakeUnique<BackgroundSyncPermissionContext>(profile); + std::make_unique<BackgroundSyncPermissionContext>(profile); #if BUILDFLAG(ENABLE_PLUGINS) permission_contexts_[CONTENT_SETTINGS_TYPE_PLUGINS] = - base::MakeUnique<FlashPermissionContext>(profile); + std::make_unique<FlashPermissionContext>(profile); #endif permission_contexts_[CONTENT_SETTINGS_TYPE_SENSORS] = - base::MakeUnique<SensorPermissionContext>(profile); + std::make_unique<SensorPermissionContext>(profile); permission_contexts_[CONTENT_SETTINGS_TYPE_ACCESSIBILITY_EVENTS] = - base::MakeUnique<AccessibilityPermissionContext>(profile); + std::make_unique<AccessibilityPermissionContext>(profile); permission_contexts_[CONTENT_SETTINGS_TYPE_CLIPBOARD_READ] = - base::MakeUnique<ClipboardReadPermissionContext>(profile); + std::make_unique<ClipboardReadPermissionContext>(profile); permission_contexts_[CONTENT_SETTINGS_TYPE_CLIPBOARD_WRITE] = - base::MakeUnique<ClipboardWritePermissionContext>(profile); + std::make_unique<ClipboardWritePermissionContext>(profile); } PermissionManager::~PermissionManager() { @@ -356,7 +355,7 @@ GURL embedding_origin = web_contents->GetLastCommittedURL().GetOrigin(); GURL canonical_requesting_origin = GetCanonicalOrigin(requesting_origin); - int request_id = pending_requests_.Add(base::MakeUnique<PendingRequest>( + int request_id = pending_requests_.Add(std::make_unique<PendingRequest>( render_frame_host, permissions, callback)); const PermissionRequestID request(render_frame_host, request_id); @@ -367,7 +366,7 @@ PermissionContextBase* context = GetPermissionContext(permission); DCHECK(context); auto callback = - base::MakeUnique<PermissionResponseCallback>(this, request_id, i); + std::make_unique<PermissionResponseCallback>(this, request_id, i); context->RequestPermission( web_contents, request, canonical_requesting_origin, user_gesture, base::Bind( @@ -525,7 +524,7 @@ HostContentSettingsMapFactory::GetForProfile(profile_)->AddObserver(this); ContentSettingsType content_type = PermissionTypeToContentSetting(permission); - auto subscription = base::MakeUnique<Subscription>(); + auto subscription = std::make_unique<Subscription>(); subscription->permission = content_type; subscription->requesting_origin = GetCanonicalOrigin(requesting_origin); subscription->embedding_origin = embedding_origin;
diff --git a/chrome/browser/permissions/permission_manager_unittest.cc b/chrome/browser/permissions/permission_manager_unittest.cc index f8e284dd5..6937b0e 100644 --- a/chrome/browser/permissions/permission_manager_unittest.cc +++ b/chrome/browser/permissions/permission_manager_unittest.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/permissions/permission_manager.h" +#include <memory> + #include "base/macros.h" #include "build/build_config.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" @@ -452,7 +454,7 @@ PermissionRequestManager::CreateForWebContents(contents); PermissionRequestManager* manager = PermissionRequestManager::FromWebContents(contents); - auto prompt_factory = base::MakeUnique<MockPermissionPromptFactory>(manager); + auto prompt_factory = std::make_unique<MockPermissionPromptFactory>(manager); NavigateAndCommit(url());
diff --git a/chrome/browser/permissions/permission_prompt_android.cc b/chrome/browser/permissions/permission_prompt_android.cc index e2563aca..8342231 100644 --- a/chrome/browser/permissions/permission_prompt_android.cc +++ b/chrome/browser/permissions/permission_prompt_android.cc
@@ -4,7 +4,8 @@ #include "chrome/browser/permissions/permission_prompt_android.h" -#include "base/memory/ptr_util.h" +#include <memory> + #include "chrome/browser/android/android_theme_resources.h" #include "chrome/browser/infobars/infobar_service.h" #include "chrome/browser/permissions/grouped_permission_infobar_delegate_android.h" @@ -115,5 +116,5 @@ std::unique_ptr<PermissionPrompt> PermissionPrompt::Create( content::WebContents* web_contents, Delegate* delegate) { - return base::MakeUnique<PermissionPromptAndroid>(web_contents, delegate); + return std::make_unique<PermissionPromptAndroid>(web_contents, delegate); }
diff --git a/chrome/browser/permissions/permission_request_manager_browsertest.cc b/chrome/browser/permissions/permission_request_manager_browsertest.cc index 6db3857..aafcd66 100644 --- a/chrome/browser/permissions/permission_request_manager_browsertest.cc +++ b/chrome/browser/permissions/permission_request_manager_browsertest.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/permissions/permission_request_manager.h" +#include <memory> + #include "base/command_line.h" #include "base/metrics/field_trial.h" #include "base/run_loop.h" @@ -137,7 +139,7 @@ bool user_gesture = true; auto decided = [](ContentSetting) {}; auto cleanup = [] {}; // Leave cleanup to test harness destructor. - owned_requests_.push_back(base::MakeUnique<PermissionRequestImpl>( + owned_requests_.push_back(std::make_unique<PermissionRequestImpl>( GetUrl(), permission, user_gesture, base::Bind(decided), base::Bind(cleanup))); return owned_requests_.back().get(); @@ -333,7 +335,7 @@ // SetUp() only creates a mock prompt factory for the first tab. MockPermissionPromptFactory* bubble_factory_0 = bubble_factory(); std::unique_ptr<MockPermissionPromptFactory> bubble_factory_1( - base::MakeUnique<MockPermissionPromptFactory>( + std::make_unique<MockPermissionPromptFactory>( GetPermissionRequestManager())); TabStripModel* tab_strip_model = browser()->tab_strip_model();
diff --git a/chrome/browser/permissions/permission_request_manager_test_api.cc b/chrome/browser/permissions/permission_request_manager_test_api.cc index c8e4171c..3f36862 100644 --- a/chrome/browser/permissions/permission_request_manager_test_api.cc +++ b/chrome/browser/permissions/permission_request_manager_test_api.cc
@@ -21,7 +21,7 @@ explicit TestPermisisonRequestOwner(ContentSettingsType type) { bool user_gesture = true; auto decided = [](ContentSetting) {}; - request_ = base::MakeUnique<PermissionRequestImpl>( + request_ = std::make_unique<PermissionRequestImpl>( GURL("https://example.com"), type, user_gesture, base::Bind(decided), base::Bind(&TestPermisisonRequestOwner::DeleteThis, base::Unretained(this)));
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc index 7470c14..c8826a9 100644 --- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc +++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -265,9 +265,6 @@ { key::kEnableSha1ForLocalAnchors, ssl_config::prefs::kCertEnableSha1LocalAnchors, base::Value::Type::BOOLEAN }, - { key::kEnableCommonNameFallbackForLocalAnchors, - ssl_config::prefs::kCertEnableCommonNameFallbackLocalAnchors, - base::Value::Type::BOOLEAN }, { key::kAuthSchemes, prefs::kAuthSchemes, base::Value::Type::STRING },
diff --git a/chrome/browser/policy/policy_browsertest.cc b/chrome/browser/policy/policy_browsertest.cc index 872e0ae..a7aa16a9 100644 --- a/chrome/browser/policy/policy_browsertest.cc +++ b/chrome/browser/policy/policy_browsertest.cc
@@ -1415,6 +1415,79 @@ EXPECT_FALSE(is_toggle_dev_mode_checkbox_enabled); } +// TODO(dpapad): Remove the "_MD" suffix once the non-MD test is deleted. +IN_PROC_BROWSER_TEST_F(PolicyTest, DeveloperToolsDisabledExtensionsDevMode_MD) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitWithFeatures( + {features::kMaterialDesignExtensions} /* enabled */, {} /* disabled */); + + // Verifies that when DeveloperToolsDisabled policy is set, the "dev mode" + // in chrome://extensions is actively turned off and the checkbox + // is disabled. + // Note: We don't test the indicator as it is tested in the policy pref test + // for kDeveloperToolsDisabled. + + // This test depends on the following helper methods to locate the DOM elemens + // to be tested. + const char define_helpers_js[] = + R"(function getToolbar() { + const manager = document.querySelector('extensions-manager'); + return manager.$$('extensions-toolbar'); + } + + function getToggle() { + return getToolbar().$$('#dev-mode'); + } + + function getControls() { + return getToolbar().$$('#devDrawer'); + } + )"; + + const char toggle_dev_mode_accessor_js[] = "getToggle()"; + const char dev_controls_accessor_js[] = "getControls()"; + const char dev_controls_visibility_check_js[] = + "getControls().hasAttribute('expanded')"; + + // Navigate to the extensions frame and enabled "Developer mode" + ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIExtensionsURL)); + + content::WebContents* contents = + browser()->tab_strip_model()->GetActiveWebContents(); + EXPECT_TRUE( + content::ExecuteScript(contents, base::StringPrintf(define_helpers_js))); + + EXPECT_TRUE(content::ExecuteScript( + contents, base::StringPrintf("domAutomationController.send(%s.click());", + toggle_dev_mode_accessor_js))); + + WaitForExtensionsDevModeControlsVisibility(contents, dev_controls_accessor_js, + dev_controls_visibility_check_js, + true); + + // Disable devtools via policy. + PolicyMap policies; + policies.Set(key::kDeveloperToolsDisabled, POLICY_LEVEL_MANDATORY, + POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, + std::make_unique<base::Value>(true), nullptr); + UpdateProviderPolicy(policies); + + // Expect devcontrols to be hidden now... + WaitForExtensionsDevModeControlsVisibility(contents, dev_controls_accessor_js, + dev_controls_visibility_check_js, + false); + + // ... and checkbox is disabled + bool is_toggle_dev_mode_checkbox_disabled = false; + EXPECT_TRUE(content::ExecuteScriptAndExtractBool( + contents, + base::StringPrintf( + "domAutomationController.send(%s.hasAttribute('disabled'))", + toggle_dev_mode_accessor_js), + &is_toggle_dev_mode_checkbox_disabled)); + EXPECT_TRUE(is_toggle_dev_mode_checkbox_disabled); +} + // TODO(samarth): remove along with rest of NTP4 code. IN_PROC_BROWSER_TEST_F(PolicyTest, DISABLED_WebStoreIconHidden) { // Verifies that the web store icons can be hidden from the new tab page.
diff --git a/chrome/browser/profiles/off_the_record_profile_io_data.cc b/chrome/browser/profiles/off_the_record_profile_io_data.cc index 06bf157b..ae9ed60 100644 --- a/chrome/browser/profiles/off_the_record_profile_io_data.cc +++ b/chrome/browser/profiles/off_the_record_profile_io_data.cc
@@ -1,3 +1,4 @@ + // 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. @@ -33,9 +34,6 @@ #include "net/http/http_cache.h" #include "net/http/http_network_session.h" #include "net/http/http_server_properties_impl.h" -#include "net/network_error_logging/network_error_logging_service.h" -#include "net/reporting/reporting_policy.h" -#include "net/reporting/reporting_service.h" #include "net/ssl/channel_id_service.h" #include "net/ssl/default_channel_id_store.h" #include "net/url_request/url_request_context.h" @@ -280,16 +278,6 @@ std::move(protocol_handler_interceptor), context->network_delegate(), context->host_resolver()); context->SetJobFactory(std::move(top_job_factory)); - if (context->reporting_service()) { - context->SetReportingService(net::ReportingService::Create( - context->reporting_service()->GetPolicy(), context)); - } - if (context->network_error_logging_delegate()) { - context->SetNetworkErrorLoggingDelegate( - net::NetworkErrorLoggingService::Create()); - context->network_error_logging_delegate()->SetReportingService( - context->reporting_service()); - } return context; }
diff --git a/chrome/browser/profiles/profile_browsertest.cc b/chrome/browser/profiles/profile_browsertest.cc index 7ce7a49..a9afe2e2 100644 --- a/chrome/browser/profiles/profile_browsertest.cc +++ b/chrome/browser/profiles/profile_browsertest.cc
@@ -50,6 +50,7 @@ #include "extensions/common/value_builder.h" #include "net/base/net_errors.h" #include "net/dns/mock_host_resolver.h" +#include "net/reporting/reporting_feature.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/embedded_test_server/http_request.h" #include "net/test/embedded_test_server/http_response.h" @@ -59,7 +60,6 @@ #include "net/url_request/url_fetcher_delegate.h" #include "net/url_request/url_request_context_getter.h" #include "net/url_request/url_request_status.h" -#include "services/network/public/cpp/network_features.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -560,10 +560,6 @@ EXPECT_NE(extension_context->reporting_service(), main_context->reporting_service()); } - if (extension_context->network_error_logging_delegate()) { - EXPECT_NE(extension_context->network_error_logging_delegate(), - main_context->network_error_logging_delegate()); - } // Check that the ChannelIDService in the HttpNetworkSession is the same as // the one directly on the URLRequestContext. @@ -587,8 +583,7 @@ ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); base::test::ScopedFeatureList feature_list; - feature_list.InitWithFeatures( - {features::kReporting, features::kNetworkErrorLogging}, {}); + feature_list.InitAndEnableFeature(features::kReporting); MockProfileDelegate delegate; EXPECT_CALL(delegate, OnProfileCreated(testing::NotNull(), true, true)); @@ -628,8 +623,7 @@ ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); base::test::ScopedFeatureList feature_list; - feature_list.InitWithFeatures( - {features::kReporting, features::kNetworkErrorLogging}, {}); + feature_list.InitAndEnableFeature(features::kReporting); MockProfileDelegate delegate; EXPECT_CALL(delegate, OnProfileCreated(testing::NotNull(), true, true));
diff --git a/chrome/browser/profiles/profile_impl_io_data.cc b/chrome/browser/profiles/profile_impl_io_data.cc index e3a3ff4..558f516 100644 --- a/chrome/browser/profiles/profile_impl_io_data.cc +++ b/chrome/browser/profiles/profile_impl_io_data.cc
@@ -68,7 +68,7 @@ #include "net/http/http_network_session.h" #include "net/http/http_server_properties.h" #include "net/http/http_server_properties_manager.h" -#include "net/network_error_logging/network_error_logging_service.h" +#include "net/reporting/reporting_feature.h" #include "net/reporting/reporting_policy.h" #include "net/reporting/reporting_service.h" #include "net/ssl/channel_id_service.h" @@ -479,6 +479,8 @@ SetUpJobFactoryDefaultsForBuilder( builder, std::move(request_interceptors), std::move(profile_params->protocol_handler_interceptor)); + + builder->set_reporting_policy(MaybeCreateReportingPolicy()); } void ProfileImplIOData::OnMainRequestContextCreated( @@ -576,7 +578,7 @@ // Build a new HttpNetworkSession that uses the new ChannelIDService. // TODO(mmenke): It's weird to combine state from - // main_request_context_storage() objects and the argument to this method, + // main_request_context_storage() objects and the argumet to this method, // |main_context|. Remove |main_context| as an argument, and just use // main_context() instead. net::HttpNetworkSession* network_session = @@ -613,17 +615,7 @@ context->host_resolver())); context->SetJobFactory(std::move(top_job_factory)); - if (context->reporting_service()) { - context->SetReportingService(net::ReportingService::Create( - context->reporting_service()->GetPolicy(), context)); - } - - if (context->network_error_logging_delegate()) { - context->SetNetworkErrorLoggingDelegate( - net::NetworkErrorLoggingService::Create()); - context->network_error_logging_delegate()->SetReportingService( - context->reporting_service()); - } + context->SetReportingService(MaybeCreateReportingService(context)); return context; } @@ -712,3 +704,22 @@ chrome_browser_net::Predictor* ProfileImplIOData::GetPredictor() { return predictor_.get(); } + +std::unique_ptr<net::ReportingService> +ProfileImplIOData::MaybeCreateReportingService( + net::URLRequestContext* url_request_context) const { + std::unique_ptr<net::ReportingPolicy> reporting_policy( + MaybeCreateReportingPolicy()); + if (!reporting_policy) + return std::unique_ptr<net::ReportingService>(); + + return net::ReportingService::Create(*reporting_policy, url_request_context); +} + +std::unique_ptr<net::ReportingPolicy> +ProfileImplIOData::MaybeCreateReportingPolicy() { + if (!base::FeatureList::IsEnabled(features::kReporting)) + return std::unique_ptr<net::ReportingPolicy>(); + + return base::MakeUnique<net::ReportingPolicy>(); +}
diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc index 85f02a3c..47f10c48 100644 --- a/chrome/browser/profiles/profile_io_data.cc +++ b/chrome/browser/profiles/profile_io_data.cc
@@ -105,7 +105,6 @@ #include "net/url_request/data_protocol_handler.h" #include "net/url_request/file_protocol_handler.h" #include "net/url_request/ftp_protocol_handler.h" -#include "net/url_request/network_error_logging_delegate.h" #include "net/url_request/report_sender.h" #include "net/url_request/url_request.h" #include "net/url_request/url_request_context.h" @@ -629,16 +628,8 @@ set_reporting_service(reporting_service_.get()); } -void ProfileIOData::AppRequestContext::SetNetworkErrorLoggingDelegate( - std::unique_ptr<net::NetworkErrorLoggingDelegate> - network_error_logging_delegate) { - network_error_logging_delegate_ = std::move(network_error_logging_delegate); - set_network_error_logging_delegate(network_error_logging_delegate_.get()); -} - ProfileIOData::AppRequestContext::~AppRequestContext() { - SetNetworkErrorLoggingDelegate(nullptr); - SetReportingService(nullptr); + SetReportingService(std::unique_ptr<net::ReportingService>()); AssertNoURLRequests(); }
diff --git a/chrome/browser/profiles/profile_io_data.h b/chrome/browser/profiles/profile_io_data.h index 934d1db..cdd85d6 100644 --- a/chrome/browser/profiles/profile_io_data.h +++ b/chrome/browser/profiles/profile_io_data.h
@@ -81,7 +81,6 @@ class ClientCertStore; class CookieStore; class HttpTransactionFactory; -class NetworkErrorLoggingDelegate; class ReportingService; class ReportSender; class SSLConfigService; @@ -301,9 +300,6 @@ void SetJobFactory(std::unique_ptr<net::URLRequestJobFactory> job_factory); void SetReportingService( std::unique_ptr<net::ReportingService> reporting_service); - void SetNetworkErrorLoggingDelegate( - std::unique_ptr<net::NetworkErrorLoggingDelegate> - network_error_logging_delegate); private: ~AppRequestContext() override; @@ -314,8 +310,6 @@ std::unique_ptr<net::HttpTransactionFactory> http_factory_; std::unique_ptr<net::URLRequestJobFactory> job_factory_; std::unique_ptr<net::ReportingService> reporting_service_; - std::unique_ptr<net::NetworkErrorLoggingDelegate> - network_error_logging_delegate_; }; // Created on the UI thread, read on the IO thread during ProfileIOData lazy
diff --git a/chrome/browser/resources/local_ntp/most_visited_single.js b/chrome/browser/resources/local_ntp/most_visited_single.js index c4c0bfe..9bdd106 100644 --- a/chrome/browser/resources/local_ntp/most_visited_single.js +++ b/chrome/browser/resources/local_ntp/most_visited_single.js
@@ -27,35 +27,6 @@ /** - * The different sources where an NTP tile's title can originate from. - * Note: Keep in sync with components/ntp_tiles/tile_title_source.h - * @enum {number} - * @const - */ -var TileTitleSource = { - UNKNOWN: 0, - MANIFEST: 1, - META_TAG: 2, - TITLE: 3, - INFERRED: 4 -}; - - -/** - * The different sources that an NTP tile can have. - * Note: Keep in sync with components/ntp_tiles/tile_source.h - * @enum {number} - * @const - */ -var TileSource = { - TOP_SITES: 0, - SUGGESTIONS_SERVICE: 1, - POPULAR: 3, - WHITELIST: 4, -}; - - -/** * The different (visual) types that an NTP tile can have. * Note: Keep in sync with components/ntp_tiles/tile_visual_type.h * @enum {number} @@ -128,9 +99,11 @@ /** * Log impression of an NTP tile. * @param {number} tileIndex Position of the tile, >= 0 and < NUMBER_OF_TILES. - * @param {number} tileTitleSource The title's source from TileTitleSource. - * @param {number} tileSource The source from TileSource. - * @param {number} tileType The type from TileVisualType. + * @param {number} tileTitleSource The source of the tile's title as received + * from getMostVisitedItemData. + * @param {number} tileSource The tile's source as received from + * getMostVisitedItemData. + * @param {number} tileType The tile's visual type from TileVisualType. * @param {Date} dataGenerationTime Timestamp representing when the tile was * produced by a ranking algorithm. */ @@ -143,9 +116,11 @@ /** * Log click on an NTP tile. * @param {number} tileIndex Position of the tile, >= 0 and < NUMBER_OF_TILES. - * @param {number} tileTitleSource The title's source from TileTitleSource. - * @param {number} tileSource The source from TileSource. - * @param {number} tileType The type from TileVisualType. + * @param {number} tileTitleSource The source of the tile's title as received + * from getMostVisitedItemData. + * @param {number} tileSource The tile's source as received from + * getMostVisitedItemData. + * @param {number} tileType The tile's visual type from TileVisualType. * @param {Date} dataGenerationTime Timestamp representing when the tile was * produced by a ranking algorithm. */
diff --git a/chrome/browser/signin/account_consistency_mode_manager.cc b/chrome/browser/signin/account_consistency_mode_manager.cc index f7d38fcd..3702c70b 100644 --- a/chrome/browser/signin/account_consistency_mode_manager.cc +++ b/chrome/browser/signin/account_consistency_mode_manager.cc
@@ -9,6 +9,7 @@ #include "chrome/browser/profiles/profile.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_service.h" +#include "content/public/browser/browser_thread.h" namespace { @@ -76,6 +77,9 @@ // static bool AccountConsistencyModeManager::IsDiceEnabledForProfile( const Profile* profile) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + DCHECK(profile); + return profile->GetProfileType() == Profile::ProfileType::REGULAR_PROFILE && signin::IsDiceEnabledForProfile(profile->GetPrefs()); } @@ -93,3 +97,16 @@ profile_->GetPrefs()->GetBoolean(kDiceMigrationOnStartupPref); } #endif // BUILDFLAG(ENABLE_DICE_SUPPORT) + +// static +bool AccountConsistencyModeManager::IsMirrorEnabledForProfile( + const Profile* profile) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + DCHECK(profile); + +#if defined(OS_CHROMEOS) + return profile->IsChild(); +#else + return signin::IsAccountConsistencyMirrorEnabled(); +#endif +}
diff --git a/chrome/browser/signin/account_consistency_mode_manager.h b/chrome/browser/signin/account_consistency_mode_manager.h index 19390de..182361a 100644 --- a/chrome/browser/signin/account_consistency_mode_manager.h +++ b/chrome/browser/signin/account_consistency_mode_manager.h
@@ -33,8 +33,16 @@ // If true, then account management is done through Gaia webpages. // Can only be used on the UI thread. // Returns false if |profile| is in Guest or Incognito mode. + // A given |profile| will have only one of Mirror or Dice consistency + // behaviour enabled. static bool IsDiceEnabledForProfile(const Profile* profile); + // Returns |true| if Mirror account consistency is enabled for |profile|. + // Can only be used on the UI thread. + // A given |profile| will have only one of Mirror or Dice consistency + // behaviour enabled. + static bool IsMirrorEnabledForProfile(const Profile* profile); + private: FRIEND_TEST_ALL_PREFIXES(AccountConsistencyModeManagerTest, MigrateAtCreation);
diff --git a/chrome/browser/signin/account_consistency_mode_manager_unittest.cc b/chrome/browser/signin/account_consistency_mode_manager_unittest.cc index 49486e73..137c424c 100644 --- a/chrome/browser/signin/account_consistency_mode_manager_unittest.cc +++ b/chrome/browser/signin/account_consistency_mode_manager_unittest.cc
@@ -5,10 +5,12 @@ #include "chrome/browser/signin/account_consistency_mode_manager.h" #include <memory> +#include <utility> #include "base/test/scoped_feature_list.h" #include "build/buildflag.h" #include "chrome/browser/prefs/browser_prefs.h" +#include "chrome/browser/supervised_user/supervised_user_constants.h" #include "chrome/test/base/testing_profile.h" #include "components/prefs/pref_notifier_impl.h" #include "components/prefs/testing_pref_store.h" @@ -91,3 +93,41 @@ EXPECT_TRUE(signin::IsDiceEnabledForProfile(profile->GetPrefs())); } #endif // BUILDFLAG(ENABLE_DICE_SUPPORT) + +#if defined(OS_CHROMEOS) +TEST(AccountConsistencyModeManagerTest, MirrorDisabledForNonUnicorn) { + // Creation of this object sets the current thread's id as UI thread. + content::TestBrowserThreadBundle test_thread_bundle; + + TestingProfile profile; + EXPECT_FALSE( + AccountConsistencyModeManager::IsMirrorEnabledForProfile(&profile)); +} + +TEST(AccountConsistencyModeManagerTest, MirrorEnabledForUnicorn) { + // Creation of this object sets the current thread's id as UI thread. + content::TestBrowserThreadBundle test_thread_bundle; + + TestingProfile profile; + profile.SetSupervisedUserId(supervised_users::kChildAccountSUID); + EXPECT_TRUE( + AccountConsistencyModeManager::IsMirrorEnabledForProfile(&profile)); +} +#endif + +#if BUILDFLAG(ENABLE_MIRROR) +TEST(AccountConsistencyModeManagerTest, MirrorEnabled) { + // Creation of this object sets the current thread's id as UI thread. + content::TestBrowserThreadBundle test_thread_bundle; + + // Test that Mirror is enabled for regular accounts. + TestingProfile profile; + EXPECT_TRUE( + AccountConsistencyModeManager::IsMirrorEnabledForProfile(&profile)); + + // Test that Mirror is enabled for child accounts. + profile.SetSupervisedUserId(supervised_users::kChildAccountSUID); + EXPECT_TRUE( + AccountConsistencyModeManager::IsMirrorEnabledForProfile(&profile)); +} +#endif
diff --git a/chrome/browser/signin/account_fetcher_service_factory.cc b/chrome/browser/signin/account_fetcher_service_factory.cc index f009533..0bf902d 100644 --- a/chrome/browser/signin/account_fetcher_service_factory.cc +++ b/chrome/browser/signin/account_fetcher_service_factory.cc
@@ -6,6 +6,7 @@ #include "chrome/browser/invalidation/profile_invalidation_provider_factory.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/search/suggestions/image_decoder_impl.h" #include "chrome/browser/signin/account_tracker_service_factory.h" #include "chrome/browser/signin/chrome_signin_client_factory.h" #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" @@ -48,6 +49,7 @@ AccountFetcherService* service = new AccountFetcherService(); service->Initialize(ChromeSigninClientFactory::GetForProfile(profile), ProfileOAuth2TokenServiceFactory::GetForProfile(profile), - AccountTrackerServiceFactory::GetForProfile(profile)); + AccountTrackerServiceFactory::GetForProfile(profile), + std::make_unique<suggestions::ImageDecoderImpl>()); return service; }
diff --git a/chrome/browser/signin/account_reconcilor_factory.cc b/chrome/browser/signin/account_reconcilor_factory.cc index e7b6195..f1a2858 100644 --- a/chrome/browser/signin/account_reconcilor_factory.cc +++ b/chrome/browser/signin/account_reconcilor_factory.cc
@@ -8,6 +8,7 @@ #include "base/logging.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/signin/account_consistency_mode_manager.h" #include "chrome/browser/signin/chrome_signin_client_factory.h" #include "chrome/browser/signin/gaia_cookie_manager_service_factory.h" #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" @@ -63,6 +64,12 @@ // static std::unique_ptr<signin::AccountReconcilorDelegate> AccountReconcilorFactory::CreateAccountReconcilorDelegate(Profile* profile) { + if (AccountConsistencyModeManager::IsMirrorEnabledForProfile(profile)) { + return std::make_unique<signin::MirrorAccountReconcilorDelegate>( + SigninManagerFactory::GetForProfile(profile)); + } + // TODO(droger): Remove this switch case. |AccountConsistencyModeManager| is + // the source of truth. switch (signin::GetAccountConsistencyMethod()) { case signin::AccountConsistencyMethod::kMirror: return std::make_unique<signin::MirrorAccountReconcilorDelegate>(
diff --git a/chrome/browser/signin/fake_account_fetcher_service_builder.cc b/chrome/browser/signin/fake_account_fetcher_service_builder.cc index 36605c8..4823cf4 100644 --- a/chrome/browser/signin/fake_account_fetcher_service_builder.cc +++ b/chrome/browser/signin/fake_account_fetcher_service_builder.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/signin/fake_account_fetcher_service_builder.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/search/suggestions/image_decoder_impl.h" #include "chrome/browser/signin/account_tracker_service_factory.h" #include "chrome/browser/signin/chrome_signin_client_factory.h" #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" @@ -18,6 +19,7 @@ Profile* profile = Profile::FromBrowserContext(context); service->Initialize(ChromeSigninClientFactory::GetForProfile(profile), ProfileOAuth2TokenServiceFactory::GetForProfile(profile), - AccountTrackerServiceFactory::GetForProfile(profile)); + AccountTrackerServiceFactory::GetForProfile(profile), + std::make_unique<suggestions ::ImageDecoderImpl>()); return std::unique_ptr<KeyedService>(service); }
diff --git a/chrome/browser/signin/signin_ui_util.cc b/chrome/browser/signin/signin_ui_util.cc index fe74ea3..dae322b 100644 --- a/chrome/browser/signin/signin_ui_util.cc +++ b/chrome/browser/signin/signin_ui_util.cc
@@ -17,6 +17,7 @@ #include "chrome/browser/signin/signin_global_error_factory.h" #include "chrome/browser/signin/signin_manager_factory.h" #include "chrome/browser/sync/profile_sync_service_factory.h" +#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_navigator.h" #include "chrome/browser/ui/browser_navigator_params.h" #include "chrome/common/pref_names.h" @@ -31,6 +32,11 @@ #include "ui/gfx/font_list.h" #include "ui/gfx/text_elider.h" +#if BUILDFLAG(ENABLE_DICE_SUPPORT) +#include "chrome/browser/signin/account_consistency_mode_manager.h" +#include "chrome/browser/ui/webui/signin/dice_turn_sync_on_helper.h" +#endif + namespace signin_ui_util { base::string16 GetAuthenticatedUsername(const SigninManagerBase* signin) { @@ -81,6 +87,7 @@ return email; } +#if BUILDFLAG(ENABLE_DICE_SUPPORT) // TODO(tangltom): Add a unit test for this function. std::vector<AccountInfo> GetAccountsForDicePromos(Profile* profile) { // Fetch account ids for accounts that have a token. @@ -113,4 +120,40 @@ return accounts; } +void EnableSync(Browser* browser, + const AccountInfo& account, + signin_metrics::AccessPoint access_point) { + DCHECK(browser); + DCHECK(!account.account_id.empty()); + DCHECK(!account.email.empty()); + DCHECK_NE(signin_metrics::AccessPoint::ACCESS_POINT_UNKNOWN, access_point); + + Profile* profile = browser->profile(); + DCHECK(AccountConsistencyModeManager::IsDiceEnabledForProfile(profile)); + if (SigninManagerFactory::GetForProfile(profile)->IsAuthenticated()) { + DVLOG(1) << "There is already a primary account."; + return; + } + + ProfileOAuth2TokenService* token_service = + ProfileOAuth2TokenServiceFactory::GetForProfile(profile); + bool needs_reauth_before_enable_sync = + !token_service->RefreshTokenIsAvailable(account.account_id) || + token_service->RefreshTokenHasError(account.account_id); + if (needs_reauth_before_enable_sync) { + browser->signin_view_controller()->ShowDiceSigninTab( + profiles::BUBBLE_VIEW_MODE_GAIA_SIGNIN, browser, access_point, + account.email); + return; + } + + // DiceTurnSyncOnHelper is suicidal (it will delete itself once it finishes + // enabling sync). + new DiceTurnSyncOnHelper( + profile, browser, access_point, + signin_metrics::Reason::REASON_UNKNOWN_REASON, account.account_id, + DiceTurnSyncOnHelper::SigninAbortedMode::KEEP_ACCOUNT); +} +#endif // BUILDFLAG(ENABLE_DICE_SUPPORT) + } // namespace signin_ui_util
diff --git a/chrome/browser/signin/signin_ui_util.h b/chrome/browser/signin/signin_ui_util.h index d0ceb21..5eea8a1 100644 --- a/chrome/browser/signin/signin_ui_util.h +++ b/chrome/browser/signin/signin_ui_util.h
@@ -9,9 +9,13 @@ #include <vector> #include "base/strings/string16.h" +#include "build/buildflag.h" #include "components/signin/core/browser/account_info.h" +#include "components/signin/core/browser/signin_features.h" +#include "components/signin/core/browser/signin_metrics.h" class Profile; +class Browser; class SigninManagerBase; // Utility functions to gather status information from the various signed in @@ -31,6 +35,7 @@ // Shows a learn more page for signin errors. void ShowSigninErrorLearnMorePage(Profile* profile); +#if BUILDFLAG(ENABLE_DICE_SUPPORT) // Returns the display email string for the given account. If the profile // has not been migrated to use gaia ids, then its possible for the display // to not ne known yet. In this case, use |account_id|, which is assumed to @@ -41,6 +46,16 @@ // the Gaia cookies will be the first account in the list. std::vector<AccountInfo> GetAccountsForDicePromos(Profile* profile); +// Enables sync for |account| if the refresh token is valid or presents the +// Chrome sign-in page with |account.email| prefilled if the token is missing +// or invalid. +// +// Note: This function does nothing if the user is already signed in to Chrome. +void EnableSync(Browser* browser, + const AccountInfo& account, + signin_metrics::AccessPoint access_point); +#endif + } // namespace signin_ui_util #endif // CHROME_BROWSER_SIGNIN_SIGNIN_UI_UTIL_H_
diff --git a/chrome/browser/ssl/ssl_browsertest.cc b/chrome/browser/ssl/ssl_browsertest.cc index 8c5895bd..4fc7638 100644 --- a/chrome/browser/ssl/ssl_browsertest.cc +++ b/chrome/browser/ssl/ssl_browsertest.cc
@@ -1920,24 +1920,6 @@ net::CERT_STATUS_COMMON_NAME_INVALID, AuthState::SHOWING_INTERSTITIAL); } -IN_PROC_BROWSER_TEST_P(SSLUITest, CommonNamePrefsCanEnable) { - bool net::SSLConfig::*member = - &net::SSLConfig::common_name_fallback_local_anchors_enabled; - - ASSERT_NO_FATAL_FAILURE(EnablePolicy( - policy::key::kEnableCommonNameFallbackForLocalAnchors, - ssl_config::prefs::kCertEnableCommonNameFallbackLocalAnchors)); - ASSERT_NO_FATAL_FAILURE( - CheckSSLConfig(browser()->profile()->GetRequestContext(), member, true)); - - ASSERT_TRUE(https_server_common_name_only_.Start()); - ui_test_utils::NavigateToURL( - browser(), https_server_common_name_only_.GetURL("/ssl/google.html")); - - CheckAuthenticatedState(browser()->tab_strip_model()->GetActiveWebContents(), - AuthState::NONE); -} - IN_PROC_BROWSER_TEST_P(SSLUITest, SymantecEnforcementIsNotDisabled) { bool net::SSLConfig::*member = &net::SSLConfig::symantec_enforcement_disabled; ASSERT_NO_FATAL_FAILURE(
diff --git a/chrome/browser/supervised_user/experimental/safe_search_url_reporter.cc b/chrome/browser/supervised_user/experimental/safe_search_url_reporter.cc index a13d641f..d00389642 100644 --- a/chrome/browser/supervised_user/experimental/safe_search_url_reporter.cc +++ b/chrome/browser/supervised_user/experimental/safe_search_url_reporter.cc
@@ -33,9 +33,6 @@ const char kAuthorizationHeaderFormat[] = "Authorization: Bearer %s"; -// Request keys -const char kUrlKey[] = "url"; - struct SafeSearchURLReporter::Report { Report(const GURL& url, const SuccessCallback& callback, int url_fetcher_id); ~Report(); @@ -149,7 +146,7 @@ base::StringPrintf(kAuthorizationHeaderFormat, access_token.c_str())); base::DictionaryValue dict; - dict.SetKey(kUrlKey, base::Value((*it)->url.spec())); + dict.SetKey("url", base::Value((*it)->url.spec())); std::string body; base::JSONWriter::Write(dict, &body);
diff --git a/chrome/browser/ui/bookmarks/bookmark_bubble_sign_in_delegate.cc b/chrome/browser/ui/bookmarks/bookmark_bubble_sign_in_delegate.cc index b5e12b6..fc374060 100644 --- a/chrome/browser/ui/bookmarks/bookmark_bubble_sign_in_delegate.cc +++ b/chrome/browser/ui/bookmarks/bookmark_bubble_sign_in_delegate.cc
@@ -5,7 +5,6 @@ #include "chrome/browser/ui/bookmarks/bookmark_bubble_sign_in_delegate.h" #include "build/buildflag.h" -#include "chrome/browser/signin/signin_manager_factory.h" #include "chrome/browser/signin/signin_promo.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" @@ -14,11 +13,10 @@ #include "chrome/browser/ui/chrome_pages.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "components/signin/core/browser/signin_features.h" -#include "components/signin/core/browser/signin_manager.h" #if BUILDFLAG(ENABLE_DICE_SUPPORT) #include "chrome/browser/signin/account_consistency_mode_manager.h" -#include "chrome/browser/ui/webui/signin/dice_turn_sync_on_helper.h" +#include "chrome/browser/signin/signin_ui_util.h" #endif BookmarkBubbleSignInDelegate::BookmarkBubbleSignInDelegate(Browser* browser) @@ -37,28 +35,17 @@ browser_, signin_metrics::AccessPoint::ACCESS_POINT_BOOKMARK_BUBBLE); } -void BookmarkBubbleSignInDelegate::EnableSync(const AccountInfo& account) { #if BUILDFLAG(ENABLE_DICE_SUPPORT) - DCHECK(AccountConsistencyModeManager::IsDiceEnabledForProfile(profile_)); - - if (SigninManagerFactory::GetForProfile(profile_)->IsAuthenticated()) - return; - +void BookmarkBubbleSignInDelegate::EnableSync(const AccountInfo& account) { EnsureBrowser(); - // DiceTurnSyncOnHelper is suicidal (it will delete itself once it finishes - // enabling sync). - new DiceTurnSyncOnHelper( - profile_, browser_, - signin_metrics::AccessPoint::ACCESS_POINT_BOOKMARK_BUBBLE, - signin_metrics::Reason::REASON_SIGNIN_PRIMARY_ACCOUNT, account.account_id, - DiceTurnSyncOnHelper::SigninAbortedMode::KEEP_ACCOUNT); + signin_ui_util::EnableSync( + browser_, account, + signin_metrics::AccessPoint::ACCESS_POINT_BOOKMARK_BUBBLE); -// TODO(msarda): Close the bookmarks bubble once the enable sync flow has -// started. -#else - NOTREACHED(); -#endif + // TODO(msarda): Close the bookmarks bubble once the enable sync flow has + // started. } +#endif void BookmarkBubbleSignInDelegate::OnBrowserRemoved(Browser* browser) { if (browser == browser_)
diff --git a/chrome/browser/ui/bookmarks/bookmark_bubble_sign_in_delegate.h b/chrome/browser/ui/bookmarks/bookmark_bubble_sign_in_delegate.h index fafbf6c..65a1e19 100644 --- a/chrome/browser/ui/bookmarks/bookmark_bubble_sign_in_delegate.h +++ b/chrome/browser/ui/bookmarks/bookmark_bubble_sign_in_delegate.h
@@ -25,7 +25,9 @@ // BubbleSyncPromoDelegate: void ShowBrowserSignin() override; +#if BUILDFLAG(ENABLE_DICE_SUPPORT) void EnableSync(const AccountInfo& account) override; +#endif // BrowserListObserver: void OnBrowserRemoved(Browser* browser) override;
diff --git a/chrome/browser/ui/cocoa/autofill/save_card_bubble_view_unittest.mm b/chrome/browser/ui/cocoa/autofill/save_card_bubble_view_unittest.mm index f2c956c..0514c62 100644 --- a/chrome/browser/ui/cocoa/autofill/save_card_bubble_view_unittest.mm +++ b/chrome/browser/ui/cocoa/autofill/save_card_bubble_view_unittest.mm
@@ -131,7 +131,7 @@ } void TearDown() override { - [browser_window_controller_ close]; + [[browser_window_controller_ nsWindowController] close]; CocoaProfileTest::TearDown(); }
diff --git a/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.mm b/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.mm index 9fa797e..63259ffe 100644 --- a/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.mm +++ b/chrome/browser/ui/cocoa/bookmarks/bookmark_bubble_controller.mm
@@ -396,8 +396,9 @@ } - (LocationBarDecoration*)decorationForBubble { - LocationBarViewMac* locationBar = - [[[self parentWindow] windowController] locationBarBridge]; + BrowserWindowController* browserWindowController = [BrowserWindowController + browserWindowControllerForWindow:[self parentWindow]]; + LocationBarViewMac* locationBar = [browserWindowController locationBarBridge]; return locationBar ? locationBar->star_decoration() : nullptr; }
diff --git a/chrome/browser/ui/cocoa/browser_window_cocoa_unittest.mm b/chrome/browser/ui/cocoa/browser_window_cocoa_unittest.mm index 76a34bc0..ceac777 100644 --- a/chrome/browser/ui/cocoa/browser_window_cocoa_unittest.mm +++ b/chrome/browser/ui/cocoa/browser_window_cocoa_unittest.mm
@@ -30,7 +30,7 @@ } void TearDown() override { - [controller_ close]; + [[controller_ nsWindowController] close]; CocoaProfileTest::TearDown(); }
diff --git a/chrome/browser/ui/cocoa/browser_window_command_handler.mm b/chrome/browser/ui/cocoa/browser_window_command_handler.mm index e68b691..1a1ff7a 100644 --- a/chrome/browser/ui/cocoa/browser_window_command_handler.mm +++ b/chrome/browser/ui/cocoa/browser_window_command_handler.mm
@@ -95,7 +95,9 @@ // TODO(jackhou): Remove the dependency on BrowserWindowController(Private). NSString* GetTitleForFullscreenMenuItem(Browser* browser) { NSWindow* ns_window = browser->window()->GetNativeWindow(); - if (BrowserWindowController* controller = [ns_window windowController]) { + BrowserWindowController* controller = + [BrowserWindowController browserWindowControllerForWindow:ns_window]; + if (controller) { return l10n_util::GetNSString([controller isInAppKitFullscreen] ? IDS_EXIT_FULLSCREEN_MAC : IDS_ENTER_FULLSCREEN_MAC);
diff --git a/chrome/browser/ui/cocoa/browser_window_controller.h b/chrome/browser/ui/cocoa/browser_window_controller.h index fb2ca36f..3974ee2 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller.h +++ b/chrome/browser/ui/cocoa/browser_window_controller.h
@@ -9,6 +9,9 @@ // object. Handles interactions between Cocoa and the cross-platform // code. Each window has a single toolbar and, by virtue of being a // TabWindowController, a tab strip along the top. +// Note that under the hood the BrowserWindowController is neither an +// NSWindowController nor its window's delegate, though it receives all +// NSWindowDelegate methods as if it were. #import <Cocoa/Cocoa.h> @@ -638,5 +641,4 @@ @end // @interface BrowserWindowController (TestingAPI) - #endif // CHROME_BROWSER_UI_COCOA_BROWSER_WINDOW_CONTROLLER_H_
diff --git a/chrome/browser/ui/cocoa/browser_window_controller.mm b/chrome/browser/ui/cocoa/browser_window_controller.mm index c65db3c..0e5db8e 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller.mm +++ b/chrome/browser/ui/cocoa/browser_window_controller.mm
@@ -249,13 +249,8 @@ @implementation BrowserWindowController + (BrowserWindowController*)browserWindowControllerForWindow:(NSWindow*)window { - while (window) { - id controller = [window windowController]; - if ([controller isKindOfClass:[BrowserWindowController class]]) - return (BrowserWindowController*)controller; - window = [window parentWindow]; - } - return nil; + return base::mac::ObjCCast<BrowserWindowController>( + [TabWindowController tabWindowControllerForWindow:window]); } + (BrowserWindowController*)browserWindowControllerForView:(NSView*)view { @@ -774,7 +769,7 @@ } - (void)activate { - [BrowserWindowUtils activateWindowForController:self]; + [BrowserWindowUtils activateWindowForController:[self nsWindowController]]; } // Determine whether we should let a window zoom/unzoom to the given |newFrame|. @@ -1286,9 +1281,8 @@ CreateNewStripWithContents(contentses, browserRect, false); // Get the new controller by asking the new window for its delegate. - BrowserWindowController* controller = - reinterpret_cast<BrowserWindowController*>( - [newBrowser->window()->GetNativeWindow() delegate]); + BrowserWindowController* controller = [BrowserWindowController + browserWindowControllerForWindow:newBrowser->window()->GetNativeWindow()]; DCHECK(controller && [controller isKindOfClass:[TabWindowController class]]); // Ensure that the window will appear on top of the source window in
diff --git a/chrome/browser/ui/cocoa/browser_window_controller_browsertest.mm b/chrome/browser/ui/cocoa/browser_window_controller_browsertest.mm index 4bae8d7..93e9020 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller_browsertest.mm +++ b/chrome/browser/ui/cocoa/browser_window_controller_browsertest.mm
@@ -636,7 +636,9 @@ EXPECT_FALSE([popupController hasToolbar]); // Open sheet in an application window. - [popupController showWindow:nil]; + NSWindowController* nsWindowController = [popupController nsWindowController]; + EXPECT_TRUE(nsWindowController); + [nsWindowController showWindow:nil]; sheetLocation = [popupController window:popupWindow willPositionSheet:sheet usingRect:defaultLocation]; @@ -644,7 +646,7 @@ // Close the application window. popup_browser->tab_strip_model()->CloseSelectedTabs(); - [popupController close]; + [nsWindowController close]; } // Verify that the info bar tip is hidden when the toolbar is not visible.
diff --git a/chrome/browser/ui/cocoa/browser_window_controller_private.mm b/chrome/browser/ui/cocoa/browser_window_controller_private.mm index f6b052ea..bedc4ae 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller_private.mm +++ b/chrome/browser/ui/cocoa/browser_window_controller_private.mm
@@ -360,7 +360,7 @@ // Have to do this here, otherwise later calls can crash because the window // has no delegate. [sourceWindow setDelegate:nil]; - [destWindow setDelegate:self]; + [destWindow setDelegate:[self nsWindowController]]; // With this call, valgrind complains that a "Conditional jump or move depends // on uninitialised value(s)". The error happens in -[NSThemeFrame @@ -389,7 +389,7 @@ [sourceWindow setWindowController:nil]; [self setWindow:destWindow]; - [destWindow setWindowController:self]; + [destWindow setWindowController:[self nsWindowController]]; // Move the status bubble over, if we have one. if (statusBubble_) @@ -608,9 +608,8 @@ NSWindow* windowForToolbar = [window _windowForToolbar]; if ([windowForToolbar isKindOfClass:[FramedBrowserWindow class]]) { - BrowserWindowController* bwc = - base::mac::ObjCCastStrict<BrowserWindowController>( - [windowForToolbar windowController]); + BrowserWindowController* bwc = [BrowserWindowController + browserWindowControllerForWindow:windowForToolbar]; if ([bwc hasToolbar]) [[window contentView] setHidden:YES]; }
diff --git a/chrome/browser/ui/cocoa/browser_window_controller_unittest.mm b/chrome/browser/ui/cocoa/browser_window_controller_unittest.mm index 8f553ce..1a72305 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/browser_window_controller_unittest.mm
@@ -84,7 +84,7 @@ } void TearDown() override { - [controller_ close]; + [[controller_ nsWindowController] close]; CocoaProfileTest::TearDown(); } @@ -136,13 +136,13 @@ new Browser(Browser::CreateParams(Browser::TYPE_POPUP, profile(), true))); NSWindow* cocoaWindow = popup_browser->window()->GetNativeWindow(); BrowserWindowController* controller = - static_cast<BrowserWindowController*>([cocoaWindow windowController]); + [BrowserWindowController browserWindowControllerForWindow:cocoaWindow]; ASSERT_TRUE([controller isKindOfClass:[BrowserWindowController class]]); EXPECT_FALSE([controller isTabbedWindow]); EXPECT_FALSE([controller hasTabStrip]); EXPECT_TRUE([controller hasTitleBar]); EXPECT_FALSE([controller isBookmarkBarVisible]); - [controller close]; + [[controller nsWindowController] close]; } TEST_F(BrowserWindowControllerTest, TestSetBounds) { @@ -152,7 +152,7 @@ Browser* browser = new Browser(params); NSWindow* cocoaWindow = browser->window()->GetNativeWindow(); BrowserWindowController* controller = - static_cast<BrowserWindowController*>([cocoaWindow windowController]); + [BrowserWindowController browserWindowControllerForWindow:cocoaWindow]; ASSERT_TRUE([controller isTabbedWindow]); BrowserWindow* browser_window = [controller browserWindow]; @@ -163,7 +163,7 @@ browser_window->SetBounds(gfx::Rect(0, 0, 50, 50)); EXPECT_EQ(browser_window->GetBounds().size(), kMinCocoaTabbedWindowSize); - [controller close]; + [[controller nsWindowController] close]; } // https://crbug.com/667698 - When Auto Layout is in use, adding the download @@ -205,7 +205,7 @@ Browser* browser = new Browser(params); NSWindow* cocoaWindow = browser->window()->GetNativeWindow(); BrowserWindowController* controller = - static_cast<BrowserWindowController*>([cocoaWindow windowController]); + [BrowserWindowController browserWindowControllerForWindow:cocoaWindow]; ASSERT_FALSE([controller isTabbedWindow]); BrowserWindow* browser_window = [controller browserWindow]; @@ -220,7 +220,7 @@ EXPECT_EQ(100, bounds.width()); EXPECT_EQ(122, bounds.height()); - [controller close]; + [[controller nsWindowController] close]; } TEST_F(BrowserWindowControllerTest, TestTheme) { @@ -245,7 +245,7 @@ Browser* browser = new Browser(params); NSWindow* cocoaWindow = browser->window()->GetNativeWindow(); BrowserWindowController* controller = - static_cast<BrowserWindowController*>([cocoaWindow windowController]); + [BrowserWindowController browserWindowControllerForWindow:cocoaWindow]; BrowserWindow* browser_window = [controller browserWindow]; gfx::Rect bounds = browser_window->GetBounds(); EXPECT_EQ(280, bounds.height()); @@ -257,7 +257,7 @@ bounds = browser_window->GetBounds(); EXPECT_EQ(272, bounds.height()); - [controller close]; + [[controller nsWindowController] close]; } #if 0 @@ -783,7 +783,7 @@ } void TearDown() override { - [controller_ close]; + [[controller_ nsWindowController] close]; CocoaProfileTest::TearDown(); } @@ -809,7 +809,7 @@ // http://crbug.com/53586 TEST_F(BrowserWindowFullScreenControllerTest, TestFullscreen) { ui::test::ScopedFakeNSWindowFullscreen fake_fullscreen; - [controller_ showWindow:nil]; + [[controller_ nsWindowController] showWindow:nil]; EXPECT_FALSE([controller_ isInAnyFullscreenMode]); // The fix for http://crbug.com/447740 , where the omnibox would lose focus @@ -844,7 +844,7 @@ // http://crbug.com/53586 TEST_F(BrowserWindowFullScreenControllerTest, TestActivate) { ui::test::ScopedFakeNSWindowFullscreen fake_fullscreen; - [controller_ showWindow:nil]; + [[controller_ nsWindowController] showWindow:nil]; EXPECT_FALSE([controller_ isInAnyFullscreenMode]);
diff --git a/chrome/browser/ui/cocoa/bubble_anchor_helper.mm b/chrome/browser/ui/cocoa/bubble_anchor_helper.mm index bd3ac83..0c46a603 100644 --- a/chrome/browser/ui/cocoa/bubble_anchor_helper.mm +++ b/chrome/browser/ui/cocoa/bubble_anchor_helper.mm
@@ -38,8 +38,10 @@ NSPoint anchor; NSWindow* parentWindow = browser->window()->GetNativeWindow(); if (has_location_bar) { + BrowserWindowController* browserWindowController = + [BrowserWindowController browserWindowControllerForWindow:parentWindow]; LocationBarViewMac* location_bar = - [[parentWindow windowController] locationBarBridge]; + [browserWindowController locationBarBridge]; anchor = location_bar->GetPageInfoBubblePoint(); } else { // Position the bubble on the left of the screen if there is no page info
diff --git a/chrome/browser/ui/cocoa/chrome_browser_window.mm b/chrome/browser/ui/cocoa/chrome_browser_window.mm index 6470d5c1..a644b43 100644 --- a/chrome/browser/ui/cocoa/chrome_browser_window.mm +++ b/chrome/browser/ui/cocoa/chrome_browser_window.mm
@@ -6,6 +6,7 @@ #include "base/logging.h" #include "chrome/browser/themes/theme_properties.h" +#import "chrome/browser/ui/cocoa/tabs/tab_window_controller.h" #import "chrome/browser/ui/cocoa/themed_window.h" #include "ui/base/theme_provider.h" @@ -26,24 +27,28 @@ @implementation ChromeBrowserWindow - (const ui::ThemeProvider*)themeProvider { - id delegate = [self delegate]; - if (![delegate respondsToSelector:@selector(themeProvider)]) + id tabWindowController = + [TabWindowController tabWindowControllerForWindow:self]; + if (![tabWindowController respondsToSelector:@selector(themeProvider)]) return NULL; - return [delegate themeProvider]; + return [tabWindowController themeProvider]; } - (ThemedWindowStyle)themedWindowStyle { - id delegate = [self delegate]; - if (![delegate respondsToSelector:@selector(themedWindowStyle)]) + id tabWindowController = + [TabWindowController tabWindowControllerForWindow:self]; + if (![tabWindowController respondsToSelector:@selector(themedWindowStyle)]) return THEMED_NORMAL; - return [delegate themedWindowStyle]; + return [tabWindowController themedWindowStyle]; } - (NSPoint)themeImagePositionForAlignment:(ThemeImageAlignment)alignment { - id delegate = [self delegate]; - if (![delegate respondsToSelector:@selector(themeImagePositionForAlignment:)]) + id tabWindowController = + [TabWindowController tabWindowControllerForWindow:self]; + if (![tabWindowController + respondsToSelector:@selector(themeImagePositionForAlignment:)]) return NSZeroPoint; - return [delegate themeImagePositionForAlignment:alignment]; + return [tabWindowController themeImagePositionForAlignment:alignment]; } - (BOOL)inIncognitoMode {
diff --git a/chrome/browser/ui/cocoa/chrome_command_dispatcher_delegate.mm b/chrome/browser/ui/cocoa/chrome_command_dispatcher_delegate.mm index f36b4bd..f6e7eb96 100644 --- a/chrome/browser/ui/cocoa/chrome_command_dispatcher_delegate.mm +++ b/chrome/browser/ui/cocoa/chrome_command_dispatcher_delegate.mm
@@ -89,7 +89,8 @@ // let the extension system try to handle the event. In case this is a // redispatched event, [event window] gives the correct window. if ([event window]) { - BrowserWindowController* controller = [[event window] windowController]; + BrowserWindowController* controller = [BrowserWindowController + browserWindowControllerForWindow:[event window]]; // |controller| is only set in Cocoa. In toolkit-views extension commands // are handled by BrowserView. if ([controller respondsToSelector:@selector(handledByExtensionCommand:
diff --git a/chrome/browser/ui/cocoa/framed_browser_window.mm b/chrome/browser/ui/cocoa/framed_browser_window.mm index ac46eae5..c564b79 100644 --- a/chrome/browser/ui/cocoa/framed_browser_window.mm +++ b/chrome/browser/ui/cocoa/framed_browser_window.mm
@@ -88,8 +88,7 @@ - (BOOL)makeFirstResponder:(NSResponder*)responder { BrowserWindowController* bwc = - base::mac::ObjCCastStrict<BrowserWindowController>( - [self windowController]); + [BrowserWindowController browserWindowControllerForWindow:self]; [bwc firstResponderUpdated:responder]; return [super makeFirstResponder:responder]; } @@ -192,8 +191,7 @@ - (NSTouchBar*)makeTouchBar { if (@available(macOS 10.12.2, *)) { BrowserWindowController* bwc = - base::mac::ObjCCastStrict<BrowserWindowController>( - [self windowController]); + [BrowserWindowController browserWindowControllerForWindow:self]; return [[bwc browserWindowTouchBar] makeTouchBar]; } else { return nil;
diff --git a/chrome/browser/ui/cocoa/page_info/page_info_bubble_controller.mm b/chrome/browser/ui/cocoa/page_info/page_info_bubble_controller.mm index 38af117..dd8e013 100644 --- a/chrome/browser/ui/cocoa/page_info/page_info_bubble_controller.mm +++ b/chrome/browser/ui/cocoa/page_info/page_info_bubble_controller.mm
@@ -298,7 +298,8 @@ } - (void)showWindow:(id)sender { - BrowserWindowController* controller = [[self parentWindow] windowController]; + BrowserWindowController* controller = [BrowserWindowController + browserWindowControllerForWindow:[self parentWindow]]; LocationBarViewMac* locationBar = [controller locationBarBridge]; if (locationBar) { decoration_ = locationBar->page_info_decoration();
diff --git a/chrome/browser/ui/cocoa/profiles/avatar_base_controller.mm b/chrome/browser/ui/cocoa/profiles/avatar_base_controller.mm index 9a77b3d..6750f55 100644 --- a/chrome/browser/ui/cocoa/profiles/avatar_base_controller.mm +++ b/chrome/browser/ui/cocoa/profiles/avatar_base_controller.mm
@@ -184,12 +184,11 @@ DCHECK(chrome::IsCommandEnabled(browser_, IDC_SHOW_AVATAR_MENU)); - NSWindowController* wc = - [browser_->window()->GetNativeWindow() windowController]; - if ([wc isKindOfClass:[BrowserWindowController class]]) { - [static_cast<BrowserWindowController*>(wc) - lockToolbarVisibilityForOwner:self - withAnimation:NO]; + BrowserWindowController* bwc = [BrowserWindowController + browserWindowControllerForWindow:browser_->window()->GetNativeWindow()]; + + if (bwc) { + [bwc lockToolbarVisibilityForOwner:self withAnimation:NO]; } // The new avatar bubble does not have an arrow, and it should be anchored @@ -233,12 +232,10 @@ } - (void)bubbleWillClose { - NSWindowController* wc = - [browser_->window()->GetNativeWindow() windowController]; - if ([wc isKindOfClass:[BrowserWindowController class]]) { - [static_cast<BrowserWindowController*>(wc) - releaseToolbarVisibilityForOwner:self - withAnimation:YES]; + BrowserWindowController* bwc = [BrowserWindowController + browserWindowControllerForWindow:browser_->window()->GetNativeWindow()]; + if (bwc) { + [bwc releaseToolbarVisibilityForOwner:self withAnimation:YES]; } profileChooserViewObserverBridge_.reset(); menuController_ = nil;
diff --git a/chrome/browser/ui/cocoa/share_menu_controller.mm b/chrome/browser/ui/cocoa/share_menu_controller.mm index 31b0f39..dc36394 100644 --- a/chrome/browser/ui/cocoa/share_menu_controller.mm +++ b/chrome/browser/ui/cocoa/share_menu_controller.mm
@@ -155,7 +155,9 @@ - (void)saveTransitionDataFromBrowser:(Browser*)browser { windowForShare_ = browser->window()->GetNativeWindow(); - NSView* contentsView = [[windowForShare_ windowController] tabContentArea]; + TabWindowController* tabWindowController = + [TabWindowController tabWindowControllerForWindow:windowForShare_]; + NSView* contentsView = [tabWindowController tabContentArea]; NSRect rectInWindow = [[contentsView superview] convertRect:[contentsView frame] toView:nil]; rectForShare_ = [windowForShare_ convertRectToScreen:rectInWindow];
diff --git a/chrome/browser/ui/cocoa/tab_dialogs_views_mac.mm b/chrome/browser/ui/cocoa/tab_dialogs_views_mac.mm index 4531c02..d87aab9 100644 --- a/chrome/browser/ui/cocoa/tab_dialogs_views_mac.mm +++ b/chrome/browser/ui/cocoa/tab_dialogs_views_mac.mm
@@ -64,7 +64,10 @@ // earlier because the bubble is shown on mouse release (but dismissed on // mouse pressed). A Cocoa browser does both on mouse pressed, so a check // when showing is sufficient. - if (ManagePasswordsBubbleDelegateViewBase::manage_password_bubble()) + if (ManagePasswordsBubbleDelegateViewBase::manage_password_bubble() && + ManagePasswordsBubbleDelegateViewBase::manage_password_bubble() + ->GetWidget() + ->IsVisible()) return; Browser* browser = chrome::FindBrowserWithWebContents(web_contents());
diff --git a/chrome/browser/ui/cocoa/tabbed_browser_window.mm b/chrome/browser/ui/cocoa/tabbed_browser_window.mm index ce42d44..864789d9 100644 --- a/chrome/browser/ui/cocoa/tabbed_browser_window.mm +++ b/chrome/browser/ui/cocoa/tabbed_browser_window.mm
@@ -196,7 +196,8 @@ // If there is a profile avatar icon present, shift the button over by its // width and some padding. The new avatar button is displayed to the right // of the fullscreen icon, so it doesn't need to be shifted. - auto* bwc = static_cast<BrowserWindowController*>([self windowController]); + BrowserWindowController* bwc = + [BrowserWindowController browserWindowControllerForWindow:self]; if ([bwc shouldShowAvatar] && ![bwc shouldUseNewAvatarButton]) { NSView* avatarButton = [[bwc avatarButtonController] view]; return NSWidth([avatarButton frame]) - 3;
diff --git a/chrome/browser/ui/cocoa/tabs/tab_strip_drag_controller.mm b/chrome/browser/ui/cocoa/tabs/tab_strip_drag_controller.mm index a1a84a8..341afe1 100644 --- a/chrome/browser/ui/cocoa/tabs/tab_strip_drag_controller.mm +++ b/chrome/browser/ui/cocoa/tabs/tab_strip_drag_controller.mm
@@ -71,7 +71,8 @@ sourceWindowFrame_ = [sourceWindow_ frame]; sourceTabFrame_ = [[tab view] frame]; - sourceController_ = [sourceWindow_ windowController]; + sourceController_ = + [TabWindowController tabWindowControllerForWindow:sourceWindow_]; draggedTab_ = tab; tabWasDragged_ = NO; tearTime_ = 0.0; @@ -473,7 +474,7 @@ // Force redraw to avoid flashes of old content before returning to event // loop. [[targetController_ window] display]; - [targetController_ showWindow:nil]; + [[targetController_ nsWindowController] showWindow:nil]; [draggedController_ removeOverlay]; } else { // Only move the window around on screen. Make sure it's set back to @@ -523,12 +524,11 @@ return NO; } - NSWindowController* controller = [sourceWindow_ windowController]; - if ([controller isKindOfClass:[TabWindowController class]]) { - TabWindowController* realController = - static_cast<TabWindowController*>(controller); + TabWindowController* controller = + [TabWindowController tabWindowControllerForWindow:sourceWindow_]; + if (controller) { for (TabView* tabView in tabs) { - if (![realController isTabDraggable:tabView]) + if (![controller isTabDraggable:tabView]) return NO; } } @@ -559,13 +559,10 @@ // Skip windows on the wrong space. if (![window isOnActiveSpace]) continue; - NSWindowController* controller = [window windowController]; - if ([controller isKindOfClass:[TabWindowController class]]) { - TabWindowController* realController = - static_cast<TabWindowController*>(controller); - if ([realController canReceiveFrom:dragController]) - [targets addObject:controller]; - } + TabWindowController* controller = + [TabWindowController tabWindowControllerForWindow:window]; + if ([controller canReceiveFrom:dragController]) + [targets addObject:controller]; } return targets; }
diff --git a/chrome/browser/ui/cocoa/tabs/tab_window_controller.h b/chrome/browser/ui/cocoa/tabs/tab_window_controller.h index a8c312a3b..523de75 100644 --- a/chrome/browser/ui/cocoa/tabs/tab_window_controller.h +++ b/chrome/browser/ui/cocoa/tabs/tab_window_controller.h
@@ -11,6 +11,9 @@ // know anything about the actual tab implementation or model, as that is fairly // application-specific. It only provides an API to be overridden by subclasses // to fill in the details. +// Note that under the hood the TabWindowController is neither an +// NSWindowController nor its window's delegate, though it receives all +// NSWindowDelegate methods as if it were. #import <Cocoa/Cocoa.h> @@ -23,7 +26,7 @@ @class TabStripView; @class TabView; -@interface TabWindowController : NSWindowController<NSWindowDelegate> { +@interface TabWindowController : NSObject<NSWindowDelegate> { @private // Wrapper view around web content, and the developer tools view. base::scoped_nsobject<FastResizeView> tabContentArea_; @@ -54,6 +57,14 @@ BOOL closeDeferred_; // If YES, call performClose: in removeOverlay:. } +// Returns the NSWindowController that manages the TabWindowController's +// NSWindow. In the past the TabWindowController was also the window's +// NSWindowController but they are now separate objects. Use +// +tabWindowControllerForWindow: to retrieve a TabWindowController from a +// given NSWindow. +@property(readonly, nonatomic) + NSWindowController<NSWindowDelegate>* nsWindowController; +@property(retain, nonatomic) NSWindow* window; @property(readonly, nonatomic) API_AVAILABLE(macos(10.10)) NSVisualEffectView* visualEffectView; @property(readonly, nonatomic) NSView* tabStripBackgroundView; @@ -61,6 +72,10 @@ @property(readonly, nonatomic) FastResizeView* tabContentArea; @property(readonly, nonatomic) NSView* chromeContentView; +// A convenience class method which returns the |TabWindowController| for a +// given window, or nil if no window in the chain has one. ++ (TabWindowController*)tabWindowControllerForWindow:(NSWindow*)window; + // This is the designated initializer for this class. - (id)initTabWindowControllerWithTabStrip:(BOOL)hasTabStrip titleBar:(BOOL)hasTitleBar;
diff --git a/chrome/browser/ui/cocoa/tabs/tab_window_controller.mm b/chrome/browser/ui/cocoa/tabs/tab_window_controller.mm index 8be82134..90a848c 100644 --- a/chrome/browser/ui/cocoa/tabs/tab_window_controller.mm +++ b/chrome/browser/ui/cocoa/tabs/tab_window_controller.mm
@@ -4,7 +4,10 @@ #import "chrome/browser/ui/cocoa/tabs/tab_window_controller.h" +#import <objc/runtime.h> + #include "base/logging.h" +#import "base/mac/foundation_util.h" #import "base/mac/sdk_forward_declarations.h" #import "chrome/browser/ui/cocoa/browser_window_layout.h" #import "chrome/browser/ui/cocoa/fast_resize_view.h" @@ -18,7 +21,63 @@ #include "ui/base/material_design/material_design_controller.h" #include "ui/base/theme_provider.h" -@interface TabWindowController () +// As of macOS 10.13 NSWindow lifetimes after closing are unpredictable. Chrome +// frees resources on window close so this new behavior created problems such as +// browser tests failing to complete (see https://crbug.com/749196 ). To work +// around this new behavior TabWindowController no longer acts as the NSWindow's +// NSWindowController or NSWindowDelegate but instead uses a +// TabWindowControllerProxy instance. The TabWindowController and its subclasses +// still expect to receive NSWindowDelegate messages, which the +// TabWindowControllerProxy forwards along. +@interface TabWindowControllerProxy : NSWindowController<NSWindowDelegate> +@property(assign, nonatomic) TabWindowController* tabWindowController; +@end + +@implementation TabWindowControllerProxy + +@synthesize tabWindowController = tabWindowController_; + +- (void)dealloc { + // The TabWindowControllerProxy should outlive the TabWindowController. + DCHECK(!tabWindowController_); + [super dealloc]; +} + +- (BOOL)respondsToSelector:(SEL)aSelector { + if ([super respondsToSelector:aSelector]) { + return YES; + } + + // Only forward methods from the NSWindowDelegate protcol. + Protocol* nsWindowDelegateProtocol = objc_getProtocol("NSWindowDelegate"); + struct objc_method_description methodDescription = + protocol_getMethodDescription(nsWindowDelegateProtocol, aSelector, NO, + YES); + + return methodDescription.name + ? [self.tabWindowController respondsToSelector:aSelector] + : NO; +} + +- (NSMethodSignature*)methodSignatureForSelector:(SEL)aSelector { + NSMethodSignature* signature = [super methodSignatureForSelector:aSelector]; + + return signature + ? signature + : [self.tabWindowController methodSignatureForSelector:aSelector]; +} + +- (void)forwardInvocation:(NSInvocation*)anInvocation { + [anInvocation setTarget:self.tabWindowController]; + [anInvocation invoke]; +} + +@end + +@interface TabWindowController () { + base::scoped_nsobject<TabWindowControllerProxy> nsWindowController_; +} + - (void)setUseOverlay:(BOOL)useOverlay; // The tab strip background view should always be inserted as the back-most @@ -85,20 +144,39 @@ @implementation TabWindowController ++ (TabWindowController*)tabWindowControllerForWindow:(NSWindow*)window { + while (window) { + TabWindowControllerProxy* nsWindowController = + base::mac::ObjCCast<TabWindowControllerProxy>( + [window windowController]); + + if (nsWindowController) { + return [nsWindowController tabWindowController]; + } + window = [window parentWindow]; + } + return nil; +} + - (id)initTabWindowControllerWithTabStrip:(BOOL)hasTabStrip titleBar:(BOOL)hasTitleBar { const CGFloat kDefaultWidth = WindowSizer::kWindowMaxDefaultWidth; const CGFloat kDefaultHeight = 600; - NSRect contentRect = NSMakeRect(60, 229, kDefaultWidth, kDefaultHeight); - base::scoped_nsobject<FramedBrowserWindow> window( - [(hasTabStrip ? [TabbedBrowserWindow alloc] : [FramedBrowserWindow alloc]) - initWithContentRect:contentRect]); - [window setReleasedWhenClosed:YES]; - [window setAutorecalculatesKeyViewLoop:YES]; + if (self = [self init]) { + NSRect contentRect = NSMakeRect(60, 229, kDefaultWidth, kDefaultHeight); + base::scoped_nsobject<FramedBrowserWindow> window( + [(hasTabStrip + ? [TabbedBrowserWindow alloc] + : [FramedBrowserWindow alloc]) initWithContentRect:contentRect]); + [window setReleasedWhenClosed:YES]; + [window setAutorecalculatesKeyViewLoop:YES]; - if ((self = [super initWithWindow:window])) { - [[self window] setDelegate:self]; + nsWindowController_.reset( + [[TabWindowControllerProxy alloc] initWithWindow:window]); + [nsWindowController_ setTabWindowController:self]; + + [[self window] setDelegate:nsWindowController_]; chromeContentView_.reset([[ChromeContentView alloc] initWithFrame:NSMakeRect(0, 0, kDefaultWidth, kDefaultHeight)]); @@ -109,8 +187,8 @@ tabContentArea_.reset( [[FastResizeView alloc] initWithFrame:[chromeContentView_ bounds]]); - [tabContentArea_ setAutoresizingMask:NSViewWidthSizable | - NSViewHeightSizable]; + [tabContentArea_ + setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; [chromeContentView_ addSubview:tabContentArea_]; // tabStripBackgroundView_ draws the theme image behind the tab strip area. @@ -127,18 +205,18 @@ [self insertTabStripBackgroundViewIntoWindow:window titleBar:hasTitleBar]; tabStripView_.reset([[TabStripView alloc] - initWithFrame:NSMakeRect( - 0, 0, kDefaultWidth, chrome::kTabStripHeight)]); - [tabStripView_ setAutoresizingMask:NSViewWidthSizable | - NSViewMinYMargin]; + initWithFrame:NSMakeRect(0, 0, kDefaultWidth, + chrome::kTabStripHeight)]); + [tabStripView_ setAutoresizingMask:NSViewWidthSizable | NSViewMinYMargin]; if (hasTabStrip) [windowView addSubview:tabStripView_]; - // |windowWillEnterFullScreen:| and |windowWillExitFullScreen:| are already - // called because self is a delegate for the window. However this class is - // designed for subclassing and can not implement NSWindowDelegate methods - // (because subclasses can do so as well and they should be able to). - // TODO(crbug.com/654656): Move |visualEffectView_| to subclass. + // |windowWillEnterFullScreen:| and |windowWillExitFullScreen:| are + // already called because self is a delegate for the window. However this + // class is designed for subclassing and can not implement + // NSWindowDelegate methods (because subclasses can do so as well and they + // should be able to). TODO(crbug.com/654656): Move |visualEffectView_| to + // subclass. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowWillEnterFullScreenNotification:) @@ -150,14 +228,30 @@ name:NSWindowWillExitFullScreenNotification object:window]; } + return self; } - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; + [[self window] setDelegate:nil]; + [nsWindowController_ setTabWindowController:nil]; + [nsWindowController_ setWindow:nil]; [super dealloc]; } +- (NSWindow*)window { + return [nsWindowController_ window]; +} + +- (void)setWindow:(NSWindow*)aWindow { + [nsWindowController_ setWindow:aWindow]; +} + +- (NSWindowController*)nsWindowController { + return nsWindowController_; +} + - (NSVisualEffectView*)visualEffectView { return visualEffectView_; }
diff --git a/chrome/browser/ui/cocoa/translate/translate_bubble_controller.mm b/chrome/browser/ui/cocoa/translate/translate_bubble_controller.mm index 105f3d8..e73ed08 100644 --- a/chrome/browser/ui/cocoa/translate/translate_bubble_controller.mm +++ b/chrome/browser/ui/cocoa/translate/translate_bubble_controller.mm
@@ -212,8 +212,9 @@ } - (void)showWindow:(id)sender { - LocationBarViewMac* locationBar = - [[[self parentWindow] windowController] locationBarBridge]; + BrowserWindowController* browserWindowController = [BrowserWindowController + browserWindowControllerForWindow:self.parentWindow]; + LocationBarViewMac* locationBar = [browserWindowController locationBarBridge]; if (locationBar) { NSPoint anchorPoint = locationBar->GetBubblePointForDecoration([self decorationForBubble]); @@ -225,8 +226,9 @@ } - (LocationBarDecoration*)decorationForBubble { - LocationBarViewMac* locationBar = - [[[self parentWindow] windowController] locationBarBridge]; + BrowserWindowController* browserWindowController = [BrowserWindowController + browserWindowControllerForWindow:self.parentWindow]; + LocationBarViewMac* locationBar = [browserWindowController locationBarBridge]; return locationBar ? locationBar->translate_decoration() : nullptr; }
diff --git a/chrome/browser/ui/cocoa/view_id_util.mm b/chrome/browser/ui/cocoa/view_id_util.mm index 95748cc..7859bad 100644 --- a/chrome/browser/ui/cocoa/view_id_util.mm +++ b/chrome/browser/ui/cocoa/view_id_util.mm
@@ -63,7 +63,8 @@ // As tabs can be created, destroyed or rearranged dynamically, we handle them // here specially. if (viewID >= VIEW_ID_TAB_0 && viewID <= VIEW_ID_TAB_LAST) { - BrowserWindowController* windowController = [window windowController]; + BrowserWindowController* windowController = + [BrowserWindowController browserWindowControllerForWindow:window]; DCHECK([windowController isKindOfClass:[BrowserWindowController class]]); TabStripController* tabStripController = [windowController tabStripController];
diff --git a/chrome/browser/ui/content_settings/content_setting_image_model_browsertest.cc b/chrome/browser/ui/content_settings/content_setting_image_model_browsertest.cc index 4d8e4a23..f9ca7ce 100644 --- a/chrome/browser/ui/content_settings/content_setting_image_model_browsertest.cc +++ b/chrome/browser/ui/content_settings/content_setting_image_model_browsertest.cc
@@ -4,13 +4,18 @@ #include "chrome/browser/ui/content_settings/content_setting_image_model.h" +#include <string> + #include "base/memory/ptr_util.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/download/download_request_limiter.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_content_setting_bubble_model_delegate.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/test/base/in_process_browser_test.h" +#include "components/subresource_filter/core/browser/subresource_filter_constants.h" +#include "content/public/test/test_navigation_observer.h" using content::WebContents; using ImageType = ContentSettingImageModel::ImageType; @@ -101,3 +106,25 @@ browser()->tab_strip_model()->AppendWebContents(other_web_contents, true); EXPECT_TRUE(model->ShouldRunAnimation(other_web_contents)); } + +// Tests that we go to the correct link when learn more is clicked in Ads +// bubble. +IN_PROC_BROWSER_TEST_F(ContentSettingImageModelBrowserTest, + AdsLearnMoreLinkClicked) { + WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + + auto model = ContentSettingImageModel::CreateForContentType(ImageType::ADS); + Profile* profile = browser()->profile(); + std::unique_ptr<ContentSettingBubbleModel> bubble(model->CreateBubbleModel( + browser()->content_setting_bubble_model_delegate(), web_contents, + profile)); + + content::TestNavigationObserver observer(nullptr); + observer.StartWatchingNewWebContents(); + bubble->OnLearnMoreClicked(); + observer.Wait(); + + std::string link_value(subresource_filter::kLearnMoreLink); + EXPECT_EQ(link_value, observer.last_navigation_url().spec()); +}
diff --git a/chrome/browser/ui/overlay/overlay_surface_embedder.cc b/chrome/browser/ui/overlay/overlay_surface_embedder.cc index f0bf0c3..b7c0581 100644 --- a/chrome/browser/ui/overlay/overlay_surface_embedder.cc +++ b/chrome/browser/ui/overlay/overlay_surface_embedder.cc
@@ -4,9 +4,6 @@ #include "chrome/browser/ui/overlay/overlay_surface_embedder.h" -#include <memory> - -#include "components/viz/common/surfaces/stub_surface_reference_factory.h" #include "ui/compositor/layer.h" OverlaySurfaceEmbedder::OverlaySurfaceEmbedder(OverlayWindow* window) @@ -18,7 +15,6 @@ // the surface layer. surface_layer_->SetFillsBoundsOpaquely(false); window_->GetLayer()->Add(surface_layer_.get()); - ref_factory_ = new viz::StubSurfaceReferenceFactory(); } OverlaySurfaceEmbedder::~OverlaySurfaceEmbedder() = default; @@ -27,5 +23,5 @@ const viz::SurfaceId& surface_id) { // SurfaceInfo has information about the embedded surface. surface_layer_->SetShowPrimarySurface(surface_id, window_->GetBounds().size(), - SK_ColorBLACK, ref_factory_); + SK_ColorBLACK); }
diff --git a/chrome/browser/ui/overlay/overlay_surface_embedder.h b/chrome/browser/ui/overlay/overlay_surface_embedder.h index 841a037..a160f06 100644 --- a/chrome/browser/ui/overlay/overlay_surface_embedder.h +++ b/chrome/browser/ui/overlay/overlay_surface_embedder.h
@@ -6,7 +6,6 @@ #define CHROME_BROWSER_UI_OVERLAY_OVERLAY_SURFACE_EMBEDDER_H_ #include "chrome/browser/ui/overlay/overlay_window.h" -#include "components/viz/common/surfaces/surface_reference_factory.h" namespace viz { class SurfaceId; @@ -29,8 +28,6 @@ // Contains the client's content. std::unique_ptr<ui::Layer> surface_layer_; - scoped_refptr<viz::SurfaceReferenceFactory> ref_factory_; - DISALLOW_COPY_AND_ASSIGN(OverlaySurfaceEmbedder); };
diff --git a/chrome/browser/ui/passwords/manage_passwords_bubble_model.cc b/chrome/browser/ui/passwords/manage_passwords_bubble_model.cc index 1d6f14d..66838e1 100644 --- a/chrome/browser/ui/passwords/manage_passwords_bubble_model.cc +++ b/chrome/browser/ui/passwords/manage_passwords_bubble_model.cc
@@ -270,6 +270,7 @@ DisplayReason display_reason) : password_overridden_(false), delegate_(std::move(delegate)), + interaction_reported_(false), metrics_recorder_(delegate_->GetPasswordFormMetricsRecorder()) { origin_ = delegate_->GetOrigin(); state_ = delegate_->GetState(); @@ -392,9 +393,16 @@ } ManagePasswordsBubbleModel::~ManagePasswordsBubbleModel() { + if (!interaction_reported_) + OnBubbleClosing(); +} + +void ManagePasswordsBubbleModel::OnBubbleClosing() { interaction_keeper_->ReportInteractions(this); if (delegate_) delegate_->OnBubbleHidden(); + delegate_.reset(); + interaction_reported_ = true; } void ManagePasswordsBubbleModel::OnNeverForThisSiteClicked() {
diff --git a/chrome/browser/ui/passwords/manage_passwords_bubble_model.h b/chrome/browser/ui/passwords/manage_passwords_bubble_model.h index b3d7aca..0969670 100644 --- a/chrome/browser/ui/passwords/manage_passwords_bubble_model.h +++ b/chrome/browser/ui/passwords/manage_passwords_bubble_model.h
@@ -42,6 +42,10 @@ DisplayReason reason); ~ManagePasswordsBubbleModel(); + // The method MAY BE called to record the statistics while the bubble is being + // closed. Otherwise, it is called later on when the model is destroyed. + void OnBubbleClosing(); + // Called by the view code when the "Nope" button in clicked by the user in // update bubble. void OnNopeUpdateClicked(); @@ -187,6 +191,10 @@ // A bridge to ManagePasswordsUIController instance. base::WeakPtr<PasswordsModelDelegate> delegate_; + // True if the model has already recorded all the necessary statistics when + // the bubble is closing. + bool interaction_reported_; + // True iff password revealing should require re-auth for privacy reasons. bool password_revealing_requires_reauth_;
diff --git a/chrome/browser/ui/passwords/manage_passwords_bubble_model_unittest.cc b/chrome/browser/ui/passwords/manage_passwords_bubble_model_unittest.cc index ad25612..4a778ff 100644 --- a/chrome/browser/ui/passwords/manage_passwords_bubble_model_unittest.cc +++ b/chrome/browser/ui/passwords/manage_passwords_bubble_model_unittest.cc
@@ -223,8 +223,9 @@ void ManagePasswordsBubbleModelTest:: DestroyModelAndVerifyControllerExpectations() { EXPECT_CALL(*controller(), OnBubbleHidden()); - model_.reset(); + model_->OnBubbleClosing(); ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(controller())); + model_.reset(); } void ManagePasswordsBubbleModelTest::DestroyModelExpectReason(
diff --git a/chrome/browser/ui/sync/bubble_sync_promo_delegate.h b/chrome/browser/ui/sync/bubble_sync_promo_delegate.h index a62f415a..22eb2986 100644 --- a/chrome/browser/ui/sync/bubble_sync_promo_delegate.h +++ b/chrome/browser/ui/sync/bubble_sync_promo_delegate.h
@@ -7,6 +7,9 @@ #include "components/signin/core/browser/account_info.h" +#include "build/buildflag.h" +#include "components/signin/core/browser/signin_features.h" + class BubbleSyncPromoDelegate { public: virtual ~BubbleSyncPromoDelegate() {} @@ -14,8 +17,10 @@ // Shows the chrome sign-in page. virtual void ShowBrowserSignin() = 0; +#if BUILDFLAG(ENABLE_DICE_SUPPORT) // Enables sync for |account|. virtual void EnableSync(const AccountInfo& account) = 0; +#endif }; #endif // CHROME_BROWSER_UI_SYNC_BUBBLE_SYNC_PROMO_DELEGATE_H_
diff --git a/chrome/browser/ui/views/extensions/extension_installed_bubble_view.cc b/chrome/browser/ui/views/extensions/extension_installed_bubble_view.cc index ffdcf552..a5ccfaa 100644 --- a/chrome/browser/ui/views/extensions/extension_installed_bubble_view.cc +++ b/chrome/browser/ui/views/extensions/extension_installed_bubble_view.cc
@@ -13,6 +13,7 @@ #include "base/metrics/user_metrics_action.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" +#include "build/buildflag.h" #include "chrome/browser/extensions/extension_action_manager.h" #include "chrome/browser/platform_util.h" #include "chrome/browser/ui/browser.h" @@ -29,6 +30,7 @@ #include "chrome/grit/generated_resources.h" #include "components/bubble/bubble_controller.h" #include "components/signin/core/browser/account_info.h" +#include "components/signin/core/browser/signin_features.h" #include "extensions/common/extension.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/ui_features.h" @@ -139,7 +141,9 @@ // BubbleSyncPromoDelegate: void ShowBrowserSignin() override; +#if BUILDFLAG(ENABLE_DICE_SUPPORT) void EnableSync(const AccountInfo& account_info) override; +#endif // views::LinkListener: void LinkClicked(views::Link* source, int event_flags) override; @@ -291,10 +295,12 @@ CloseBubble(BUBBLE_CLOSE_NAVIGATED); } +#if BUILDFLAG(ENABLE_DICE_SUPPORT) void ExtensionInstalledBubbleView::EnableSync(const AccountInfo& account) { NOTREACHED() << "Extension installl bubble does not display the DICE " << "personalized sign-in promo asking the user to enable sync."; } +#endif void ExtensionInstalledBubbleView::LinkClicked(views::Link* source, int event_flags) {
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index 246c871f..1bb3be2 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -751,6 +751,14 @@ // we don't want any WebContents to be attached, so that we // avoid an unnecessary resize and re-layout of a WebContents. if (change_tab_contents) { + if (GetWidget() && + (contents_web_view_->HasFocus() || devtools_web_view_->HasFocus())) { + // Manually clear focus before setting focus behavior so that the focus + // is not temporarily advanced to an arbitrary place in the UI via + // SetFocusBehavior(FocusBehavior::NEVER), confusing screen readers. + // The saved focus for new_contents is restored after it is attached. + GetWidget()->GetFocusManager()->ClearFocus(); + } contents_web_view_->SetWebContents(nullptr); devtools_web_view_->SetWebContents(nullptr); }
diff --git a/chrome/browser/ui/views/frame/browser_view_focus_uitest.cc b/chrome/browser/ui/views/frame/browser_view_focus_uitest.cc index 01138ff..afb9a71d 100644 --- a/chrome/browser/ui/views/frame/browser_view_focus_uitest.cc +++ b/chrome/browser/ui/views/frame/browser_view_focus_uitest.cc
@@ -14,6 +14,8 @@ #include "chrome/test/base/interactive_test_utils.h" #include "chrome/test/base/ui_test_utils.h" #include "net/test/embedded_test_server/embedded_test_server.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "ui/views/controls/webview/webview.h" #include "ui/views/focus/focus_manager.h" #include "ui/views/view.h" #include "url/gurl.h" @@ -91,3 +93,72 @@ browser_view2->Close(); #endif } + +// Helper class that tracks view classes receiving focus. +class FocusedViewClassRecorder : public views::FocusChangeListener { + public: + explicit FocusedViewClassRecorder(views::FocusManager* focus_manager) + : focus_manager_(focus_manager) { + focus_manager_->AddFocusChangeListener(this); + } + + ~FocusedViewClassRecorder() override { + focus_manager_->RemoveFocusChangeListener(this); + } + + std::vector<std::string>& GetFocusClasses() { return focus_classes_; } + + private: + // Inherited from views::FocusChangeListener + void OnWillChangeFocus(views::View* focused_before, + views::View* focused_now) override {} + void OnDidChangeFocus(views::View* focused_before, + views::View* focused_now) override { + std::string class_name; + if (focused_now) + class_name = focused_now->GetClassName(); + focus_classes_.push_back(class_name); + } + + views::FocusManager* focus_manager_; + std::vector<std::string> focus_classes_; + + DISALLOW_COPY_AND_ASSIGN(FocusedViewClassRecorder); +}; + +// Switching tabs does not focus views unexpectedly. +// (bug http://crbug.com/791757, bug http://crbug.com/777051) +IN_PROC_BROWSER_TEST_F(BrowserViewFocusTest, TabChangesAvoidSpuriousFocus) { + ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser())); + ASSERT_TRUE(embedded_test_server()->Start()); + + // First we navigate to our test page. + GURL url = embedded_test_server()->GetURL(kSimplePage); + ui_test_utils::NavigateToURL(browser(), url); + + // Create another tab. + AddTabAtIndex(1, url, ui::PAGE_TRANSITION_TYPED); + + // Begin recording focus changes. + gfx::NativeWindow window = browser()->window()->GetNativeWindow(); + views::Widget* widget = views::Widget::GetWidgetForNativeWindow(window); + views::FocusManager* focus_manager = widget->GetFocusManager(); + FocusedViewClassRecorder focus_change_recorder(focus_manager); + + // Switch tabs using ctrl+tab. + ASSERT_TRUE(ui_test_utils::SendKeyPressSync(browser(), ui::VKEY_TAB, true, + false, false, false)); + + std::vector<std::string>& focused_classes = + focus_change_recorder.GetFocusClasses(); + + // Everything before the last focus must be either "" (nothing) or a WebView. + for (size_t index = 0; index < focused_classes.size() - 1; index++) { + EXPECT_THAT(focused_classes[index], + testing::AnyOf("", views::WebView::kViewClassName)); + } + + // Must end up focused on a WebView. + ASSERT_FALSE(focused_classes.empty()); + EXPECT_EQ(views::WebView::kViewClassName, focused_classes.back()); +}
diff --git a/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.cc b/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.cc index 69fbe08..f8ba00c 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.cc
@@ -185,6 +185,7 @@ // No matches or the IME is showing a popup window which may overlap // the omnibox popup window. Close any existing popup. if (popup_) { + NotifyAccessibilityEvent(ui::AX_EVENT_EXPANDED_CHANGED, true); size_animation_.Stop(); // NOTE: Do NOT use CloseNow() here, as we may be deep in a callstack @@ -294,6 +295,11 @@ return; } popup_->ShowInactive(); + + // Popup is now expanded and first item will be selected. + NotifyAccessibilityEvent(ui::AX_EVENT_EXPANDED_CHANGED, true); + if (result_view_at(0)) + result_view_at(0)->NotifyAccessibilityEvent(ui::AX_EVENT_SELECTION, true); } else { // Animate the popup shrinking, but don't animate growing larger since that // would make the popup feel less responsive. @@ -454,6 +460,12 @@ void OmniboxPopupContentsView::GetAccessibleNodeData( ui::AXNodeData* node_data) { node_data->role = ui::AX_ROLE_LIST_BOX; + if (IsOpen()) { + node_data->AddState(ui::AX_STATE_EXPANDED); + } else { + node_data->AddState(ui::AX_STATE_COLLAPSED); + node_data->AddState(ui::AX_STATE_INVISIBLE); + } } ////////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/ui/views/omnibox/omnibox_result_view_unittest.cc b/chrome/browser/ui/views/omnibox/omnibox_result_view_unittest.cc index 1b6974c..957eae43 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_result_view_unittest.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_result_view_unittest.cc
@@ -235,4 +235,7 @@ ui::AXNodeData popup_node_data; popup_view()->GetAccessibleNodeData(&popup_node_data); EXPECT_EQ(popup_node_data.role, ui::AX_ROLE_LIST_BOX); + EXPECT_FALSE(popup_node_data.HasState(ui::AX_STATE_EXPANDED)); + EXPECT_TRUE(popup_node_data.HasState(ui::AX_STATE_COLLAPSED)); + EXPECT_TRUE(popup_node_data.HasState(ui::AX_STATE_INVISIBLE)); }
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.h b/chrome/browser/ui/views/omnibox/omnibox_view_views.h index a2f7aba9..3d402d0f 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_view_views.h +++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.h
@@ -110,9 +110,16 @@ void AddedToWidget() override; void RemovedFromWidget() override; + protected: + // For testing only. + OmniboxPopupContentsView* GetPopupContentsView() const { + return popup_view_.get(); + } + private: FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsTest, CloseOmniboxPopupOnTextDrag); FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsTest, FriendlyAccessibleLabel); + FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsTest, AccessiblePopup); FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsTest, MaintainCursorAfterFocusCycle); FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsTest, OnBlur);
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views_browsertest.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views_browsertest.cc index 3f1b10c..312e210 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_view_views_browsertest.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_view_views_browsertest.cc
@@ -17,6 +17,7 @@ #include "chrome/browser/ui/view_ids.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/location_bar/location_bar_view.h" +#include "chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.h" #include "chrome/browser/ui/views/toolbar/toolbar_view.h" #include "chrome/grit/generated_resources.h" #include "chrome/test/base/in_process_browser_test.h" @@ -472,6 +473,10 @@ base::UTF8ToUTF16("https://www.google.com/#\u2603")); } +// Ensure that when the user navigates between suggestions, that the accessible +// value of the Omnibox includes helpful information for human comprehension, +// such as the document title. When the user begins to arrow left/right +// within the label or edit it, the value is presented as the pure editable URL. IN_PROC_BROWSER_TEST_F(OmniboxViewViewsTest, FriendlyAccessibleLabel) { OmniboxView* omnibox_view = nullptr; ASSERT_NO_FATAL_FAILURE(GetOmniboxViewForBrowser(browser(), &omnibox_view)); @@ -549,3 +554,53 @@ EXPECT_EQ(base::ASCIIToUTF16("hxps://google.com"), node_data.GetString16Attribute(ui::AX_ATTR_VALUE)); } + +// Ensure that the Omnibox popup exposes appropriate accessibility semantics, +// given a current state of open or closed. +IN_PROC_BROWSER_TEST_F(OmniboxViewViewsTest, AccessiblePopup) { + OmniboxView* omnibox_view = nullptr; + ASSERT_NO_FATAL_FAILURE(GetOmniboxViewForBrowser(browser(), &omnibox_view)); + OmniboxViewViews* omnibox_view_views = + static_cast<OmniboxViewViews*>(omnibox_view); + + base::string16 match_url = base::ASCIIToUTF16("https://google.com"); + AutocompleteMatch match(nullptr, 500, false, + AutocompleteMatchType::HISTORY_TITLE); + match.contents = match_url; + match.contents_class.push_back( + ACMatchClassification(0, ACMatchClassification::URL)); + match.destination_url = GURL(match_url); + match.description = base::ASCIIToUTF16("Google"); + match.allowed_to_be_default_match = true; + + OmniboxPopupContentsView* popup_view = + omnibox_view_views->GetPopupContentsView(); + ui::AXNodeData popup_node_data_1; + popup_view->GetAccessibleNodeData(&popup_node_data_1); + EXPECT_FALSE(popup_node_data_1.HasState(ui::AX_STATE_EXPANDED)); + EXPECT_TRUE(popup_node_data_1.HasState(ui::AX_STATE_COLLAPSED)); + EXPECT_TRUE(popup_node_data_1.HasState(ui::AX_STATE_INVISIBLE)); + + // Populate suggestions for the omnibox popup. + AutocompleteController* autocomplete_controller = + omnibox_view->model()->popup_model()->autocomplete_controller(); + AutocompleteResult& results = autocomplete_controller->result_; + ACMatches matches; + matches.push_back(match); + AutocompleteInput input(base::ASCIIToUTF16("g"), + metrics::OmniboxEventProto::OTHER, + TestSchemeClassifier()); + results.AppendMatches(input, matches); + results.SortAndCull( + input, TemplateURLServiceFactory::GetForProfile(browser()->profile())); + + // The omnibox popup should open with suggestions displayed. + chrome::FocusLocationBar(browser()); + omnibox_view->model()->popup_model()->OnResultChanged(); + EXPECT_TRUE(omnibox_view->model()->popup_model()->IsOpen()); + ui::AXNodeData popup_node_data_2; + popup_view->GetAccessibleNodeData(&popup_node_data_2); + EXPECT_TRUE(popup_node_data_2.HasState(ui::AX_STATE_EXPANDED)); + EXPECT_FALSE(popup_node_data_2.HasState(ui::AX_STATE_COLLAPSED)); + EXPECT_FALSE(popup_node_data_2.HasState(ui::AX_STATE_INVISIBLE)); +}
diff --git a/chrome/browser/ui/views/passwords/manage_password_update_pending_view.cc b/chrome/browser/ui/views/passwords/manage_password_update_pending_view.cc index a1ab097..36fdb543 100644 --- a/chrome/browser/ui/views/passwords/manage_password_update_pending_view.cc +++ b/chrome/browser/ui/views/passwords/manage_password_update_pending_view.cc
@@ -4,33 +4,39 @@ #include "chrome/browser/ui/views/passwords/manage_password_update_pending_view.h" -#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h" #include "chrome/browser/ui/views/passwords/credentials_selection_view.h" #include "chrome/browser/ui/views/passwords/manage_password_items_view.h" #include "chrome/browser/ui/views/passwords/manage_passwords_bubble_view.h" #include "chrome/grit/generated_resources.h" #include "ui/base/l10n/l10n_util.h" -#include "ui/views/controls/button/md_text_button.h" +#include "ui/views/bubble/bubble_frame_view.h" +#include "ui/views/controls/label.h" +#include "ui/views/controls/styled_label.h" #include "ui/views/layout/grid_layout.h" ManagePasswordUpdatePendingView::ManagePasswordUpdatePendingView( - ManagePasswordsBubbleView* parent) - : parent_(parent), selection_view_(nullptr) { - ChromeLayoutProvider* layout_provider = ChromeLayoutProvider::Get(); + content::WebContents* web_contents, + views::View* anchor_view, + const gfx::Point& anchor_point, + DisplayReason reason) + : ManagePasswordsBubbleDelegateViewBase(web_contents, + anchor_view, + anchor_point, + reason), + selection_view_(nullptr) { views::GridLayout* layout = SetLayoutManager(std::make_unique<views::GridLayout>(this)); layout->set_minimum_size( gfx::Size(ManagePasswordsBubbleView::kDesiredBubbleWidth, 0)); // Credential row. - if (parent->model()->ShouldShowMultipleAccountUpdateUI()) { + if (model()->ShouldShowMultipleAccountUpdateUI()) { ManagePasswordsBubbleView::BuildColumnSet( layout, ManagePasswordsBubbleView::SINGLE_VIEW_COLUMN_SET); layout->StartRow(0, ManagePasswordsBubbleView::SINGLE_VIEW_COLUMN_SET); - layout->AddView(new CredentialsSelectionView(parent->model())); + layout->AddView(new CredentialsSelectionView(model())); } else { - const autofill::PasswordForm& password_form = - parent_->model()->pending_password(); + const autofill::PasswordForm& password_form = model()->pending_password(); ManagePasswordsBubbleView::BuildCredentialRows( layout, CreateUsernameLabel(password_form).release(), CreatePasswordLabel(password_form, @@ -39,46 +45,64 @@ nullptr, /* password_view_button */ true /* show_password_label */); } - layout->AddPaddingRow( - 0, layout_provider->GetDistanceMetric( - views::DISTANCE_DIALOG_CONTENT_MARGIN_BOTTOM_CONTROL)); - - // Button row. - nope_button_ = views::MdTextButton::CreateSecondaryUiButton( - this, l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_CANCEL_BUTTON)); - - update_button_ = views::MdTextButton::CreateSecondaryUiBlueButton( - this, l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_UPDATE_BUTTON)); - ManagePasswordsBubbleView::BuildColumnSet( - layout, ManagePasswordsBubbleView::DOUBLE_BUTTON_COLUMN_SET); - layout->StartRow(0, ManagePasswordsBubbleView::DOUBLE_BUTTON_COLUMN_SET); - layout->AddView(update_button_); - layout->AddView(nope_button_); - - parent_->set_initially_focused_view(update_button_); } ManagePasswordUpdatePendingView::~ManagePasswordUpdatePendingView() = default; -void ManagePasswordUpdatePendingView::ButtonPressed(views::Button* sender, - const ui::Event& event) { - DCHECK(sender == update_button_ || sender == nope_button_); - if (sender == update_button_) { - if (selection_view_) { - // Multi account case. - parent_->model()->OnUpdateClicked( - *selection_view_->GetSelectedCredentials()); - } else { - parent_->model()->OnUpdateClicked(parent_->model()->pending_password()); - } - } else { - parent_->model()->OnNopeUpdateClicked(); - } - parent_->CloseBubble(); -} - gfx::Size ManagePasswordUpdatePendingView::CalculatePreferredSize() const { return gfx::Size(ManagePasswordsBubbleView::kDesiredBubbleWidth, GetLayoutManager()->GetPreferredHeightForWidth( this, ManagePasswordsBubbleView::kDesiredBubbleWidth)); } + +base::string16 ManagePasswordUpdatePendingView::GetDialogButtonLabel( + ui::DialogButton button) const { + return l10n_util::GetStringUTF16(button == ui::DIALOG_BUTTON_OK + ? IDS_PASSWORD_MANAGER_UPDATE_BUTTON + : IDS_PASSWORD_MANAGER_CANCEL_BUTTON); +} + +bool ManagePasswordUpdatePendingView::Accept() { + if (selection_view_) { + // Multi account case. + model()->OnUpdateClicked(*selection_view_->GetSelectedCredentials()); + } else { + model()->OnUpdateClicked(model()->pending_password()); + } + return true; +} + +bool ManagePasswordUpdatePendingView::Cancel() { + model()->OnNopeUpdateClicked(); + return true; +} + +bool ManagePasswordUpdatePendingView::Close() { + return true; +} + +void ManagePasswordUpdatePendingView::AddedToWidget() { + auto title_view = + base::MakeUnique<views::StyledLabel>(base::string16(), this); + title_view->SetTextContext(views::style::CONTEXT_DIALOG_TITLE); + UpdateTitleText(title_view.get()); + GetBubbleFrameView()->SetTitleView(std::move(title_view)); +} + +void ManagePasswordUpdatePendingView::StyledLabelLinkClicked( + views::StyledLabel* label, + const gfx::Range& range, + int event_flags) { + DCHECK_EQ(model()->title_brand_link_range(), range); + model()->OnBrandLinkClicked(); +} + +void ManagePasswordUpdatePendingView::UpdateTitleText( + views::StyledLabel* title_view) { + title_view->SetText(GetWindowTitle()); + if (!model()->title_brand_link_range().is_empty()) { + auto link_style = views::StyledLabel::RangeStyleInfo::CreateForLink(); + link_style.disable_line_wrapping = false; + title_view->AddStyleRange(model()->title_brand_link_range(), link_style); + } +}
diff --git a/chrome/browser/ui/views/passwords/manage_password_update_pending_view.h b/chrome/browser/ui/views/passwords/manage_password_update_pending_view.h index d07410f..03420529 100644 --- a/chrome/browser/ui/views/passwords/manage_password_update_pending_view.h +++ b/chrome/browser/ui/views/passwords/manage_password_update_pending_view.h
@@ -5,35 +5,47 @@ #ifndef CHROME_BROWSER_UI_VIEWS_PASSWORDS_MANAGE_PASSWORD_UPDATE_PENDING_VIEW_H_ #define CHROME_BROWSER_UI_VIEWS_PASSWORDS_MANAGE_PASSWORD_UPDATE_PENDING_VIEW_H_ -#include "ui/views/controls/button/button.h" -#include "ui/views/view.h" +#include "chrome/browser/ui/views/passwords/manage_passwords_bubble_delegate_view_base.h" +#include "ui/views/controls/styled_label_listener.h" + +namespace views { +class StyledLabel; +} class CredentialsSelectionView; -class ManagePasswordsBubbleView; // A view offering the user the ability to update credentials. Contains a // single credential row (in case of one credentials) or // CredentialsSelectionView otherwise, along with a "Update Passwords" button // and a rejection button. -class ManagePasswordUpdatePendingView : public views::View, - public views::ButtonListener { +class ManagePasswordUpdatePendingView + : public ManagePasswordsBubbleDelegateViewBase, + public views::StyledLabelListener { public: - explicit ManagePasswordUpdatePendingView(ManagePasswordsBubbleView* parent); + ManagePasswordUpdatePendingView(content::WebContents* web_contents, + views::View* anchor_view, + const gfx::Point& anchor_point, + DisplayReason reason); ~ManagePasswordUpdatePendingView() override; private: - // views::ButtonListener: - void ButtonPressed(views::Button* sender, const ui::Event& event) override; - // views::View: + // ManagePasswordsBubbleDelegateViewBase: gfx::Size CalculatePreferredSize() const override; + base::string16 GetDialogButtonLabel(ui::DialogButton button) const override; + bool Accept() override; + bool Cancel() override; + bool Close() override; + void AddedToWidget() override; - ManagePasswordsBubbleView* parent_; + // views::StyledLabelListener: + void StyledLabelLinkClicked(views::StyledLabel* label, + const gfx::Range& range, + int event_flags) override; + + void UpdateTitleText(views::StyledLabel* title_view); CredentialsSelectionView* selection_view_; - views::Button* update_button_; - views::Button* nope_button_; - DISALLOW_COPY_AND_ASSIGN(ManagePasswordUpdatePendingView); };
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_bubble_delegate_view_base.cc b/chrome/browser/ui/views/passwords/manage_passwords_bubble_delegate_view_base.cc index 1e6594f..f9fdfd57 100644 --- a/chrome/browser/ui/views/passwords/manage_passwords_bubble_delegate_view_base.cc +++ b/chrome/browser/ui/views/passwords/manage_passwords_bubble_delegate_view_base.cc
@@ -11,6 +11,7 @@ #include "chrome/browser/ui/views/passwords/manage_password_auto_sign_in_view.h" #include "chrome/browser/ui/views/passwords/manage_password_items_view.h" #include "chrome/browser/ui/views/passwords/manage_password_save_confirmation_view.h" +#include "chrome/browser/ui/views/passwords/manage_password_update_pending_view.h" #include "chrome/browser/ui/views/passwords/manage_passwords_bubble_view.h" #include "chrome/browser/ui/views/passwords/manage_passwords_icon_views.h" #include "ui/base/material_design/material_design_controller.h" @@ -94,6 +95,11 @@ } else if (model_state == password_manager::ui::CONFIRMATION_STATE) { view = new ManagePasswordSaveConfirmationView(web_contents, anchor_view, anchor_point, reason); + } else if (model_state == + password_manager::ui::PENDING_PASSWORD_UPDATE_STATE) { + view = new ManagePasswordUpdatePendingView(web_contents, anchor_view, + anchor_point, reason); + } else { // TODO(crbug.com/654115): Get rid of the one-bubble-for-everything // BubbleView. @@ -118,6 +124,19 @@ g_manage_passwords_bubble_->GetWidget()->Activate(); } +const content::WebContents* +ManagePasswordsBubbleDelegateViewBase::GetWebContents() const { + return model_.GetWebContents(); +} + +base::string16 ManagePasswordsBubbleDelegateViewBase::GetWindowTitle() const { + return model_.title(); +} + +bool ManagePasswordsBubbleDelegateViewBase::ShouldShowWindowTitle() const { + return !model_.title().empty(); +} + ManagePasswordsBubbleDelegateViewBase::ManagePasswordsBubbleDelegateViewBase( content::WebContents* web_contents, views::View* anchor_view, @@ -128,8 +147,7 @@ reason == AUTOMATIC ? ManagePasswordsBubbleModel::AUTOMATIC : ManagePasswordsBubbleModel::USER_ACTION), mouse_handler_( - std::make_unique<WebContentMouseHandler>(this, - model_.GetWebContents())) {} + std::make_unique<WebContentMouseHandler>(this, web_contents)) {} ManagePasswordsBubbleDelegateViewBase:: ~ManagePasswordsBubbleDelegateViewBase() { @@ -137,20 +155,16 @@ g_manage_passwords_bubble_ = nullptr; } -const content::WebContents* -ManagePasswordsBubbleDelegateViewBase::GetWebContents() const { - return model_.GetWebContents(); -} - -void ManagePasswordsBubbleDelegateViewBase::CloseBubble() { +void ManagePasswordsBubbleDelegateViewBase::OnWidgetClosing( + views::Widget* widget) { + LocationBarBubbleDelegateView::OnWidgetClosing(widget); + if (widget != GetWidget()) + return; mouse_handler_.reset(); - LocationBarBubbleDelegateView::CloseBubble(); -} - -base::string16 ManagePasswordsBubbleDelegateViewBase::GetWindowTitle() const { - return model_.title(); -} - -bool ManagePasswordsBubbleDelegateViewBase::ShouldShowWindowTitle() const { - return !model_.title().empty(); + // It can be the case that a password bubble is being closed while another + // password bubble is being opened. The metrics recorder can be shared between + // them and it doesn't understand the sequence [open1, open2, close1, close2]. + // Therefore, we reset the model early (before the bubble destructor) to get + // the following sequence of events [open1, close1, open2, close2]. + model_.OnBubbleClosing(); }
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_bubble_delegate_view_base.h b/chrome/browser/ui/views/passwords/manage_passwords_bubble_delegate_view_base.h index 3913ccb..0cda49d 100644 --- a/chrome/browser/ui/views/passwords/manage_passwords_bubble_delegate_view_base.h +++ b/chrome/browser/ui/views/passwords/manage_passwords_bubble_delegate_view_base.h
@@ -70,10 +70,10 @@ ~ManagePasswordsBubbleDelegateViewBase() override; - // LocationBarBubbleDelegateView: - void CloseBubble() override; - private: + // WidgetObserver: + void OnWidgetClosing(views::Widget* widget) override; + // Singleton instance of the Password bubble.The instance is owned by the // Bubble and will be deleted when the bubble closes. static ManagePasswordsBubbleDelegateViewBase* g_manage_passwords_bubble_;
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.cc b/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.cc index f475f37..0056f90 100644 --- a/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.cc +++ b/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.cc
@@ -24,7 +24,6 @@ #include "chrome/browser/ui/views/passwords/manage_password_items_view.h" #include "chrome/browser/ui/views/passwords/manage_password_pending_view.h" #include "chrome/browser/ui/views/passwords/manage_password_sign_in_promo_view.h" -#include "chrome/browser/ui/views/passwords/manage_password_update_pending_view.h" #include "chrome/grit/generated_resources.h" #include "chrome/grit/theme_resources.h" #include "components/password_manager/core/common/password_manager_features.h" @@ -301,9 +300,6 @@ void ManagePasswordsBubbleView::CreateChild() { if (model()->state() == password_manager::ui::PENDING_PASSWORD_STATE) { AddChildView(new ManagePasswordPendingView(this)); - } else if (model()->state() == - password_manager::ui::PENDING_PASSWORD_UPDATE_STATE) { - AddChildView(new ManagePasswordUpdatePendingView(this)); } else { // This model state should be handled by separate dialogs. NOTREACHED();
diff --git a/chrome/browser/ui/views/profiles/profile_chooser_view.cc b/chrome/browser/ui/views/profiles/profile_chooser_view.cc index 67a0c5e..90c376e 100644 --- a/chrome/browser/ui/views/profiles/profile_chooser_view.cc +++ b/chrome/browser/ui/views/profiles/profile_chooser_view.cc
@@ -48,7 +48,6 @@ #include "chrome/browser/ui/views/profiles/badged_profile_photo.h" #include "chrome/browser/ui/views/profiles/signin_view_controller_delegate_views.h" #include "chrome/browser/ui/views/profiles/user_manager_view.h" -#include "chrome/browser/ui/webui/signin/dice_turn_sync_on_helper.h" #include "chrome/browser/ui/webui/signin/login_ui_service.h" #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h" #include "chrome/common/pref_names.h" @@ -653,13 +652,8 @@ } else if (sender == signin_current_profile_button_) { ShowViewFromMode(profiles::BUBBLE_VIEW_MODE_GAIA_SIGNIN); } else if (sender == signin_with_gaia_account_button_) { - // DiceTurnSyncOnHelper deletes itself once it's done. - new DiceTurnSyncOnHelper( - browser_->profile(), browser_, access_point_, - signin_metrics::Reason::REASON_SIGNIN_PRIMARY_ACCOUNT, - signin_with_gaia_account_id_, - DiceTurnSyncOnHelper::SigninAbortedMode::KEEP_ACCOUNT); - + signin_ui_util::EnableSync(browser_, dice_sync_promo_account_, + access_point_); } else { // Either one of the "other profiles", or one of the profile accounts // buttons was pressed. @@ -1063,11 +1057,13 @@ } // Create a hover button to sign in the first account of |accounts|. - // TODO(http://crbug.com/794522): Use the account picture instead of the - // default avatar. gfx::Image account_icon = - ui::ResourceBundle::GetSharedInstance().GetImageNamed( - profiles::GetPlaceholderAvatarIconResourceID()); + AccountTrackerServiceFactory::GetForProfile(browser_->profile()) + ->GetAccountImage(accounts[0].account_id); + if (account_icon.IsEmpty()) { + account_icon = ui::ResourceBundle::GetSharedInstance().GetImageNamed( + profiles::GetPlaceholderAvatarIconResourceID()); + } auto account_photo = std::make_unique<BadgedProfilePhoto>( BadgedProfilePhoto::BADGE_TYPE_NONE, account_icon); base::string16 first_account_button_title = @@ -1086,7 +1082,7 @@ promo_button_container->AddChildView(signin_button_view); signin_with_gaia_account_button_ = first_account_button; - signin_with_gaia_account_id_ = accounts[0].account_id; + dice_sync_promo_account_ = accounts[0]; constexpr int kSmallMenuIconSize = 16; HoverButton* sync_to_another_account_button = new HoverButton(
diff --git a/chrome/browser/ui/views/profiles/profile_chooser_view.h b/chrome/browser/ui/views/profiles/profile_chooser_view.h index 56d2ec84..ced3e92 100644 --- a/chrome/browser/ui/views/profiles/profile_chooser_view.h +++ b/chrome/browser/ui/views/profiles/profile_chooser_view.h
@@ -229,9 +229,8 @@ CloseBubbleOnTabActivationHelper close_bubble_helper_; - // ID of the GAIA account that should be signed in when - // |signin_with_gaia_account_button_| is pressed. - std::string signin_with_gaia_account_id_; + // Account that is presented in the enable sync promo. + AccountInfo dice_sync_promo_account_; const bool dice_enabled_;
diff --git a/chrome/browser/ui/views/sync/bubble_sync_promo_view_unittest.cc b/chrome/browser/ui/views/sync/bubble_sync_promo_view_unittest.cc index ea2ec3f..e3384bd 100644 --- a/chrome/browser/ui/views/sync/bubble_sync_promo_view_unittest.cc +++ b/chrome/browser/ui/views/sync/bubble_sync_promo_view_unittest.cc
@@ -26,7 +26,10 @@ protected: // BubbleSyncPromoDelegate: void ShowBrowserSignin() override { ++show_browser_signin_count_; } + +#if BUILDFLAG(ENABLE_DICE_SUPPORT) void EnableSync(const AccountInfo& account_info) override { NOTREACHED(); } +#endif // Number of times that OnSignInLinkClicked has been called. int show_browser_signin_count_ = 0;
diff --git a/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc b/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc index fcbea931..562b7df 100644 --- a/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc +++ b/chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc
@@ -7,6 +7,7 @@ #include <utility> #include "base/auto_reset.h" +#include "base/command_line.h" #include "base/macros.h" #include "base/metrics/user_metrics.h" #include "base/task_scheduler/post_task.h" @@ -31,6 +32,7 @@ #include "chrome/browser/ui/views/tabs/tab.h" #include "chrome/browser/ui/views/tabs/tab_renderer_data.h" #include "chrome/browser/ui/views/tabs/tab_strip.h" +#include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" #include "components/feature_engagement/features.h" @@ -72,7 +74,8 @@ *adjust_layout = true; return prefs->GetBoolean(prefs::kTabStripStackedLayout); #else - return false; + return base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kForceStackedTabStripLayout); #endif }
diff --git a/chrome/browser/ui/webui/discards/discards_ui.cc b/chrome/browser/ui/webui/discards/discards_ui.cc index d237795..2d53a02 100644 --- a/chrome/browser/ui/webui/discards/discards_ui.cc +++ b/chrome/browser/ui/webui/discards/discards_ui.cc
@@ -4,7 +4,9 @@ #include "chrome/browser/ui/webui/discards/discards_ui.h" -#include "base/memory/ptr_util.h" +#include <utility> +#include <vector> + #include "base/strings/utf_string_conversions.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile.h" @@ -23,15 +25,11 @@ namespace { -namespace { - resource_coordinator::DiscardReason GetDiscardReason(bool urgent) { return urgent ? resource_coordinator::DiscardReason::kUrgent : resource_coordinator::DiscardReason::kProactive; } -} // namespace - class DiscardsDetailsProviderImpl : public mojom::DiscardsDetailsProvider { public: // This instance is deleted when the supplied pipe is destroyed. @@ -129,5 +127,6 @@ DiscardsUI::~DiscardsUI() {} void DiscardsUI::BindUIHandler(mojom::DiscardsDetailsProviderRequest request) { - ui_handler_.reset(new DiscardsDetailsProviderImpl(std::move(request))); + ui_handler_ = + std::make_unique<DiscardsDetailsProviderImpl>(std::move(request)); }
diff --git a/chrome/browser/ui/webui/discards/discards_ui.h b/chrome/browser/ui/webui/discards/discards_ui.h index 442fd98..212c664 100644 --- a/chrome/browser/ui/webui/discards/discards_ui.h +++ b/chrome/browser/ui/webui/discards/discards_ui.h
@@ -5,6 +5,8 @@ #ifndef CHROME_BROWSER_UI_WEBUI_DISCARDS_DISCARDS_UI_H_ #define CHROME_BROWSER_UI_WEBUI_DISCARDS_DISCARDS_UI_H_ +#include <memory> + #include "base/macros.h" #include "chrome/browser/ui/webui/discards/discards.mojom.h" #include "chrome/browser/ui/webui/mojo_web_ui_controller.h"
diff --git a/chrome/browser/ui/webui/interstitials/interstitial_ui.cc b/chrome/browser/ui/webui/interstitials/interstitial_ui.cc index 24fc3095..3ce482e 100644 --- a/chrome/browser/ui/webui/interstitials/interstitial_ui.cc +++ b/chrome/browser/ui/webui/interstitials/interstitial_ui.cc
@@ -162,6 +162,8 @@ if (net::GetValueForKeyInQuery(web_contents->GetURL(), "type", &type_param)) { if (type_param == "hpkp_failure") { cert_error = net::ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN; + } else if (type_param == "ct_failure") { + cert_error = net::ERR_CERTIFICATE_TRANSPARENCY_REQUIRED; } } net::SSLInfo ssl_info;
diff --git a/chrome/browser/ui/webui/interstitials/interstitial_ui_browsertest.cc b/chrome/browser/ui/webui/interstitials/interstitial_ui_browsertest.cc index 8b82fe2..cfda310 100644 --- a/chrome/browser/ui/webui/interstitials/interstitial_ui_browsertest.cc +++ b/chrome/browser/ui/webui/interstitials/interstitial_ui_browsertest.cc
@@ -12,6 +12,7 @@ #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" #include "content/public/browser/web_contents.h" +#include "content/public/test/browser_test_utils.h" #include "content/public/test/test_navigation_observer.h" class InterstitialUITest : public InProcessBrowserTest { @@ -76,6 +77,18 @@ "Privacy error"); } +IN_PROC_BROWSER_TEST_F(InterstitialUITest, CTInterstitial) { + TestInterstitial(GURL("chrome://interstitials/ssl?type=ct_failure"), + "Privacy error"); + bool found_ct_error = false; + EXPECT_TRUE(content::ExecuteScriptAndExtractBool( + browser()->tab_strip_model()->GetActiveWebContents(), + "window.domAutomationController.send(document.body.textContent.indexOf('" + "CERTIFICATE_TRANSPARENCY') != -1);", + &found_ct_error)); + EXPECT_TRUE(found_ct_error); +} + IN_PROC_BROWSER_TEST_F(InterstitialUITest, MalwareInterstitial) { TestInterstitial( GURL("chrome://interstitials/safebrowsing?type=malware"),
diff --git a/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper.cc b/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper.cc index 6b171c72..9150faf 100644 --- a/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper.cc +++ b/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper.cc
@@ -377,9 +377,6 @@ base::RecordAction(base::UserMetricsAction("Signin_Signin_Succeed")); // Show Sync confirmation. - browser_sync::ProfileSyncService* sync_service = GetProfileSyncService(); - if (sync_service) - sync_blocker_ = sync_service->GetSetupInProgressHandle(); scoped_login_ui_service_observer_.Add( LoginUIServiceFactory::GetForProfile(profile_)); browser_ = EnsureBrowser(browser_, profile_);
diff --git a/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper.h b/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper.h index d1ef87b..d83197f 100644 --- a/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper.h +++ b/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper.h
@@ -26,10 +26,6 @@ class ProfileSyncService; } -namespace syncer { -class SyncSetupInProgressHandle; -} - // Handles details of signing the user in with SigninManager and turning on // sync for an account that is already present in the token service. class DiceTurnSyncOnHelper : public BrowserListObserver, @@ -144,9 +140,6 @@ // Account information. const AccountInfo account_info_; - // Prevents Sync from running until configuration is complete. - std::unique_ptr<syncer::SyncSetupInProgressHandle> sync_blocker_; - // Policy credentials we keep while determining whether to create // a new profile for an enterprise user or not. std::string dm_token_;
diff --git a/chrome/browser/vr/PRESUBMIT.py b/chrome/browser/vr/PRESUBMIT.py index 4bb6e355..5e94690 100644 --- a/chrome/browser/vr/PRESUBMIT.py +++ b/chrome/browser/vr/PRESUBMIT.py
@@ -49,6 +49,8 @@ against all Chromium commits, but should be run against changes likely to affect these tests. + Also, it compiles the Linux VR tryserver to compile the UI testapp. + When adding/removing tests here, ensure that both gpu/PRESUBMIT.py and ui/gl/PRESUBMIT.py are updated. """ @@ -59,5 +61,6 @@ 'master.tryserver.chromium.mac:mac_optional_gpu_tests_rel', 'master.tryserver.chromium.win:win_optional_gpu_tests_rel', 'master.tryserver.chromium.android:android_optional_gpu_tests_rel', + 'master.tryserver.chromium.linux:linux_vr', ], 'Automatically added optional GPU tests to run on CQ.')
diff --git a/chrome/browser/vr/elements/text.cc b/chrome/browser/vr/elements/text.cc index 3c1cd1d..a892bdc 100644 --- a/chrome/browser/vr/elements/text.cc +++ b/chrome/browser/vr/elements/text.cc
@@ -10,6 +10,7 @@ #include "ui/gfx/canvas.h" #include "ui/gfx/font_list.h" #include "ui/gfx/geometry/rect.h" +#include "ui/gfx/geometry/safe_integer_conversions.h" #include "ui/gfx/geometry/vector2d.h" #include "ui/gfx/render_text.h" @@ -150,6 +151,7 @@ void Draw(SkCanvas* sk_canvas, const gfx::Size& texture_size) override; gfx::SizeF size_; + gfx::Vector2d texture_offset_; base::string16 text_; float font_height_dmms_ = 0; float text_width_ = 0; @@ -295,12 +297,17 @@ // Note, there is no padding here whatsoever. size_ = gfx::SizeF(text_bounds.size()); + if (parameters.shadows_enabled) { + texture_offset_ = gfx::Vector2d(gfx::ToFlooredInt(parameters.shadow_size), + gfx::ToFlooredInt(parameters.shadow_size)); + } } void TextTexture::Draw(SkCanvas* sk_canvas, const gfx::Size& texture_size) { cc::SkiaPaintCanvas paint_canvas(sk_canvas); gfx::Canvas gfx_canvas(&paint_canvas, 1.0f); gfx::Canvas* canvas = &gfx_canvas; + canvas->Translate(texture_offset_); for (auto& render_text : lines_) render_text->Draw(canvas);
diff --git a/chrome/browser/vr/elements/ui_element_name.cc b/chrome/browser/vr/elements/ui_element_name.cc index b2fad274..0a90f463 100644 --- a/chrome/browser/vr/elements/ui_element_name.cc +++ b/chrome/browser/vr/elements/ui_element_name.cc
@@ -118,6 +118,7 @@ "kDownloadedSnackbar", "kControllerTrackpadLabel", "kControllerExitButtonLabel", + "kControllerBackButtonLabel", }; static_assert(
diff --git a/chrome/browser/vr/elements/ui_element_name.h b/chrome/browser/vr/elements/ui_element_name.h index 9857f5d..dea3d3e 100644 --- a/chrome/browser/vr/elements/ui_element_name.h +++ b/chrome/browser/vr/elements/ui_element_name.h
@@ -117,6 +117,7 @@ kDownloadedSnackbar, kControllerTrackpadLabel, kControllerExitButtonLabel, + kControllerBackButtonLabel, // This must be last. kNumUiElementNames,
diff --git a/chrome/browser/vr/elements/ui_texture.cc b/chrome/browser/vr/elements/ui_texture.cc index f3182db97..3fd1a47 100644 --- a/chrome/browser/vr/elements/ui_texture.cc +++ b/chrome/browser/vr/elements/ui_texture.cc
@@ -126,7 +126,6 @@ // Set calculated height. if (bounds->height() == 0) bounds->set_height(height); - } else { std::unique_ptr<gfx::RenderText> render_text = CreateConfiguredRenderText( text, font_list, parameters.color, parameters.text_alignment, @@ -147,6 +146,12 @@ render_text->SetDisplayRect(*bounds); lines.push_back(std::move(render_text)); } + + if (parameters.shadows_enabled) { + bounds->Inset(-parameters.shadow_size, -parameters.shadow_size); + bounds->Offset(parameters.shadow_size, parameters.shadow_size); + } + return lines; }
diff --git a/chrome/browser/vr/testapp/vr_test_context.cc b/chrome/browser/vr/testapp/vr_test_context.cc index 2fbc2d0..9d227fd 100644 --- a/chrome/browser/vr/testapp/vr_test_context.cc +++ b/chrome/browser/vr/testapp/vr_test_context.cc
@@ -55,7 +55,7 @@ constexpr float kViewScaleAdjustmentFactor = 0.2f; constexpr float kPageLoadTimeMilliseconds = 500; -constexpr gfx::Point3F kDefaultLaserOrigin = {0.5f, -0.5f, 0.f}; +constexpr gfx::Point3F kDefaultLaserOrigin = {0.1f, -0.5f, 0.f}; constexpr gfx::Vector3dF kLaserLocalOffset = {0.f, -0.0075f, -0.05f}; constexpr float kControllerScaleFactor = 1.5f;
diff --git a/chrome/browser/vr/ui_scene_constants.h b/chrome/browser/vr/ui_scene_constants.h index 5a64662..50c9fc76 100644 --- a/chrome/browser/vr/ui_scene_constants.h +++ b/chrome/browser/vr/ui_scene_constants.h
@@ -260,9 +260,9 @@ static constexpr float kSnackbarMoveInAngle = -base::kPiFloat / 10; static constexpr int kSnackbarTransitionDurationMs = 300; -static constexpr float kControllerLabelSpacerSize = 0.003f; -static constexpr float kControllerLabelLayoutMargin = 0.005f; -static constexpr float kControllerLabelCalloutWidth = 0.025f; +static constexpr float kControllerLabelSpacerSize = 0.025f; +static constexpr float kControllerLabelLayoutMargin = -0.005f; +static constexpr float kControllerLabelCalloutWidth = 0.02f; static constexpr float kControllerLabelCalloutHeight = 0.001f; static constexpr float kControllerLabelFontHeight = 0.05f; static constexpr float kControllerLabelScale = 0.2f; @@ -270,6 +270,7 @@ // TODO(vollick): these should be encoded in the controller mesh. static constexpr float kControllerTrackpadOffset = -0.035f; static constexpr float kControllerExitButtonOffset = -0.008f; +static constexpr float kControllerBackButtonOffset = -0.008f; static constexpr int kControllerLabelTransitionDurationMs = 700;
diff --git a/chrome/browser/vr/ui_scene_creator.cc b/chrome/browser/vr/ui_scene_creator.cc index 4ae0a3c..9c0fb8e2 100644 --- a/chrome/browser/vr/ui_scene_creator.cc +++ b/chrome/browser/vr/ui_scene_creator.cc
@@ -1308,10 +1308,15 @@ auto exit_button_label = CreateControllerLabel( kControllerExitButtonLabel, kControllerExitButtonOffset, l10n_util::GetStringUTF16(IDS_VR_BUTTON_EXIT), model_); - VR_BIND_VISIBILITY(exit_button_label, model->fullscreen_enabled()); callout_group->AddChild(std::move(exit_button_label)); + auto back_button_label = CreateControllerLabel( + kControllerBackButtonLabel, kControllerBackButtonOffset, + l10n_util::GetStringUTF16(IDS_VR_BUTTON_BACK), model_); + VR_BIND_VISIBILITY(back_button_label, model->omnibox_editing_enabled()); + callout_group->AddChild(std::move(back_button_label)); + controller->AddChild(std::move(callout_group)); scene_->AddUiElement(kControllerGroup, std::move(controller));
diff --git a/chrome/browser/vr/ui_unittest.cc b/chrome/browser/vr/ui_unittest.cc index 5f11028..e084d0b 100644 --- a/chrome/browser/vr/ui_unittest.cc +++ b/chrome/browser/vr/ui_unittest.cc
@@ -1070,18 +1070,28 @@ EXPECT_FALSE(IsVisible(kControllerTrackpadLabel)); EXPECT_FALSE(IsVisible(kControllerExitButtonLabel)); + EXPECT_FALSE(IsVisible(kControllerBackButtonLabel)); model_->controller.resting_in_viewport = true; EXPECT_TRUE(IsVisible(kControllerTrackpadLabel)); EXPECT_FALSE(IsVisible(kControllerExitButtonLabel)); + EXPECT_FALSE(IsVisible(kControllerBackButtonLabel)); - ui_->SetFullscreen(true); + model_->push_mode(kModeFullscreen); EXPECT_TRUE(IsVisible(kControllerTrackpadLabel)); EXPECT_TRUE(IsVisible(kControllerExitButtonLabel)); + EXPECT_FALSE(IsVisible(kControllerBackButtonLabel)); + + model_->pop_mode(kModeFullscreen); + model_->push_mode(kModeEditingOmnibox); + EXPECT_TRUE(IsVisible(kControllerTrackpadLabel)); + EXPECT_FALSE(IsVisible(kControllerExitButtonLabel)); + EXPECT_TRUE(IsVisible(kControllerBackButtonLabel)); model_->controller.resting_in_viewport = false; EXPECT_FALSE(IsVisible(kControllerTrackpadLabel)); EXPECT_FALSE(IsVisible(kControllerExitButtonLabel)); + EXPECT_FALSE(IsVisible(kControllerBackButtonLabel)); } } // namespace vr
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index 4a0f972..bc000f1 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc
@@ -422,6 +422,9 @@ // Forces Chrome to use localNTP instead of server (GWS) NTP. const char kForceLocalNtp[] = "force-local-ntp"; +// Forces Chrome to use a stacked tab strip layout. +const char kForceStackedTabStripLayout[] = "force-stacked-tab-strip-layout"; + // Specifies which page will be displayed in newly-opened tabs. We need this // for testing purposes so that the UI tests don't depend on what comes up for // http://google.com.
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index 7f500f51..5adf77db 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h
@@ -134,6 +134,7 @@ extern const char kForceFirstRun[]; extern const char kForceFirstRunDialog[]; extern const char kForceLocalNtp[]; +extern const char kForceStackedTabStripLayout[]; extern const char kHomePage[]; extern const char kIgnoreUrlFetcherCertRequests[]; extern const char kIncognito[];
diff --git a/chrome/common/media_router/discovery/media_sink_service_base.cc b/chrome/common/media_router/discovery/media_sink_service_base.cc index 9374c4ff..f3f62c19 100644 --- a/chrome/common/media_router/discovery/media_sink_service_base.cc +++ b/chrome/common/media_router/discovery/media_sink_service_base.cc
@@ -37,8 +37,12 @@ } DVLOG(2) << "Send sinks to media router, [size]: " << current_sinks_.size(); - on_sinks_discovered_cb_.Run(std::vector<MediaSinkInternal>( - current_sinks_.begin(), current_sinks_.end())); + + std::vector<MediaSinkInternal> sinks; + for (const auto& sink_it : current_sinks_) + sinks.push_back(sink_it.second); + + on_sinks_discovered_cb_.Run(std::move(sinks)); mrp_sinks_ = current_sinks_; discovery_timer_->Stop(); RecordDeviceCounts();
diff --git a/chrome/common/media_router/discovery/media_sink_service_base.h b/chrome/common/media_router/discovery/media_sink_service_base.h index ea0b503..f8e323cd 100644 --- a/chrome/common/media_router/discovery/media_sink_service_base.h +++ b/chrome/common/media_router/discovery/media_sink_service_base.h
@@ -7,7 +7,7 @@ #include <memory> -#include "base/containers/flat_set.h" +#include "base/containers/flat_map.h" #include "base/gtest_prod_util.h" #include "base/sequence_checker.h" #include "base/timer/timer.h" @@ -44,21 +44,24 @@ // |StartTimer()| is called. void RestartTimer(); - // Sorted sinks from current round of discovery. - base::flat_set<MediaSinkInternal> current_sinks_; + // Sorted sinks from current round of discovery, keyed by sink ID. + base::flat_map<std::string, MediaSinkInternal> current_sinks_; private: friend class MediaSinkServiceBaseTest; FRIEND_TEST_ALL_PREFIXES(MediaSinkServiceBaseTest, TestOnDiscoveryComplete_SameSink); + FRIEND_TEST_ALL_PREFIXES(MediaSinkServiceBaseTest, + TestOnDiscoveryComplete_SameSinkDifferentOrders); // Helper method to start |discovery_timer_|. void DoStart(); OnSinksDiscoveredCallback on_sinks_discovered_cb_; - // Sorted sinks sent to Media Router Provider in last |OnDiscoveryComplete()| - base::flat_set<MediaSinkInternal> mrp_sinks_; + // Sorted sinks sent to Media Router Provider in last |OnDiscoveryComplete()|, + // keyed by sink ID. + base::flat_map<std::string, MediaSinkInternal> mrp_sinks_; // Timer for completing the current round of discovery. std::unique_ptr<base::Timer> discovery_timer_;
diff --git a/chrome/common/media_router/discovery/media_sink_service_base_unittest.cc b/chrome/common/media_router/discovery/media_sink_service_base_unittest.cc index 8e7de8b9..953c8ba 100644 --- a/chrome/common/media_router/discovery/media_sink_service_base_unittest.cc +++ b/chrome/common/media_router/discovery/media_sink_service_base_unittest.cc
@@ -58,13 +58,25 @@ media_sink_service_.SetTimerForTest(base::WrapUnique(mock_timer_)); } + void PopulateSinks(const std::vector<MediaSinkInternal>& old_sinks, + const std::vector<MediaSinkInternal>& new_sinks) { + media_sink_service_.mrp_sinks_.clear(); + for (const auto& old_sink : old_sinks) { + std::string sink_id = old_sink.sink().id(); + media_sink_service_.mrp_sinks_[sink_id] = old_sink; + } + + media_sink_service_.current_sinks_.clear(); + for (const auto& new_sink : new_sinks) { + std::string sink_id = new_sink.sink().id(); + media_sink_service_.current_sinks_[sink_id] = new_sink; + } + } + void TestOnDiscoveryComplete( const std::vector<MediaSinkInternal>& old_sinks, const std::vector<MediaSinkInternal>& new_sinks) { - media_sink_service_.mrp_sinks_ = - base::flat_set<MediaSinkInternal>(old_sinks.begin(), old_sinks.end()); - media_sink_service_.current_sinks_ = - base::flat_set<MediaSinkInternal>(new_sinks.begin(), new_sinks.end()); + PopulateSinks(old_sinks, new_sinks); EXPECT_CALL(mock_sink_discovered_cb_, Run(new_sinks)); media_sink_service_.OnDiscoveryComplete(); } @@ -88,6 +100,17 @@ media_sink_service_.OnDiscoveryComplete(); } +TEST_F(MediaSinkServiceBaseTest, + TestOnDiscoveryComplete_SameSinkDifferentOrders) { + std::vector<MediaSinkInternal> old_sinks = CreateDialMediaSinks(); + std::vector<MediaSinkInternal> new_sinks = CreateDialMediaSinks(); + std::reverse(new_sinks.begin(), new_sinks.end()); + + PopulateSinks(old_sinks, new_sinks); + EXPECT_CALL(mock_sink_discovered_cb_, Run(new_sinks)).Times(0); + media_sink_service_.OnDiscoveryComplete(); +} + TEST_F(MediaSinkServiceBaseTest, TestOnDiscoveryComplete_OneNewSink) { std::vector<MediaSinkInternal> old_sinks = CreateDialMediaSinks(); std::vector<MediaSinkInternal> new_sinks = CreateDialMediaSinks();
diff --git a/chrome/installer/zucchini/image_utils.h b/chrome/installer/zucchini/image_utils.h index c6dd4e8..599f9b1 100644 --- a/chrome/installer/zucchini/image_utils.h +++ b/chrome/installer/zucchini/image_utils.h
@@ -195,6 +195,7 @@ // A matched pair of Elements. struct ElementMatch { bool IsValid() const { return old_element.exe_type == new_element.exe_type; } + ExecutableType exe_type() const { return old_element.exe_type; } Element old_element; Element new_element;
diff --git a/chrome/installer/zucchini/patch_read_write_unittest.cc b/chrome/installer/zucchini/patch_read_write_unittest.cc index e18761a0..580144d 100644 --- a/chrome/installer/zucchini/patch_read_write_unittest.cc +++ b/chrome/installer/zucchini/patch_read_write_unittest.cc
@@ -63,22 +63,22 @@ TEST(PatchTest, ParseSerializeElementMatch) { ByteVector data = { - 1, 0, 0, 0, // old_offset - 3, 0, 0, 0, // new_offset - 2, 0, 0, 0, // old_length - 4, 0, 0, 0, // new_length - 7, 0, 0, 0, // kExeTypeDex + 0x01, 0, 0, 0, // old_offset + 0x03, 0, 0, 0, // new_offset + 0x02, 0, 0, 0, // old_length + 0x04, 0, 0, 0, // new_length + 7, 0, 0, 0, // kExeTypeDex }; BufferSource buffer_source(data.data(), data.size()); ElementMatch element_match = {}; EXPECT_TRUE(patch::ParseElementMatch(&buffer_source, &element_match)); - + EXPECT_EQ(kExeTypeDex, element_match.exe_type()); EXPECT_EQ(kExeTypeDex, element_match.old_element.exe_type); EXPECT_EQ(kExeTypeDex, element_match.new_element.exe_type); - EXPECT_EQ(size_t(1), element_match.old_element.offset); - EXPECT_EQ(size_t(2), element_match.old_element.size); - EXPECT_EQ(size_t(3), element_match.new_element.offset); - EXPECT_EQ(size_t(4), element_match.new_element.size); + EXPECT_EQ(0x1U, element_match.old_element.offset); + EXPECT_EQ(0x2U, element_match.old_element.size); + EXPECT_EQ(0x3U, element_match.new_element.offset); + EXPECT_EQ(0x4U, element_match.new_element.size); size_t size = patch::SerializedElementMatchSize(element_match); EXPECT_EQ(data.size(), size); @@ -429,12 +429,13 @@ TestInitialize<PatchElementReader>(&data); ElementMatch element_match = patch_element_reader.element_match(); + EXPECT_EQ(kExeTypeWin32X86, element_match.exe_type()); EXPECT_EQ(kExeTypeWin32X86, element_match.old_element.exe_type); - EXPECT_EQ(0x01U, element_match.old_element.offset); - EXPECT_EQ(0x02U, element_match.old_element.size); EXPECT_EQ(kExeTypeWin32X86, element_match.new_element.exe_type); - EXPECT_EQ(0x03U, element_match.new_element.offset); - EXPECT_EQ(0x04U, element_match.new_element.size); + EXPECT_EQ(0x1U, element_match.old_element.offset); + EXPECT_EQ(0x2U, element_match.old_element.size); + EXPECT_EQ(0x3U, element_match.new_element.offset); + EXPECT_EQ(0x4U, element_match.new_element.size); EquivalenceSource equivalence_source = patch_element_reader.GetEquivalenceSource();
diff --git a/chrome/installer/zucchini/patch_writer.cc b/chrome/installer/zucchini/patch_writer.cc index d4e37f8..13be44d0 100644 --- a/chrome/installer/zucchini/patch_writer.cc +++ b/chrome/installer/zucchini/patch_writer.cc
@@ -29,7 +29,7 @@ base::checked_cast<uint32_t>(element_match.old_element.size); element_header.new_length = base::checked_cast<uint32_t>(element_match.new_element.size); - element_header.exe_type = element_match.old_element.exe_type; + element_header.exe_type = element_match.exe_type(); return sink->PutValue<PatchElementHeader>(element_header); }
diff --git a/chrome/installer/zucchini/zucchini_apply.cc b/chrome/installer/zucchini/zucchini_apply.cc index 59477be..1f4cd00 100644 --- a/chrome/installer/zucchini/zucchini_apply.cc +++ b/chrome/installer/zucchini/zucchini_apply.cc
@@ -242,9 +242,8 @@ for (const auto& element_patch : patch_reader.elements()) { ElementMatch match = element_patch.element_match(); - if (!ApplyElement(match.old_element.exe_type, - old_image[match.old_element.region()], element_patch, - new_image[match.new_element.region()])) + if (!ApplyElement(match.exe_type(), old_image[match.old_element.region()], + element_patch, new_image[match.new_element.region()])) return status::kStatusFatal; }
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json index ed745bd..b05df588 100644 --- a/chrome/test/data/policy/policy_test_cases.json +++ b/chrome/test/data/policy/policy_test_cases.json
@@ -751,13 +751,7 @@ }, "EnableCommonNameFallbackForLocalAnchors": { - "os": ["win", "linux", "mac", "chromeos", "android"], - "test_policy": { "EnableCommonNameFallbackForLocalAnchors": true }, - "pref_mappings": [ - { "pref": "ssl.common_name_fallback_enabled_for_local_anchors", - "local_state": true - } - ] + "note": "This policy is deprecated and removed since Chrome 66." }, "AuthSchemes": {
diff --git a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastApplication.java b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastApplication.java index fec40f7..c4ae8edc 100644 --- a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastApplication.java +++ b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastApplication.java
@@ -7,10 +7,10 @@ import android.content.Context; import org.chromium.base.ApplicationStatus; +import org.chromium.base.BaseChromiumApplication; import org.chromium.base.CommandLineInitUtil; import org.chromium.base.ContextUtils; import org.chromium.base.PathUtils; -import org.chromium.content.app.ContentApplication; /** * Entry point for the Android cast shell application. Handles initialization of information that @@ -20,7 +20,7 @@ * processes don't need most of the full "setup" performed in CastBrowserHelper.java, but they do * require a few basic pieces (found here). */ -public class CastApplication extends ContentApplication { +public class CastApplication extends BaseChromiumApplication { private static final String TAG = "CastApplication"; private static final String PRIVATE_DATA_DIRECTORY_SUFFIX = "cast_shell";
diff --git a/chromecast/graphics/cast_window_manager_aura.cc b/chromecast/graphics/cast_window_manager_aura.cc index 409fee669..34a4112 100644 --- a/chromecast/graphics/cast_window_manager_aura.cc +++ b/chromecast/graphics/cast_window_manager_aura.cc
@@ -266,8 +266,8 @@ wm::SetActivationClient(window_tree_host_->window(), nullptr); aura::client::SetFocusClient(window_tree_host_->window(), nullptr); focus_client_.reset(); - window_tree_host_.reset(); system_gesture_event_handler_.reset(); + window_tree_host_.reset(); } void CastWindowManagerAura::SetWindowId(gfx::NativeView window,
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index 27e9a18..54d8d22 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -10324.0.0 \ No newline at end of file +10330.0.0 \ No newline at end of file
diff --git a/components/arc/arc_bridge_host_impl.cc b/components/arc/arc_bridge_host_impl.cc index eb7aaae..0ba4d8a9 100644 --- a/components/arc/arc_bridge_host_impl.cc +++ b/components/arc/arc_bridge_host_impl.cc
@@ -233,6 +233,12 @@ std::move(rotation_lock_ptr)); } +void ArcBridgeHostImpl::OnScreenCaptureInstanceReady( + mojom::ScreenCaptureInstancePtr screen_capture_ptr) { + OnInstanceReady(arc_bridge_service_->screen_capture(), + std::move(screen_capture_ptr)); +} + void ArcBridgeHostImpl::OnStorageManagerInstanceReady( mojom::StorageManagerInstancePtr storage_manager_ptr) { OnInstanceReady(arc_bridge_service_->storage_manager(),
diff --git a/components/arc/arc_bridge_host_impl.h b/components/arc/arc_bridge_host_impl.h index 0a7374a..f4e86e28 100644 --- a/components/arc/arc_bridge_host_impl.h +++ b/components/arc/arc_bridge_host_impl.h
@@ -82,6 +82,8 @@ void OnProcessInstanceReady(mojom::ProcessInstancePtr process_ptr) override; void OnRotationLockInstanceReady( mojom::RotationLockInstancePtr rotation_lock_ptr) override; + void OnScreenCaptureInstanceReady( + mojom::ScreenCaptureInstancePtr screen_capture_ptr) override; void OnStorageManagerInstanceReady( mojom::StorageManagerInstancePtr storage_manager_ptr) override; void OnTracingInstanceReady(mojom::TracingInstancePtr trace_ptr) override;
diff --git a/components/arc/arc_bridge_service.h b/components/arc/arc_bridge_service.h index 6cfd090..92916d6 100644 --- a/components/arc/arc_bridge_service.h +++ b/components/arc/arc_bridge_service.h
@@ -65,6 +65,8 @@ class PrintInstance; class ProcessInstance; class RotationLockInstance; +class ScreenCaptureHost; +class ScreenCaptureInstance; class StorageManagerInstance; class TracingInstance; class TtsHost; @@ -181,6 +183,10 @@ ConnectionHolder<mojom::RotationLockInstance>* rotation_lock() { return &rotation_lock_; } + ConnectionHolder<mojom::ScreenCaptureInstance, mojom::ScreenCaptureHost>* + screen_capture() { + return &screen_capture_; + } ConnectionHolder<mojom::StorageManagerInstance>* storage_manager() { return &storage_manager_; } @@ -249,6 +255,8 @@ ConnectionHolder<mojom::PrintInstance, mojom::PrintHost> print_; ConnectionHolder<mojom::ProcessInstance> process_; ConnectionHolder<mojom::RotationLockInstance> rotation_lock_; + ConnectionHolder<mojom::ScreenCaptureInstance, mojom::ScreenCaptureHost> + screen_capture_; ConnectionHolder<mojom::StorageManagerInstance> storage_manager_; ConnectionHolder<mojom::TracingInstance> tracing_; ConnectionHolder<mojom::TtsInstance, mojom::TtsHost> tts_;
diff --git a/components/arc/common/BUILD.gn b/components/arc/common/BUILD.gn index 0ea2baf..c22a239c 100644 --- a/components/arc/common/BUILD.gn +++ b/components/arc/common/BUILD.gn
@@ -43,6 +43,7 @@ "process.mojom", "rotation_lock.mojom", "scale_factor.mojom", + "screen_capture.mojom", "storage_manager.mojom", "tracing.mojom", "tts.mojom",
diff --git a/components/arc/common/arc_bridge.mojom b/components/arc/common/arc_bridge.mojom index c779b381..492c170 100644 --- a/components/arc/common/arc_bridge.mojom +++ b/components/arc/common/arc_bridge.mojom
@@ -32,6 +32,7 @@ import "print.mojom"; import "process.mojom"; import "rotation_lock.mojom"; +import "screen_capture.mojom"; import "storage_manager.mojom"; import "tracing.mojom"; import "tts.mojom"; @@ -42,9 +43,9 @@ import "volume_mounter.mojom"; import "wallpaper.mojom"; -// Next MinVersion: 35 +// Next MinVersion: 36 // Deprecated method IDs: 101, 105 -// Next method ID: 140 +// Next method ID: 141 interface ArcBridgeHost { // Keep the entries alphabetical. In order to do so without breaking // compatibility with the ARC instance, explicitly assign each interface a @@ -142,6 +143,9 @@ // Notifies Chrome that the RotationLockInstance interface is ready. [MinVersion=32] OnRotationLockInstanceReady@137(RotationLockInstance instance_ptr); + // Notifies Chrome that the ScreenCaptureInstance interface is ready. + [MinVersion=35] OnScreenCaptureInstanceReady@140(ScreenCaptureInstance instance_ptr); + // Notifies Chrome that the StorageManagerInstance interface is ready. [MinVersion=12] OnStorageManagerInstanceReady@118(StorageManagerInstance instance_ptr);
diff --git a/components/arc/common/screen_capture.mojom b/components/arc/common/screen_capture.mojom new file mode 100644 index 0000000..d6c96b8 --- /dev/null +++ b/components/arc/common/screen_capture.mojom
@@ -0,0 +1,66 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Mojo interface for performing screen capture in ChromeOS at the request of +// Android. Android does not have access to the full desktop for capture (it has +// access only to its Windows), so via this IPC mechanism it can request +// permissions to capture the entire desktop and then also perform that capture. + +// The original version of this file lives in the Chromium repository at: +// src/components/arc/common/screen_capture.mojom + +module arc.mojom; + +// For gfx::Size. +import "video_common.mojom"; + +// Implemented by Chrome in order to allow requesting of permissions to perform +// desktop capture as well as creating a session for it. +interface ScreenCaptureHost { + // This will also show the desktop picker in case of multiple displays and + // will then link that desktop window to the granted permission. + // display_name is the string that should be used in the UI + // package_name is what should be used as the permission token + // returns true if the user accepts, false otherwise + RequestPermission@0(string display_name, string package_name) => (bool granted); + + // Starts a new capture session, binding the session interface to the passed + // in session request. + // notifier interface passed in will be used to send messages back to Android + // for when updates are needed by the Chrome rendering engine + // package_name should correspond to what was passed into the + // RequestPermission call + // size should have the width/height of the buffers used + // returns null interface in the case the permission was not granted, a valid + // interface pointer otherwise + OpenSession@1(ScreenCaptureSessionNotifier notifier, + string package_name, Size size) => + (ScreenCaptureSession? session); +}; + +// Implemented by Chrome for handling a screen capture session. +interface ScreenCaptureSession { + // Called to set the graphics buffer that the screen capture should be + // rendered to. This call does not return until the rendering is complete to + // the passed in buffer. + // graphics_buffer should be a handle to the buffer which corresponds to the + // surface being rendered to + // stride is the stride in pixels for each row of the buffer + SetOutputBuffer@0(handle graphics_buffer, uint32 stride) => (); +}; + +// Implemented by Android. +interface ScreenCaptureInstance { + // Establishes full-duplex communication with the host. + Init@0(ScreenCaptureHost host_ptr) => (); +}; + +// Implemented by Android as a callback mechanism. +interface ScreenCaptureSessionNotifier { + // This is called when Chrome detects a compositor update but Android is not + // actively rendering. This will occur if the Android windows are minimized or + // not animating but Chrome windows are since Android’s rendering stack does + // not update if nothing in Android itself is changing. + ForceUpdate@0(); +};
diff --git a/components/arc/test/fake_arc_bridge_host.cc b/components/arc/test/fake_arc_bridge_host.cc index 148f5c22..c4c567a7 100644 --- a/components/arc/test/fake_arc_bridge_host.cc +++ b/components/arc/test/fake_arc_bridge_host.cc
@@ -90,6 +90,9 @@ void FakeArcBridgeHost::OnRotationLockInstanceReady( mojom::RotationLockInstancePtr rotation_lock_ptr) {} +void FakeArcBridgeHost::OnScreenCaptureInstanceReady( + mojom::ScreenCaptureInstancePtr screen_capture_ptr) {} + void FakeArcBridgeHost::OnStorageManagerInstanceReady( mojom::StorageManagerInstancePtr storage_manager_ptr) {}
diff --git a/components/arc/test/fake_arc_bridge_host.h b/components/arc/test/fake_arc_bridge_host.h index cce1ad2b..83036ea 100644 --- a/components/arc/test/fake_arc_bridge_host.h +++ b/components/arc/test/fake_arc_bridge_host.h
@@ -60,6 +60,8 @@ void OnProcessInstanceReady(mojom::ProcessInstancePtr process_ptr) override; void OnRotationLockInstanceReady( mojom::RotationLockInstancePtr rotation_lock_ptr) override; + void OnScreenCaptureInstanceReady( + mojom::ScreenCaptureInstancePtr screen_capture_ptr) override; void OnStorageManagerInstanceReady( mojom::StorageManagerInstancePtr storage_manager_ptr) override; void OnTracingInstanceReady(mojom::TracingInstancePtr trace_ptr) override;
diff --git a/components/browsing_data/core/counters/history_counter.cc b/components/browsing_data/core/counters/history_counter.cc index 93d8e0e3..dfa5433 100644 --- a/components/browsing_data/core/counters/history_counter.cc +++ b/components/browsing_data/core/counters/history_counter.cc
@@ -88,7 +88,7 @@ history::QueryOptions options; options.max_count = 1; options.begin_time = GetPeriodStart(); - options.end_time = base::Time::Max(); + options.end_time = GetPeriodEnd(); net::PartialNetworkTrafficAnnotationTag partial_traffic_annotation = net::DefinePartialNetworkTrafficAnnotation("web_history_counter", "web_history_service",
diff --git a/components/component_updater/component_installer.cc b/components/component_updater/component_installer.cc index 499b32a..903ad21 100644 --- a/components/component_updater/component_installer.cc +++ b/components/component_updater/component_installer.cc
@@ -22,6 +22,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "base/values.h" #include "base/version.h" +#include "build/build_config.h" #include "components/component_updater/component_updater_paths.h" #include "components/component_updater/component_updater_service.h" #include "components/update_client/component_unpacker.h"
diff --git a/components/cronet/url_request_context_config.cc b/components/cronet/url_request_context_config.cc index 7dc920ad8..0a6ebfb 100644 --- a/components/cronet/url_request_context_config.cc +++ b/components/cronet/url_request_context_config.cc
@@ -29,14 +29,9 @@ #include "net/nqe/network_quality_estimator_params.h" #include "net/quic/chromium/quic_utils_chromium.h" #include "net/quic/core/quic_packets.h" -#include "net/reporting/reporting_policy.h" #include "net/socket/ssl_client_socket.h" #include "net/url_request/url_request_context_builder.h" -#if BUILDFLAG(ENABLE_REPORTING) -#include "net/reporting/reporting_policy.h" -#endif // BUILDFLAG(ENABLE_REPORTING) - namespace cronet { namespace { @@ -110,11 +105,6 @@ // NetworkQualityEstimator (NQE) experiment dictionary name. const char kNetworkQualityEstimatorFieldTrialName[] = "NetworkQualityEstimator"; -// Network Error Logging experiment dictionary name. -const char kNetworkErrorLoggingFieldTrialName[] = "NetworkErrorLogging"; -// Name of boolean to enable Reporting API. -const char kNetworkErrorLoggingEnable[] = "enable"; - // Disable IPv6 when on WiFi. This is a workaround for a known issue on certain // Android phones, and should not be necessary when not on one of those devices. // See https://crbug.com/696569 for details. @@ -219,7 +209,6 @@ bool stale_dns_enable = false; bool host_resolver_rules_enable = false; bool disable_ipv6_on_wifi = false; - bool nel_enable = false; effective_experimental_options = dict->CreateDeepCopy(); StaleHostResolver::StaleOptions stale_dns_options; @@ -423,15 +412,6 @@ } host_resolver_rules_enable = host_resolver_rules_args->GetString( kHostResolverRules, &host_resolver_rules_string); - } else if (it.key() == kNetworkErrorLoggingFieldTrialName) { - const base::DictionaryValue* nel_args = nullptr; - if (!it.value().GetAsDictionary(&nel_args)) { - LOG(ERROR) << "\"" << it.key() << "\" config params \"" << it.value() - << "\" is not a dictionary value"; - effective_experimental_options->Remove(it.key(), nullptr); - continue; - } - nel_args->GetBoolean(kNetworkErrorLoggingEnable, &nel_enable); } else if (it.key() == kDisableIPv6OnWifi) { if (!it.value().GetAsBoolean(&disable_ipv6_on_wifi)) { LOG(ERROR) << "\"" << it.key() << "\" config params \"" << it.value() @@ -503,23 +483,6 @@ } context_builder->set_host_resolver(std::move(host_resolver)); } - -#if BUILDFLAG(ENABLE_REPORTING) - if (nel_enable) { - auto policy = std::make_unique<net::ReportingPolicy>(); - - // Apps (like Cronet embedders) are generally allowed to run in the - // background, even across network changes, so use more relaxed privacy - // settings than when Reporting is running in the browser. - policy->persist_reports_across_restarts = true; - policy->persist_clients_across_restarts = true; - policy->clear_reports_on_network_changes = false; - policy->clear_clients_on_network_changes = false; - - context_builder->set_reporting_policy(std::move(policy)); - context_builder->set_network_error_logging_enabled(true); - } -#endif // BUILDFLAG(ENABLE_REPORTING) } void URLRequestContextConfig::ConfigureURLRequestContextBuilder(
diff --git a/components/cronet/url_request_context_config_unittest.cc b/components/cronet/url_request_context_config_unittest.cc index 39666e862..20f938c 100644 --- a/components/cronet/url_request_context_config_unittest.cc +++ b/components/cronet/url_request_context_config_unittest.cc
@@ -52,7 +52,6 @@ "\"race_cert_verification\":true," "\"connection_options\":\"TIME,TBBR,REJ\"}," "\"AsyncDNS\":{\"enable\":true}," - "\"NetworkErrorLogging\":{\"enable\":true}," "\"UnknownOption\":{\"foo\":true}," "\"HostResolverRules\":{\"host_resolver_rules\":" "\"MAP * 127.0.0.1\"}," @@ -107,13 +106,6 @@ EXPECT_TRUE(context->host_resolver()->GetDnsConfigAsValue()); #endif // defined(ENABLE_BUILT_IN_DNS) -#if BUILDFLAG(ENABLE_REPORTING) - // Check Reporting and Network Error Logging are enabled (can be disabled at - // build time). - EXPECT_TRUE(context->reporting_service()); - EXPECT_TRUE(context->network_error_logging_delegate()); -#endif // BUILDFLAG(ENABLE_REPORTING) - // Check IPv6 is disabled when on wifi. EXPECT_TRUE(context->host_resolver()->GetNoIPv6OnWifi());
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc index f13d6f99..7d4257c 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config.cc
@@ -493,20 +493,37 @@ DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(IsFetchInFlight()); - // Check the proxy server used, or disable all data saver proxies? - if (!IsDataReductionProxy(proxy_server, nullptr)) { - // No need to do anything here. + // If the probe times out, then proxy server information may not have been + // set by the URL fetcher. + bool timed_out_with_no_proxy_data = + (success_response == WarmupURLFetcher::FetchResult::kTimedOut && + !proxy_server.is_valid()); + + // Check the proxy server used. + if (!timed_out_with_no_proxy_data && + !IsDataReductionProxy(proxy_server, nullptr)) { + // No need to do anything here since the warmup fetch did not go through + // the data saver proxy. return; } - bool is_secure_proxy = proxy_server.is_https() || proxy_server.is_quic(); - bool is_core_proxy = IsDataReductionProxyServerCore(proxy_server); + bool is_secure_proxy = false; + bool is_core_proxy = false; - // The proxy server through which the warmup URL was fetched should match - // the proxy server for which the warmup URL is in-flight. - DCHECK(GetInFlightWarmupProxyDetails()); - DCHECK_EQ(is_secure_proxy, GetInFlightWarmupProxyDetails()->first); - DCHECK_EQ(is_core_proxy, GetInFlightWarmupProxyDetails()->second); + if (!timed_out_with_no_proxy_data) { + is_secure_proxy = proxy_server.is_https() || proxy_server.is_quic(); + is_core_proxy = IsDataReductionProxyServerCore(proxy_server); + // The proxy server through which the warmup URL was fetched should match + // the proxy server for which the warmup URL is in-flight. + DCHECK(GetInFlightWarmupProxyDetails()); + DCHECK_EQ(is_secure_proxy, GetInFlightWarmupProxyDetails()->first); + DCHECK_EQ(is_core_proxy, GetInFlightWarmupProxyDetails()->second); + } else { + // When the probe times out, the proxy information may not be set. Fill-in + // the missing data using the proxy that was being probed. + is_secure_proxy = warmup_url_fetch_in_flight_secure_proxy_; + is_core_proxy = warmup_url_fetch_in_flight_core_proxy_; + } if (is_secure_proxy && is_core_proxy) { UMA_HISTOGRAM_BOOLEAN(
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc index 541f676..3e40a19 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc
@@ -1298,6 +1298,62 @@ test_config()->SetInFlightWarmupProxyDetails(base::nullopt); } +// Tests the behavior when warmup URL fetcher times out. +TEST_F(DataReductionProxyConfigTest, HandleWarmupFetcherTimeout) { + base::HistogramTester histogram_tester; + const net::URLRequestStatus kSuccess(net::URLRequestStatus::SUCCESS, net::OK); + const net::ProxyServer kHttpsProxy = net::ProxyServer::FromURI( + "https://origin.net:443", net::ProxyServer::SCHEME_HTTP); + const net::ProxyServer kHttpProxy = net::ProxyServer::FromURI( + "fallback.net:80", net::ProxyServer::SCHEME_HTTP); + + SetProxiesForHttpOnCommandLine({kHttpsProxy, kHttpProxy}); + ResetSettings(); + + // Enable the proxy. + test_config()->SetWarmupURLFetchAttemptCounts(0); + test_config()->UpdateConfigForTesting(true, true, true); + + test_config()->SetIsFetchInFlight(true); + + histogram_tester.ExpectTotalCount( + "DataReductionProxy.WarmupURL.FetchInitiated", 0); + test_config()->OnNewClientConfigFetched(); + EXPECT_EQ(std::vector<net::ProxyServer>({kHttpsProxy, kHttpProxy}), + GetConfiguredProxiesForHttp()); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(std::vector<net::ProxyServer>({kHttpsProxy, kHttpProxy}), + GetConfiguredProxiesForHttp()); + + histogram_tester.ExpectTotalCount( + "DataReductionProxy.WarmupURLFetcherCallback.SuccessfulFetch." + "InsecureProxy.NonCore", + 0); + histogram_tester.ExpectTotalCount( + "DataReductionProxy.WarmupURLFetcherCallback.SuccessfulFetch." + "SecureProxy.NonCore", + 0); + histogram_tester.ExpectTotalCount( + "DataReductionProxy.WarmupURL.FetchInitiated", 1); + + // The first probe should go through the HTTPS data saver proxy. On fetch + // timeout, the HTTPS proxy must be disabled even though the callback did + // not specify a proxy. + test_config()->HandleWarmupFetcherResponse( + net::ProxyServer(), WarmupURLFetcher::FetchResult::kTimedOut); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(std::vector<net::ProxyServer>({kHttpProxy}), + GetConfiguredProxiesForHttp()); + histogram_tester.ExpectUniqueSample( + "DataReductionProxy.WarmupURLFetcherCallback.SuccessfulFetch." + "SecureProxy.NonCore", + 0, 1); + + // Warmup URL should be fetched from the next proxy. + histogram_tester.ExpectTotalCount( + "DataReductionProxy.WarmupURL.FetchInitiated", 2); +} + TEST_F(DataReductionProxyConfigTest, HandleWarmupFetcherRetryWithConnectionChange) { constexpr size_t kMaxWarmupURLFetchAttempts = 3;
diff --git a/components/data_reduction_proxy/core/browser/warmup_url_fetcher.cc b/components/data_reduction_proxy/core/browser/warmup_url_fetcher.cc index f11bb1c..7c1a58cd 100644 --- a/components/data_reduction_proxy/core/browser/warmup_url_fetcher.cc +++ b/components/data_reduction_proxy/core/browser/warmup_url_fetcher.cc
@@ -29,9 +29,9 @@ const scoped_refptr<net::URLRequestContextGetter>& url_request_context_getter, WarmupURLFetcherCallback callback) - : previous_attempt_counts_(0), + : is_fetch_in_flight_(false), + previous_attempt_counts_(0), url_request_context_getter_(url_request_context_getter), - is_fetch_in_flight_(false), callback_(callback) { DCHECK(url_request_context_getter_); DCHECK(url_request_context_getter_->GetURLRequestContext() @@ -41,6 +41,8 @@ WarmupURLFetcher::~WarmupURLFetcher() {} void WarmupURLFetcher::FetchWarmupURL(size_t previous_attempt_counts) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + previous_attempt_counts_ = previous_attempt_counts; DCHECK_LE(0u, previous_attempt_counts_); @@ -58,6 +60,7 @@ } base::TimeDelta WarmupURLFetcher::GetFetchWaitTime() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_LT(0u, previous_attempt_counts_); DCHECK_GE(2u, previous_attempt_counts_); @@ -68,6 +71,8 @@ } void WarmupURLFetcher::FetchWarmupURLNow() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + UMA_HISTOGRAM_EXACT_LINEAR("DataReductionProxy.WarmupURL.FetchInitiated", 1, 2); net::NetworkTrafficAnnotationTag traffic_annotation = @@ -96,6 +101,7 @@ GetWarmupURLWithQueryParam(&warmup_url_with_query_params); fetcher_.reset(); + fetch_timeout_timer_.Stop(); is_fetch_in_flight_ = true; fetcher_ = @@ -114,11 +120,15 @@ static const int kMaxRetries = 5; fetcher_->SetAutomaticallyRetryOn5xx(false); fetcher_->SetAutomaticallyRetryOnNetworkChanges(kMaxRetries); + fetch_timeout_timer_.Start(FROM_HERE, GetFetchTimeout(), this, + &WarmupURLFetcher::OnFetchTimeout); fetcher_->Start(); } void WarmupURLFetcher::GetWarmupURLWithQueryParam( GURL* warmup_url_with_query_params) const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + // Set the query param to a random string to prevent intermediate middleboxes // from returning cached content. const std::string query = "q=" + base::GenerateGUID(); @@ -133,6 +143,7 @@ } void WarmupURLFetcher::OnURLFetchComplete(const net::URLFetcher* source) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_EQ(source, fetcher_.get()); DCHECK(is_fetch_in_flight_); @@ -161,8 +172,7 @@ if (!GetFieldTrialParamByFeatureAsBool( features::kDataReductionProxyRobustConnection, "warmup_fetch_callback_enabled", false)) { - // Running the callback is not enabled. - is_fetch_in_flight_ = false; + CleanupAfterFetch(); return; } @@ -171,7 +181,7 @@ // Fetching failed due to Internet unavailability, and not due to some // error. Set the proxy server to unknown. callback_.Run(net::ProxyServer(), FetchResult::kSuccessful); - is_fetch_in_flight_ = false; + CleanupAfterFetch(); return; } @@ -184,11 +194,84 @@ callback_.Run(source->ProxyServerUsed(), success_response ? FetchResult::kSuccessful : FetchResult::kFailed); - is_fetch_in_flight_ = false; + CleanupAfterFetch(); } bool WarmupURLFetcher::IsFetchInFlight() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + return is_fetch_in_flight_; } +base::TimeDelta WarmupURLFetcher::GetFetchTimeout() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK_LE(0u, previous_attempt_counts_); + DCHECK_GE(2u, previous_attempt_counts_); + + // The timeout value should always be between kMinTimeout and kMaxTimeout + // (both inclusive). + constexpr base::TimeDelta kMinTimeout = base::TimeDelta::FromSeconds(8); + constexpr base::TimeDelta kMaxTimeout = base::TimeDelta::FromSeconds(60); + + // Set the timeout based on how many times the fetching of the warmup URL + // has been tried. + size_t http_rtt_multiplier = 5; + if (previous_attempt_counts_ == 1) { + http_rtt_multiplier = 10; + } else if (previous_attempt_counts_ == 2) { + http_rtt_multiplier = 20; + } + + const net::NetworkQualityEstimator* network_quality_estimator = + url_request_context_getter_->GetURLRequestContext() + ->network_quality_estimator(); + + base::Optional<base::TimeDelta> http_rtt_estimate = + network_quality_estimator->GetHttpRTT(); + if (!http_rtt_estimate) + return kMaxTimeout; + + base::TimeDelta timeout = http_rtt_multiplier * http_rtt_estimate.value(); + if (timeout > kMaxTimeout) + return kMaxTimeout; + + if (timeout < kMinTimeout) + return kMinTimeout; + + return timeout; +} + +void WarmupURLFetcher::OnFetchTimeout() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(is_fetch_in_flight_); + DCHECK(fetcher_); + + const net::ProxyServer proxy_server = fetcher_->ProxyServerUsed(); + DCHECK_LE(1, proxy_server.scheme()); + + UMA_HISTOGRAM_BOOLEAN("DataReductionProxy.WarmupURL.FetchSuccessful", false); + base::UmaHistogramSparse("DataReductionProxy.WarmupURL.NetError", + net::ERR_ABORTED); + base::UmaHistogramSparse("DataReductionProxy.WarmupURL.HttpResponseCode", + std::abs(net::URLFetcher::RESPONSE_CODE_INVALID)); + + if (!GetFieldTrialParamByFeatureAsBool( + features::kDataReductionProxyRobustConnection, + "warmup_fetch_callback_enabled", false)) { + // Running the callback is not enabled. + CleanupAfterFetch(); + return; + } + + callback_.Run(proxy_server, FetchResult::kTimedOut); + CleanupAfterFetch(); +} + +void WarmupURLFetcher::CleanupAfterFetch() { + is_fetch_in_flight_ = false; + fetcher_.reset(); + fetch_timeout_timer_.Stop(); + fetch_delay_timer_.Stop(); +} + } // namespace data_reduction_proxy
diff --git a/components/data_reduction_proxy/core/browser/warmup_url_fetcher.h b/components/data_reduction_proxy/core/browser/warmup_url_fetcher.h index 9a50275..41cd9d47 100644 --- a/components/data_reduction_proxy/core/browser/warmup_url_fetcher.h +++ b/components/data_reduction_proxy/core/browser/warmup_url_fetcher.h
@@ -10,6 +10,7 @@ #include "base/callback.h" #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "base/sequence_checker.h" #include "base/timer/timer.h" #include "net/url_request/url_fetcher_delegate.h" @@ -59,30 +60,48 @@ // delayed. virtual base::TimeDelta GetFetchWaitTime() const; + // Returns the timeout value for fetching the secure proxy URL. Virtualized + // for testing. + virtual base::TimeDelta GetFetchTimeout() const; + + // Called when the fetch timeouts. + void OnFetchTimeout(); + + void OnURLFetchComplete(const net::URLFetcher* source) override; + + // The URLFetcher being used for fetching the warmup URL. Protected for + // testing. + std::unique_ptr<net::URLFetcher> fetcher_; + + // Timer used to delay the fetching of the warmup probe URL. + base::OneShotTimer fetch_delay_timer_; + + // Timer to enforce timeout of fetching the warmup URL. + base::OneShotTimer fetch_timeout_timer_; + + // True if the fetcher for warmup URL is in-flight. + bool is_fetch_in_flight_; + private: // Creates and immediately starts a URLFetcher that fetches the warmup URL. void FetchWarmupURLNow(); - void OnURLFetchComplete(const net::URLFetcher* source) override; + // Resets the variable after the fetching of the warmup URL has completed or + // timed out. Must be called after |callback_| has been run. + void CleanupAfterFetch(); // Count of fetch attempts that have been made to the proxy which is being // probed. size_t previous_attempt_counts_; - // Timer used to delay the fetching of the warmup probe URL. - base::OneShotTimer fetch_delay_timer_; - scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_; - // The URLFetcher being used for fetching the warmup URL. - std::unique_ptr<net::URLFetcher> fetcher_; - - bool is_fetch_in_flight_; - // Callback that should be executed when the fetching of the warmup URL is // completed. WarmupURLFetcherCallback callback_; + SEQUENCE_CHECKER(sequence_checker_); + DISALLOW_COPY_AND_ASSIGN(WarmupURLFetcher); };
diff --git a/components/data_reduction_proxy/core/browser/warmup_url_fetcher_unittest.cc b/components/data_reduction_proxy/core/browser/warmup_url_fetcher_unittest.cc index 817ec07..ec8d654 100644 --- a/components/data_reduction_proxy/core/browser/warmup_url_fetcher_unittest.cc +++ b/components/data_reduction_proxy/core/browser/warmup_url_fetcher_unittest.cc
@@ -12,6 +12,7 @@ #include "base/macros.h" #include "base/message_loop/message_loop.h" #include "base/run_loop.h" +#include "base/test/gtest_util.h" #include "base/test/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "base/threading/platform_thread.h" @@ -24,6 +25,7 @@ #include "net/url_request/url_fetcher.h" #include "net/url_request/url_request_context_getter.h" #include "net/url_request/url_request_test_util.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" namespace data_reduction_proxy { @@ -66,8 +68,29 @@ fetch_wait_time_ = fetch_wait_time; } + void SetFetchTimeout(base::Optional<base::TimeDelta> fetch_timeout) { + fetch_timeout_ = fetch_timeout; + } + using WarmupURLFetcher::FetchWarmupURL; using WarmupURLFetcher::GetWarmupURLWithQueryParam; + using WarmupURLFetcher::OnFetchTimeout; + using WarmupURLFetcher::OnURLFetchComplete; + + base::TimeDelta GetFetchTimeout() const override { + if (!fetch_timeout_) + return WarmupURLFetcher::GetFetchTimeout(); + return fetch_timeout_.value(); + } + + void VerifyStateCleanedUp() const { + DCHECK(!fetcher_); + DCHECK(!fetch_delay_timer_.IsRunning()); + DCHECK(!fetch_timeout_timer_.IsRunning()); + DCHECK(!is_fetch_in_flight_); + } + + net::URLFetcher* fetcher() const { return fetcher_.get(); } private: void HandleWarmupFetcherResponse(const net::ProxyServer& proxy_server, @@ -81,6 +104,7 @@ size_t callback_received_count_ = 0; net::ProxyServer proxy_server_last_; FetchResult success_response_last_ = FetchResult::kFailed; + base::Optional<base::TimeDelta> fetch_timeout_; DISALLOW_COPY_AND_ASSIGN(WarmupURLFetcherTest); }; @@ -118,6 +142,7 @@ query_param_different = true; } EXPECT_TRUE(query_param_different); + warmup_url_fetcher.VerifyStateCleanedUp(); } TEST(WarmupURLFetcherTest, TestSuccessfulFetchWarmupURLNoViaHeader) { @@ -180,6 +205,7 @@ // the via header. EXPECT_EQ(WarmupURLFetcher::FetchResult::kFailed, warmup_url_fetcher.success_response_last()); + warmup_url_fetcher.VerifyStateCleanedUp(); } TEST(WarmupURLFetcherTest, TestSuccessfulFetchWarmupURLWithViaHeader) { @@ -242,6 +268,10 @@ // The last response contained the via header. EXPECT_EQ(WarmupURLFetcher::FetchResult::kSuccessful, warmup_url_fetcher.success_response_last()); + warmup_url_fetcher.VerifyStateCleanedUp(); + + // If the fetch times out, it should cause DCHECK to trigger. + EXPECT_DCHECK_DEATH(warmup_url_fetcher.OnFetchTimeout()); } TEST(WarmupURLFetcherTest, @@ -295,6 +325,7 @@ // The callback should not be run. EXPECT_EQ(0u, warmup_url_fetcher.callback_received_count()); + warmup_url_fetcher.VerifyStateCleanedUp(); } TEST(WarmupURLFetcherTest, TestConnectionResetFetchWarmupURL) { @@ -351,6 +382,67 @@ warmup_url_fetcher.proxy_server_last().scheme()); EXPECT_EQ(WarmupURLFetcher::FetchResult::kFailed, warmup_url_fetcher.success_response_last()); + warmup_url_fetcher.VerifyStateCleanedUp(); +} + +TEST(WarmupURLFetcherTest, TestFetchTimesout) { + base::test::ScopedFeatureList scoped_feature_list; + WarmupURLFetcherTest::InitExperiment(&scoped_feature_list); + + base::HistogramTester histogram_tester; + base::MessageLoopForIO message_loop; + const std::string config = "foobarbaz"; + std::vector<std::unique_ptr<net::SocketDataProvider>> socket_data_providers; + net::MockClientSocketFactory mock_socket_factory; + net::MockRead success_reads[3]; + success_reads[0] = net::MockRead( + "HTTP/1.1 204 OK\r\nVia: 1.1 Chrome-Compression-Proxy\r\n\r\n"); + success_reads[1] = net::MockRead(net::ASYNC, config.c_str(), config.length()); + success_reads[2] = net::MockRead(net::SYNCHRONOUS, net::OK); + + socket_data_providers.push_back( + (base::MakeUnique<net::StaticSocketDataProvider>( + success_reads, arraysize(success_reads), nullptr, 0))); + mock_socket_factory.AddSocketDataProvider(socket_data_providers.back().get()); + + std::unique_ptr<net::TestURLRequestContext> test_request_context( + new net::TestURLRequestContext(true)); + + test_request_context->set_client_socket_factory(&mock_socket_factory); + test_request_context->Init(); + scoped_refptr<net::URLRequestContextGetter> request_context_getter = + new net::TestURLRequestContextGetter(message_loop.task_runner(), + std::move(test_request_context)); + net::TestNetworkQualityEstimator estimator; + request_context_getter->GetURLRequestContext()->set_network_quality_estimator( + &estimator); + + WarmupURLFetcherTest warmup_url_fetcher(request_context_getter); + // Set the timeout to a very low value. This should cause warmup URL fetcher + // to run the callback with appropriate error code. + warmup_url_fetcher.SetFetchTimeout(base::TimeDelta::FromSeconds(0)); + EXPECT_FALSE(warmup_url_fetcher.IsFetchInFlight()); + warmup_url_fetcher.FetchWarmupURL(0); + EXPECT_TRUE(warmup_url_fetcher.IsFetchInFlight()); + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(warmup_url_fetcher.IsFetchInFlight()); + + histogram_tester.ExpectUniqueSample( + "DataReductionProxy.WarmupURL.FetchInitiated", 1, 1); + histogram_tester.ExpectUniqueSample( + "DataReductionProxy.WarmupURL.FetchSuccessful", 0, 1); + histogram_tester.ExpectUniqueSample("DataReductionProxy.WarmupURL.NetError", + net::ERR_ABORTED, 1); + + EXPECT_EQ(1u, warmup_url_fetcher.callback_received_count()); + // The last response should have timedout. + EXPECT_EQ(WarmupURLFetcher::FetchResult::kTimedOut, + warmup_url_fetcher.success_response_last()); + warmup_url_fetcher.VerifyStateCleanedUp(); + + // If the URL fetch completes, it should cause DCHECK to trigger. + EXPECT_DCHECK_DEATH( + warmup_url_fetcher.OnURLFetchComplete(warmup_url_fetcher.fetcher())); } TEST(WarmupURLFetcherTest, TestSuccessfulFetchWarmupURLWithDelay) { @@ -416,6 +508,49 @@ // header. EXPECT_EQ(WarmupURLFetcher::FetchResult::kSuccessful, warmup_url_fetcher.success_response_last()); + warmup_url_fetcher.VerifyStateCleanedUp(); +} + +TEST(WarmupURLFetcherTest, TestFetchTimeoutIncreasing) { + // Must remain in sync with warmup_url_fetcher.cc. + constexpr base::TimeDelta kMinTimeout = base::TimeDelta::FromSeconds(8); + constexpr base::TimeDelta kMaxTimeout = base::TimeDelta::FromSeconds(60); + + base::HistogramTester histogram_tester; + base::MessageLoopForIO message_loop; + + std::unique_ptr<net::TestURLRequestContext> test_request_context( + new net::TestURLRequestContext(true)); + + test_request_context->Init(); + scoped_refptr<net::URLRequestContextGetter> request_context_getter = + new net::TestURLRequestContextGetter(message_loop.task_runner(), + std::move(test_request_context)); + net::TestNetworkQualityEstimator estimator; + request_context_getter->GetURLRequestContext()->set_network_quality_estimator( + &estimator); + + WarmupURLFetcherTest warmup_url_fetcher(request_context_getter); + EXPECT_FALSE(warmup_url_fetcher.IsFetchInFlight()); + + EXPECT_EQ(kMinTimeout, warmup_url_fetcher.GetFetchTimeout()); + + base::TimeDelta http_rtt = base::TimeDelta::FromSeconds(2); + estimator.SetStartTimeNullHttpRtt(http_rtt); + EXPECT_EQ(http_rtt * 5, warmup_url_fetcher.GetFetchTimeout()); + + warmup_url_fetcher.FetchWarmupURL(1); + EXPECT_EQ(http_rtt * 10, warmup_url_fetcher.GetFetchTimeout()); + + warmup_url_fetcher.FetchWarmupURL(2); + EXPECT_EQ(http_rtt * 20, warmup_url_fetcher.GetFetchTimeout()); + + http_rtt = base::TimeDelta::FromSeconds(5); + estimator.SetStartTimeNullHttpRtt(http_rtt); + EXPECT_EQ(kMaxTimeout, warmup_url_fetcher.GetFetchTimeout()); + + warmup_url_fetcher.FetchWarmupURL(0); + EXPECT_EQ(http_rtt * 5, warmup_url_fetcher.GetFetchTimeout()); } } // namespace
diff --git a/components/exo/surface.cc b/components/exo/surface.cc index 6b9d48a..d636360 100644 --- a/components/exo/surface.cc +++ b/components/exo/surface.cc
@@ -23,7 +23,6 @@ #include "components/viz/common/quads/solid_color_draw_quad.h" #include "components/viz/common/quads/texture_draw_quad.h" #include "components/viz/common/resources/single_release_callback.h" -#include "components/viz/common/surfaces/sequence_surface_reference_factory.h" #include "components/viz/service/surfaces/surface.h" #include "components/viz/service/surfaces/surface_manager.h" #include "services/ui/public/interfaces/window_tree_constants.mojom.h"
diff --git a/components/image_fetcher/core/image_fetcher_impl.cc b/components/image_fetcher/core/image_fetcher_impl.cc index ccbc25c..0cf6c10 100644 --- a/components/image_fetcher/core/image_fetcher_impl.cc +++ b/components/image_fetcher/core/image_fetcher_impl.cc
@@ -101,7 +101,8 @@ // Run all callbacks for (const auto& callback : request->callbacks) { - callback.Run(request->id, image, metadata); + if (callback) + callback.Run(request->id, image, metadata); } // Inform the ImageFetcherDelegate.
diff --git a/components/ntp_tiles/most_visited_sites.cc b/components/ntp_tiles/most_visited_sites.cc index 2722ce9..1fcfc627 100644 --- a/components/ntp_tiles/most_visited_sites.cc +++ b/components/ntp_tiles/most_visited_sites.cc
@@ -563,8 +563,10 @@ int num_personal_tiles = 0; for (const auto& tile : *current_tiles_) { - if (tile.source != TileSource::POPULAR) + if (tile.source != TileSource::POPULAR && + tile.source != TileSource::POPULAR_BAKED_IN) { num_personal_tiles++; + } } prefs_->SetInteger(prefs::kNumPersonalTiles, num_personal_tiles); if (!observer_)
diff --git a/components/omnibox/browser/autocomplete_controller.h b/components/omnibox/browser/autocomplete_controller.h index b6a6d550..a059b81 100644 --- a/components/omnibox/browser/autocomplete_controller.h +++ b/components/omnibox/browser/autocomplete_controller.h
@@ -147,6 +147,7 @@ FRIEND_TEST_ALL_PREFIXES(OmniboxViewTest, DoesNotUpdateAutocompleteOnBlur); FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsTest, CloseOmniboxPopupOnTextDrag); FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsTest, FriendlyAccessibleLabel); + FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsTest, AccessiblePopup); FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsTest, MaintainCursorAfterFocusCycle); FRIEND_TEST_ALL_PREFIXES(OmniboxPopupModelTest, SetSelectedLine);
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index d685b56..a652098 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -5265,11 +5265,12 @@ 'name': 'EnableCommonNameFallbackForLocalAnchors', 'type': 'main', 'schema': { 'type': 'boolean' }, - 'supported_on': ['chrome.*:58-66', 'chrome_os:58-66', 'android:58-66'], + 'supported_on': ['chrome.*:58-65', 'chrome_os:58-65', 'android:58-65'], 'features': { 'dynamic_refresh': True, 'per_profile': False, }, + 'deprecated': True, 'example_value': False, 'id': 366, 'caption': '''Whether to allow certificates issued by local trust anchors that are missing the subjectAlternativeName extension''',
diff --git a/components/security_interstitials/core/browser/resources/list_of_interstitials.html b/components/security_interstitials/core/browser/resources/list_of_interstitials.html index 639d6769..6da45f27 100644 --- a/components/security_interstitials/core/browser/resources/list_of_interstitials.html +++ b/components/security_interstitials/core/browser/resources/list_of_interstitials.html
@@ -44,6 +44,9 @@ <a href="ssl?type=hpkp_failure">Pinned certificate error</a> </li> <li> + <a href="ssl?type=ct_failure&overridable=1">Certificate Transparency error</a> + </li> + <li> <a href="superfish-ssl">Superfish</a> </li> <li>
diff --git a/components/signin/core/browser/BUILD.gn b/components/signin/core/browser/BUILD.gn index 9bbfc29..951cf3e 100644 --- a/components/signin/core/browser/BUILD.gn +++ b/components/signin/core/browser/BUILD.gn
@@ -118,17 +118,20 @@ "//components/signin/core/browser:signin_features", "//google_apis", "//net", + "//ui/gfx", "//url", ] deps = [ "//base:i18n", "//components/data_use_measurement/core", "//components/google/core/browser", + "//components/image_fetcher/core", "//components/metrics", "//components/os_crypt", "//components/pref_registry", "//components/webdata/common", "//crypto", + "//skia", "//sql", "//third_party/icu", "//third_party/re2", @@ -186,6 +189,7 @@ public_deps = [ ":browser", "//base", + "//components/image_fetcher/core/", "//components/prefs:test_support", "//components/webdata/common", "//google_apis:test_support",
diff --git a/components/signin/core/browser/DEPS b/components/signin/core/browser/DEPS index 1daccb8f..8808770 100644 --- a/components/signin/core/browser/DEPS +++ b/components/signin/core/browser/DEPS
@@ -1,8 +1,10 @@ include_rules = [ "+components/data_use_measurement/core", + "+components/image_fetcher/core", "+components/invalidation/public", "+components/metrics", "+google/cacheinvalidation", "+jni", "+third_party/re2", + "+ui/gfx", ]
diff --git a/components/signin/core/browser/account_fetcher_service.cc b/components/signin/core/browser/account_fetcher_service.cc index ce77941..7027fef 100644 --- a/components/signin/core/browser/account_fetcher_service.cc +++ b/components/signin/core/browser/account_fetcher_service.cc
@@ -10,10 +10,13 @@ #include "base/metrics/field_trial.h" #include "base/trace_event/trace_event.h" #include "build/build_config.h" +#include "components/image_fetcher/core/image_decoder.h" +#include "components/image_fetcher/core/image_fetcher_impl.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_service.h" #include "components/signin/core/browser/account_info_fetcher.h" #include "components/signin/core/browser/account_tracker_service.h" +#include "components/signin/core/browser/avatar_icon_util.h" #include "components/signin/core/browser/child_account_info_fetcher.h" #include "components/signin/core/browser/signin_client.h" #include "components/signin/core/browser/signin_switches.h" @@ -24,6 +27,8 @@ const base::TimeDelta kRefreshFromTokenServiceDelay = base::TimeDelta::FromHours(24); +constexpr int kAccountImageDownloadSize = 64; + bool AccountSupportsUserInfo(const std::string& account_id) { // Supervised users use a specially scoped token which when used for general // purposes causes the token service to raise spurious auth errors. @@ -32,7 +37,7 @@ return account_id != "managed_user@localhost"; } -} +} // namespace // This pref used to be in the AccountTrackerService, hence its string value. const char AccountFetcherService::kLastUpdatePref[] = @@ -65,7 +70,8 @@ void AccountFetcherService::Initialize( SigninClient* signin_client, OAuth2TokenService* token_service, - AccountTrackerService* account_tracker_service) { + AccountTrackerService* account_tracker_service, + std::unique_ptr<image_fetcher::ImageDecoder> image_decoder) { DCHECK(signin_client); DCHECK(!signin_client_); signin_client_ = signin_client; @@ -76,6 +82,9 @@ DCHECK(!token_service_); token_service_ = token_service; token_service_->AddObserver(this); + DCHECK(image_decoder); + DCHECK(!image_decoder_); + image_decoder_ = std::move(image_decoder); last_updated_ = base::Time::FromInternalValue( signin_client_->GetPrefs()->GetInt64(kLastUpdatePref)); @@ -247,9 +256,60 @@ std::unique_ptr<base::DictionaryValue> user_info) { account_tracker_service_->SetAccountStateFromUserInfo(account_id, user_info.get()); + FetchAccountImage(account_id); user_info_requests_.erase(account_id); } +image_fetcher::ImageFetcherImpl* +AccountFetcherService::GetOrCreateImageFetcher() { + // Lazy initialization of |image_fetcher_| because the request context might + // not be available yet when |Initialize| is called. + if (!image_fetcher_) { + image_fetcher_ = std::make_unique<image_fetcher::ImageFetcherImpl>( + std::move(image_decoder_), signin_client_->GetURLRequestContext()); + image_fetcher_->SetImageFetcherDelegate(this); + } + return image_fetcher_.get(); +} + +void AccountFetcherService::FetchAccountImage(const std::string& account_id) { + DCHECK(signin_client_); + std::string picture_url_string = + account_tracker_service_->GetAccountInfo(account_id).picture_url; + GURL picture_url(picture_url_string); + if (!picture_url.is_valid()) { + DVLOG(1) << "Invalid avatar picture URL: \"" + picture_url_string + "\""; + return; + } + net::NetworkTrafficAnnotationTag traffic_annotation = + net::DefineNetworkTrafficAnnotation("accounts_image_fetcher", R"( + semantics { + sender: "Image fetcher for GAIA accounts" + description: + "To use a GAIA web account to log into Chrome in the user menu, the" + "account images of the signed-in GAIA accounts are displayed." + trigger: "At startup." + data: "Account picture URL of signed-in GAIA accounts." + destination: GOOGLE_OWNED_SERVICE + } + policy { + cookies_allowed: YES + cookies_store: "user" + setting: "This feature cannot be disabled by settings, " + "however, it will only be requested if the user " + "has signed into the web." + policy_exception_justification: + "Not implemented, considered not useful as no content is being " + "uploaded or saved; this request merely downloads the web account" + "profile image." + })"); + GURL image_url_with_size(signin::GetAvatarImageURLWithOptions( + picture_url, kAccountImageDownloadSize, true /* no_silhouette */)); + GetOrCreateImageFetcher()->StartOrQueueNetworkRequest( + account_id, image_url_with_size, + image_fetcher::ImageFetcher::ImageFetcherCallback(), traffic_annotation); +} + void AccountFetcherService::SetIsChildAccount(const std::string& account_id, bool is_child_account) { if (child_request_account_id_ == account_id) @@ -306,3 +366,8 @@ refresh_tokens_loaded_ = true; MaybeEnableNetworkFetches(); } + +void AccountFetcherService::OnImageFetched(const std::string& id, + const gfx::Image& image) { + account_tracker_service_->SetAccountImage(id, image); +}
diff --git a/components/signin/core/browser/account_fetcher_service.h b/components/signin/core/browser/account_fetcher_service.h index d8abc50..6e86435 100644 --- a/components/signin/core/browser/account_fetcher_service.h +++ b/components/signin/core/browser/account_fetcher_service.h
@@ -13,6 +13,7 @@ #include "base/macros.h" #include "base/sequence_checker.h" #include "base/timer/timer.h" +#include "components/image_fetcher/core/image_fetcher_delegate.h" #include "components/keyed_service/core/keyed_service.h" #include "google_apis/gaia/oauth2_token_service.h" @@ -22,6 +23,11 @@ class OAuth2TokenService; class SigninClient; +namespace image_fetcher { +class ImageDecoder; +class ImageFetcherImpl; +} // namespace image_fetcher + namespace invalidation { class InvalidationService; } @@ -34,7 +40,8 @@ // to child account info fetching. class AccountFetcherService : public KeyedService, - public OAuth2TokenService::Observer { + public OAuth2TokenService::Observer, + public image_fetcher::ImageFetcherDelegate { public: // Name of the preference that tracks the int64_t representation of the last // time the AccountTrackerService was updated. @@ -48,7 +55,8 @@ void Initialize(SigninClient* signin_client, OAuth2TokenService* token_service, - AccountTrackerService* account_tracker_service); + AccountTrackerService* account_tracker_service, + std::unique_ptr<image_fetcher::ImageDecoder> image_decoder); // KeyedService implementation void Shutdown() override; @@ -112,6 +120,14 @@ std::unique_ptr<base::DictionaryValue> user_info); void OnUserInfoFetchFailure(const std::string& account_id); + image_fetcher::ImageFetcherImpl* GetOrCreateImageFetcher(); + + // Called in |OnUserInfoFetchSuccess| after the account info has been fetched. + void FetchAccountImage(const std::string& account_id); + + // image_fetcher::ImageFetcherDelegate: + void OnImageFetched(const std::string& id, const gfx::Image& image) override; + AccountTrackerService* account_tracker_service_; // Not owned. OAuth2TokenService* token_service_; // Not owned. SigninClient* signin_client_; // Not owned. @@ -132,6 +148,10 @@ std::unordered_map<std::string, std::unique_ptr<AccountInfoFetcher>> user_info_requests_; + // Used for fetching the account images. + std::unique_ptr<image_fetcher::ImageFetcherImpl> image_fetcher_; + std::unique_ptr<image_fetcher::ImageDecoder> image_decoder_; + SEQUENCE_CHECKER(sequence_checker_); DISALLOW_COPY_AND_ASSIGN(AccountFetcherService);
diff --git a/components/signin/core/browser/account_tracker_service.cc b/components/signin/core/browser/account_tracker_service.cc index 2b0173c4..9b49e2a3 100644 --- a/components/signin/core/browser/account_tracker_service.cc +++ b/components/signin/core/browser/account_tracker_service.cc
@@ -145,6 +145,12 @@ return AccountInfo(); } +gfx::Image AccountTrackerService::GetAccountImage( + const std::string& account_id) { + return base::ContainsKey(accounts_, account_id) ? accounts_[account_id].image + : gfx::Image(); +} + AccountTrackerService::AccountIdMigrationState AccountTrackerService::GetMigrationState() const { return GetMigrationState(signin_client_->GetPrefs()); @@ -243,6 +249,12 @@ SaveToPrefs(state); } +void AccountTrackerService::SetAccountImage(const std::string& account_id, + const gfx::Image& image) { + DCHECK(base::ContainsKey(accounts_, account_id)); + accounts_[account_id].image = image; +} + void AccountTrackerService::SetIsChildAccount(const std::string& account_id, const bool& is_child_account) { DCHECK(base::ContainsKey(accounts_, account_id));
diff --git a/components/signin/core/browser/account_tracker_service.h b/components/signin/core/browser/account_tracker_service.h index 128dc73..65396fa 100644 --- a/components/signin/core/browser/account_tracker_service.h +++ b/components/signin/core/browser/account_tracker_service.h
@@ -18,6 +18,7 @@ #include "components/keyed_service/core/keyed_service.h" #include "components/signin/core/browser/account_info.h" #include "google_apis/gaia/gaia_auth_util.h" +#include "ui/gfx/image/image.h" class PrefService; class SigninClient; @@ -94,6 +95,10 @@ AccountInfo FindAccountInfoByGaiaId(const std::string& gaia_id) const; AccountInfo FindAccountInfoByEmail(const std::string& email) const; + // Returns the account image associated to the account id |account_id|. + // If the account id is not known an empty image is returned. + gfx::Image GetAccountImage(const std::string& account_id); + // Picks the correct account_id for the specified account depending on the // migration state. std::string PickAccountIdForAccount(const std::string& gaia, @@ -129,11 +134,16 @@ void SetAccountStateFromUserInfo(const std::string& account_id, const base::DictionaryValue* user_info); + // Assumes that there already exists an account with |account_id| in + // |accounts_|. + void SetAccountImage(const std::string& account_id, const gfx::Image& image); + private: friend class AccountFetcherService; friend class FakeAccountFetcherService; struct AccountState { AccountInfo info; + gfx::Image image; }; void NotifyAccountUpdated(const AccountState& state);
diff --git a/components/signin/core/browser/account_tracker_service_unittest.cc b/components/signin/core/browser/account_tracker_service_unittest.cc index 8b5cb75..56f20df 100644 --- a/components/signin/core/browser/account_tracker_service_unittest.cc +++ b/components/signin/core/browser/account_tracker_service_unittest.cc
@@ -74,7 +74,8 @@ } std::string AccountIdToPictureURL(const std::string& account_id) { - return "picture_url-" + account_id; + return "https://example.com/-" + account_id + + "/AAAAAAAAAAI/AAAAAAAAACQ/Efg/photo.jpg"; } void CheckAccountDetails(const std::string& account_id, @@ -276,9 +277,9 @@ account_tracker_->Initialize(signin_client_.get()); account_fetcher_.reset(new AccountFetcherService()); - account_fetcher_->Initialize(signin_client_.get(), - fake_oauth2_token_service_.get(), - account_tracker_.get()); + account_fetcher_->Initialize( + signin_client_.get(), fake_oauth2_token_service_.get(), + account_tracker_.get(), std::make_unique<TestImageDecoder>()); account_fetcher_->EnableNetworkFetchesForTest(); } @@ -460,7 +461,8 @@ tracker.AddObserver(&observer); tracker.Initialize(signin_client()); - fetcher.Initialize(signin_client(), token_service(), &tracker); + fetcher.Initialize(signin_client(), token_service(), &tracker, + std::make_unique<TestImageDecoder>()); fetcher.EnableNetworkFetchesForTest(); ASSERT_FALSE(fetcher.IsAllUserInfoFetched()); ASSERT_TRUE(observer.CheckEvents()); @@ -542,7 +544,8 @@ tracker.Initialize(signin_client()); AccountFetcherService fetcher_service; - fetcher_service.Initialize(signin_client(), token_service(), &tracker); + fetcher_service.Initialize(signin_client(), token_service(), &tracker, + std::make_unique<TestImageDecoder>()); SimulateTokenAvailable("alpha"); IssueAccessToken("alpha"); @@ -629,7 +632,8 @@ CheckAccountDetails("beta", infos[1]); FakeAccountFetcherService fetcher; - fetcher.Initialize(signin_client(), token_service(), &tracker); + fetcher.Initialize(signin_client(), token_service(), &tracker, + std::make_unique<TestImageDecoder>()); fetcher.EnableNetworkFetchesForTest(); // Remove an account. // This will allow testing removal as well as child accounts which is only @@ -727,7 +731,8 @@ AccountTrackerService tracker; tracker.Initialize(signin_client()); AccountFetcherService fetcher; - fetcher.Initialize(signin_client(), token_service(), &tracker); + fetcher.Initialize(signin_client(), token_service(), &tracker, + std::make_unique<TestImageDecoder>()); fetcher.EnableNetworkFetchesForTest(); SimulateTokenAvailable("incomplete"); ReturnOAuthUrlFetchSuccessIncomplete("incomplete"); @@ -739,7 +744,8 @@ AccountTrackerService tracker; tracker.Initialize(signin_client()); AccountFetcherService fetcher; - fetcher.Initialize(signin_client(), token_service(), &tracker); + fetcher.Initialize(signin_client(), token_service(), &tracker, + std::make_unique<TestImageDecoder>()); fetcher.EnableNetworkFetchesForTest(); // Validate that the loaded AccountInfo from prefs is considered invalid. std::vector<AccountInfo> infos = tracker.GetAccounts(); @@ -767,7 +773,8 @@ tracker.AddObserver(&observer); tracker.Initialize(signin_client()); AccountFetcherService fetcher; - fetcher.Initialize(signin_client(), token_service(), &tracker); + fetcher.Initialize(signin_client(), token_service(), &tracker, + std::make_unique<TestImageDecoder>()); ASSERT_TRUE(observer.CheckEvents(TrackingEvent(UPDATED, "incomplete"))); // Enabling network fetches shouldn't cause any actual fetch since the @@ -793,7 +800,8 @@ AccountTrackerService tracker; tracker.Initialize(signin_client()); AccountFetcherService fetcher; - fetcher.Initialize(signin_client(), token_service(), &tracker); + fetcher.Initialize(signin_client(), token_service(), &tracker, + std::make_unique<TestImageDecoder>()); fetcher.EnableNetworkFetchesForTest(); SimulateTokenAvailable("alpha"); ReturnOAuthUrlFetchSuccess("alpha"); @@ -816,7 +824,8 @@ AccountTrackerService tracker; tracker.Initialize(signin_client()); AccountFetcherService fetcher; - fetcher.Initialize(signin_client(), token_service(), &tracker); + fetcher.Initialize(signin_client(), token_service(), &tracker, + std::make_unique<TestImageDecoder>()); ASSERT_TRUE(fetcher.IsAllUserInfoFetched()); std::vector<AccountInfo> infos = tracker.GetAccounts(); @@ -842,7 +851,8 @@ AccountTrackerService tracker; tracker.Initialize(signin_client()); AccountFetcherService fetcher; - fetcher.Initialize(signin_client(), token_service(), &tracker); + fetcher.Initialize(signin_client(), token_service(), &tracker, + std::make_unique<TestImageDecoder>()); ASSERT_TRUE(fetcher.IsAllUserInfoFetched()); std::vector<AccountInfo> infos = tracker.GetAccounts(); @@ -865,7 +875,8 @@ AccountTrackerService tracker; tracker.Initialize(signin_client()); AccountFetcherService fetcher; - fetcher.Initialize(signin_client(), token_service(), &tracker); + fetcher.Initialize(signin_client(), token_service(), &tracker, + std::make_unique<TestImageDecoder>()); fetcher.EnableNetworkFetchesForTest(); SimulateTokenAvailable("foo.bar@gmail.com"); SimulateTokenAvailable("foobar@gmail.com"); @@ -885,7 +896,8 @@ AccountTrackerService tracker; tracker.Initialize(signin_client()); AccountFetcherService fetcher; - fetcher.Initialize(signin_client(), token_service(), &tracker); + fetcher.Initialize(signin_client(), token_service(), &tracker, + std::make_unique<TestImageDecoder>()); ASSERT_TRUE(fetcher.IsAllUserInfoFetched()); std::vector<AccountInfo> infos = tracker.GetAccounts(); @@ -1085,7 +1097,8 @@ AccountTrackerService tracker; tracker.Initialize(signin_client()); FakeAccountFetcherService fetcher; - fetcher.Initialize(signin_client(), token_service(), &tracker); + fetcher.Initialize(signin_client(), token_service(), &tracker, + std::make_unique<TestImageDecoder>()); fetcher.EnableNetworkFetchesForTest(); AccountTrackerObserver observer; tracker.AddObserver(&observer); @@ -1114,7 +1127,8 @@ AccountTrackerService tracker; tracker.Initialize(signin_client()); FakeAccountFetcherService fetcher; - fetcher.Initialize(signin_client(), token_service(), &tracker); + fetcher.Initialize(signin_client(), token_service(), &tracker, + std::make_unique<TestImageDecoder>()); fetcher.EnableNetworkFetchesForTest(); AccountTrackerObserver observer; tracker.AddObserver(&observer); @@ -1143,7 +1157,8 @@ AccountTrackerService tracker; tracker.Initialize(signin_client()); FakeAccountFetcherService fetcher; - fetcher.Initialize(signin_client(), token_service(), &tracker); + fetcher.Initialize(signin_client(), token_service(), &tracker, + std::make_unique<TestImageDecoder>()); fetcher.EnableNetworkFetchesForTest(); AccountTrackerObserver observer; tracker.AddObserver(&observer); @@ -1178,7 +1193,8 @@ AccountTrackerService tracker; tracker.Initialize(signin_client()); FakeAccountFetcherService fetcher; - fetcher.Initialize(signin_client(), token_service(), &tracker); + fetcher.Initialize(signin_client(), token_service(), &tracker, + std::make_unique<TestImageDecoder>()); fetcher.EnableNetworkFetchesForTest(); AccountTrackerObserver observer; tracker.AddObserver(&observer); @@ -1215,7 +1231,8 @@ AccountTrackerService tracker; tracker.Initialize(signin_client()); FakeAccountFetcherService fetcher; - fetcher.Initialize(signin_client(), token_service(), &tracker); + fetcher.Initialize(signin_client(), token_service(), &tracker, + std::make_unique<TestImageDecoder>()); fetcher.EnableNetworkFetchesForTest(); AccountTrackerObserver observer; tracker.AddObserver(&observer);
diff --git a/components/signin/core/browser/fake_account_fetcher_service.cc b/components/signin/core/browser/fake_account_fetcher_service.cc index 21eb31b6..ce60c6f9 100644 --- a/components/signin/core/browser/fake_account_fetcher_service.cc +++ b/components/signin/core/browser/fake_account_fetcher_service.cc
@@ -46,3 +46,14 @@ const std::string& account_id) { // In tests, don't do actual network fetch. } + +TestImageDecoder::TestImageDecoder() = default; + +TestImageDecoder::~TestImageDecoder() = default; + +void TestImageDecoder::DecodeImage( + const std::string& image_data, + const gfx::Size& desired_image_frame_size, + const image_fetcher::ImageDecodedCallback& callback) { + callback.Run(gfx::Image()); +}
diff --git a/components/signin/core/browser/fake_account_fetcher_service.h b/components/signin/core/browser/fake_account_fetcher_service.h index 84d6713..948121c3 100644 --- a/components/signin/core/browser/fake_account_fetcher_service.h +++ b/components/signin/core/browser/fake_account_fetcher_service.h
@@ -8,6 +8,7 @@ #include <memory> #include "base/macros.h" +#include "components/image_fetcher/core/image_decoder.h" #include "components/signin/core/browser/account_fetcher_service.h" class KeyedService; @@ -44,4 +45,23 @@ DISALLOW_COPY_AND_ASSIGN(FakeAccountFetcherService); }; +// This dummy class implements |image_fetcher::ImageDecoder|, and is passed +// as an argument to |AccountFetcherService::Initialize|. +class TestImageDecoder : public image_fetcher::ImageDecoder { + public: + TestImageDecoder(); + ~TestImageDecoder() override; + + // image_fetcher::Decoder implementation: + + // Passes an empty image to callback. + void DecodeImage( + const std::string& image_data, + const gfx::Size& desired_image_frame_size, + const image_fetcher::ImageDecodedCallback& callback) override; + + private: + DISALLOW_COPY_AND_ASSIGN(TestImageDecoder); +}; + #endif // COMPONENTS_SIGNIN_CORE_BROWSER_FAKE_ACCOUNT_FETCHER_SERVICE_H_
diff --git a/components/signin/core/browser/signin_manager_unittest.cc b/components/signin/core/browser/signin_manager_unittest.cc index 90eb20b..c69565a 100644 --- a/components/signin/core/browser/signin_manager_unittest.cc +++ b/components/signin/core/browser/signin_manager_unittest.cc
@@ -97,7 +97,8 @@ SigninManagerBase::RegisterPrefs(local_state_.registry()); account_tracker_.Initialize(&test_signin_client_); account_fetcher_.Initialize(&test_signin_client_, &token_service_, - &account_tracker_); + &account_tracker_, + std::make_unique<TestImageDecoder>()); } ~SigninManagerTest() override {
diff --git a/components/ssl_config/ssl_config_service_manager_pref.cc b/components/ssl_config/ssl_config_service_manager_pref.cc index f924fe26..0d5c299 100644 --- a/components/ssl_config/ssl_config_service_manager_pref.cc +++ b/components/ssl_config/ssl_config_service_manager_pref.cc
@@ -196,27 +196,27 @@ const std::string tls13_variant = base::GetFieldTrialParamValue(kTLS13VariantExperimentName, "variant"); const char* tls13_value = nullptr; - const char* experiment_value = nullptr; + const char* version_value = nullptr; if (tls13_variant == "disabled") { tls13_value = switches::kTLS13VariantDisabled; } else if (tls13_variant == "draft22") { tls13_value = switches::kTLS13VariantDraft22; - experiment_value = switches::kSSLVersionTLSv13; + version_value = switches::kSSLVersionTLSv13; } else if (tls13_variant == "draft23") { tls13_value = switches::kTLS13VariantDraft23; - experiment_value = switches::kSSLVersionTLSv13; + version_value = switches::kSSLVersionTLSv13; } else if (tls13_variant == "experiment2") { tls13_value = switches::kTLS13VariantExperiment2; - experiment_value = switches::kSSLVersionTLSv13; + version_value = switches::kSSLVersionTLSv13; } if (tls13_value) { local_state->SetDefaultPrefValue(ssl_config::prefs::kTLS13Variant, base::Value(tls13_value)); } - if (experiment_value) { + if (version_value) { local_state->SetDefaultPrefValue(ssl_config::prefs::kSSLVersionMax, - base::Value(experiment_value)); + base::Value(version_value)); } PrefChangeRegistrar::NamedChangeCallback local_state_callback =
diff --git a/components/update_client/action_runner.cc b/components/update_client/action_runner.cc index e357a11..be8706c4 100644 --- a/components/update_client/action_runner.cc +++ b/components/update_client/action_runner.cc
@@ -14,6 +14,7 @@ #include "base/location.h" #include "base/logging.h" #include "base/task_scheduler/post_task.h" +#include "build/build_config.h" #include "components/update_client/component.h" #include "components/update_client/configurator.h" #include "components/update_client/task_traits.h"
diff --git a/components/update_client/update_client_unittest.cc b/components/update_client/update_client_unittest.cc index f0a6278..e3e8846 100644 --- a/components/update_client/update_client_unittest.cc +++ b/components/update_client/update_client_unittest.cc
@@ -21,6 +21,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "base/values.h" #include "base/version.h" +#include "build/build_config.h" #include "components/prefs/testing_pref_service.h" #include "components/update_client/component_unpacker.h" #include "components/update_client/crx_update_item.h"
diff --git a/components/viz/common/BUILD.gn b/components/viz/common/BUILD.gn index b1f1c51..51b18d6 100644 --- a/components/viz/common/BUILD.gn +++ b/components/viz/common/BUILD.gn
@@ -126,18 +126,9 @@ "surfaces/local_surface_id.h", "surfaces/parent_local_surface_id_allocator.cc", "surfaces/parent_local_surface_id_allocator.h", - "surfaces/sequence_surface_reference_factory.cc", - "surfaces/sequence_surface_reference_factory.h", - "surfaces/stub_surface_reference_factory.cc", - "surfaces/stub_surface_reference_factory.h", "surfaces/surface_id.cc", "surfaces/surface_id.h", "surfaces/surface_info.h", - "surfaces/surface_reference_factory.h", - "surfaces/surface_reference_owner.h", - "surfaces/surface_sequence.h", - "surfaces/surface_sequence_generator.cc", - "surfaces/surface_sequence_generator.h", "switches.cc", "switches.h", "traced_value.cc", @@ -194,7 +185,6 @@ "quads/draw_quad_unittest.cc", "quads/render_pass_unittest.cc", "resources/platform_color_unittest.cc", - "surfaces/surface_sequence_generator_unittest.cc", "yuv_readback_unittest.cc", ]
diff --git a/components/viz/common/DEPS b/components/viz/common/DEPS index 04cd092..10c073f 100644 --- a/components/viz/common/DEPS +++ b/components/viz/common/DEPS
@@ -14,6 +14,7 @@ "+components/viz/test", "+gpu/ipc/gl_in_process_context.h", "+media/base", + "+third_party/skia/include/core", "+ui/gl", ], ".*_benchmark\.cc": [
diff --git a/components/viz/common/gpu/context_cache_controller.cc b/components/viz/common/gpu/context_cache_controller.cc index d49abb7..572955cd 100644 --- a/components/viz/common/gpu/context_cache_controller.cc +++ b/components/viz/common/gpu/context_cache_controller.cc
@@ -159,8 +159,11 @@ return; } - if (gr_context_) - gr_context_->freeGpuResources(); + if (gr_context_) { + // Avoid the more complete GrContext::freeGpuResources, as that evicts + // harder to re-generate Skia caches. + gr_context_->performDeferredCleanup(std::chrono::milliseconds(0)); + } // Toggle SetAggressivelyFreeResources to drop command buffer data. context_support_->SetAggressivelyFreeResources(true);
diff --git a/components/viz/common/gpu/context_cache_controller_unittest.cc b/components/viz/common/gpu/context_cache_controller_unittest.cc index d6eb828e..f91475b 100644 --- a/components/viz/common/gpu/context_cache_controller_unittest.cc +++ b/components/viz/common/gpu/context_cache_controller_unittest.cc
@@ -11,6 +11,9 @@ #include "cc/test/test_web_graphics_context_3d.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/skia/include/core/SkImage.h" +#include "third_party/skia/include/core/SkPixmap.h" +#include "third_party/skia/include/gpu/GrContext.h" using ::testing::Mock; using ::testing::StrictMock; @@ -112,5 +115,51 @@ cache_controller.ClientBecameNotVisible(std::move(visible)); } +// Confirms that the Skia performDeferredCleanup API used by the cache +// controller behaves as expected. +TEST(ContextCacheControllerTest, CheckSkiaResourcePurgeAPI) { + StrictMock<MockContextSupport> context_support; + auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>(); + ContextCacheController cache_controller(&context_support, task_runner); + auto context_provider = cc::TestContextProvider::Create(); + context_provider->BindToCurrentThread(); + auto* gr_context = context_provider->GrContext(); + cache_controller.SetGrContext(gr_context); + + // Make us visible. + EXPECT_CALL(context_support, SetAggressivelyFreeResources(false)); + auto visibility = cache_controller.ClientBecameVisible(); + Mock::VerifyAndClearExpectations(&context_support); + + // Now that we're visible, become busy, create and release a skia resource. + auto busy = cache_controller.ClientBecameBusy(); + { + auto image_info = SkImageInfo::MakeN32Premul(200, 200); + std::vector<uint8_t> image_data(image_info.computeMinByteSize()); + SkPixmap pixmap(image_info, image_data.data(), image_info.minRowBytes()); + auto image = SkImage::MakeRasterCopy(pixmap); + auto image_gpu = image->makeTextureImage(gr_context, nullptr); + gr_context->flush(); + } + + // Ensure we see size taken up for the image (now released, but cached for + // re-use). + EXPECT_GT(gr_context->getResourceCachePurgeableBytes(), 0u); + + // Make the client idle and wait for the idle callback to trigger. + cache_controller.ClientBecameNotBusy(std::move(busy)); + EXPECT_CALL(context_support, SetAggressivelyFreeResources(true)); + EXPECT_CALL(context_support, SetAggressivelyFreeResources(false)); + task_runner->FastForwardBy(base::TimeDelta::FromSeconds(5)); + Mock::VerifyAndClearExpectations(&context_support); + + // The Skia resource cache should now be empty. + EXPECT_EQ(gr_context->getResourceCachePurgeableBytes(), 0u); + + // Set not-visible. + EXPECT_CALL(context_support, SetAggressivelyFreeResources(true)); + cache_controller.ClientBecameNotVisible(std::move(visibility)); +} + } // namespace } // namespace viz
diff --git a/components/viz/common/surfaces/sequence_surface_reference_factory.cc b/components/viz/common/surfaces/sequence_surface_reference_factory.cc deleted file mode 100644 index 7faf30e..0000000 --- a/components/viz/common/surfaces/sequence_surface_reference_factory.cc +++ /dev/null
@@ -1,23 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/viz/common/surfaces/sequence_surface_reference_factory.h" - -#include "base/bind.h" -#include "base/memory/ptr_util.h" - -#include "components/viz/common/surfaces/surface_sequence.h" - -namespace viz { - -base::Closure SequenceSurfaceReferenceFactory::CreateReference( - SurfaceReferenceOwner* owner, - const SurfaceId& surface_id) const { - auto seq = owner->GetSurfaceSequenceGenerator()->CreateSurfaceSequence(); - RequireSequence(surface_id, seq); - return base::Bind(&SequenceSurfaceReferenceFactory::SatisfySequence, this, - seq); -} - -} // namespace viz
diff --git a/components/viz/common/surfaces/sequence_surface_reference_factory.h b/components/viz/common/surfaces/sequence_surface_reference_factory.h deleted file mode 100644 index c3cbde9..0000000 --- a/components/viz/common/surfaces/sequence_surface_reference_factory.h +++ /dev/null
@@ -1,37 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_VIZ_COMMON_SURFACES_SEQUENCE_SURFACE_REFERENCE_FACTORY_H_ -#define COMPONENTS_VIZ_COMMON_SURFACES_SEQUENCE_SURFACE_REFERENCE_FACTORY_H_ - -#include "components/viz/common/surfaces/surface_reference_factory.h" -#include "components/viz/common/surfaces/surface_sequence.h" -#include "components/viz/common/viz_common_export.h" - -namespace viz { - -// A surface reference factory that uses SurfaceSequence. -class VIZ_COMMON_EXPORT SequenceSurfaceReferenceFactory - : public SurfaceReferenceFactory { - public: - SequenceSurfaceReferenceFactory() = default; - - // SurfaceReferenceFactory implementation: - base::Closure CreateReference(SurfaceReferenceOwner* owner, - const SurfaceId& surface_id) const override; - - protected: - ~SequenceSurfaceReferenceFactory() override = default; - - private: - virtual void RequireSequence(const SurfaceId& surface_id, - const SurfaceSequence& sequence) const = 0; - virtual void SatisfySequence(const SurfaceSequence& sequence) const = 0; - - DISALLOW_COPY_AND_ASSIGN(SequenceSurfaceReferenceFactory); -}; - -} // namespace viz - -#endif // COMPONENTS_VIZ_COMMON_SURFACES_SEQUENCE_SURFACE_REFERENCE_FACTORY_H_
diff --git a/components/viz/common/surfaces/stub_surface_reference_factory.cc b/components/viz/common/surfaces/stub_surface_reference_factory.cc deleted file mode 100644 index e5d2ce50..0000000 --- a/components/viz/common/surfaces/stub_surface_reference_factory.cc +++ /dev/null
@@ -1,17 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/viz/common/surfaces/stub_surface_reference_factory.h" - -#include "base/callback.h" - -namespace viz { - -base::Closure StubSurfaceReferenceFactory::CreateReference( - SurfaceReferenceOwner* owner, - const SurfaceId& surface_id) const { - return base::Closure(); -} - -} // namespace viz
diff --git a/components/viz/common/surfaces/stub_surface_reference_factory.h b/components/viz/common/surfaces/stub_surface_reference_factory.h deleted file mode 100644 index 156809c..0000000 --- a/components/viz/common/surfaces/stub_surface_reference_factory.h +++ /dev/null
@@ -1,34 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_VIZ_COMMON_SURFACES_STUB_SURFACE_REFERENCE_FACTORY_H_ -#define COMPONENTS_VIZ_COMMON_SURFACES_STUB_SURFACE_REFERENCE_FACTORY_H_ - -#include "base/compiler_specific.h" -#include "components/viz/common/surfaces/surface_reference_factory.h" -#include "components/viz/common/viz_common_export.h" - -namespace viz { - -// A stub implementation that creates a closure which does nothing. -// TODO(kylechar): Delete this class and all usage of -// SurfaceReferenceFactory when surface references are enabled by default. -class VIZ_COMMON_EXPORT StubSurfaceReferenceFactory - : public SurfaceReferenceFactory { - public: - StubSurfaceReferenceFactory() = default; - - // SurfaceReferenceFactory: - base::Closure CreateReference(SurfaceReferenceOwner* owner, - const SurfaceId& surface_id) const override; - - protected: - ~StubSurfaceReferenceFactory() override = default; - - DISALLOW_COPY_AND_ASSIGN(StubSurfaceReferenceFactory); -}; - -} // namespace viz - -#endif // COMPONENTS_VIZ_COMMON_SURFACES_STUB_SURFACE_REFERENCE_FACTORY_H_
diff --git a/components/viz/common/surfaces/surface_reference_factory.h b/components/viz/common/surfaces/surface_reference_factory.h deleted file mode 100644 index 03e5808..0000000 --- a/components/viz/common/surfaces/surface_reference_factory.h +++ /dev/null
@@ -1,39 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_VIZ_COMMON_SURFACES_SURFACE_REFERENCE_FACTORY_H_ -#define COMPONENTS_VIZ_COMMON_SURFACES_SURFACE_REFERENCE_FACTORY_H_ - -#include "base/callback_forward.h" -#include "base/memory/ref_counted.h" -#include "components/viz/common/surfaces/surface_id.h" -#include "components/viz/common/surfaces/surface_reference_owner.h" - -namespace viz { - -// Confusingly, SurfaceReferenceFactory is only used to create SurfaceSequences. -// TODO(kylechar): Delete all usage of SurfaceReferenceFactory when surface -// references are enabled by default. -class SurfaceReferenceFactory - : public base::RefCountedThreadSafe<SurfaceReferenceFactory> { - public: - // Creates a reference to the surface with the given surface id and returns - // a closure that must be called exactly once to remove the reference. - virtual base::Closure CreateReference(SurfaceReferenceOwner* owner, - const SurfaceId& surface_id) const = 0; - - SurfaceReferenceFactory() = default; - - protected: - virtual ~SurfaceReferenceFactory() = default; - - private: - friend class base::RefCountedThreadSafe<SurfaceReferenceFactory>; - - DISALLOW_COPY_AND_ASSIGN(SurfaceReferenceFactory); -}; - -} // namespace viz - -#endif // COMPONENTS_VIZ_COMMON_SURFACES_SURFACE_REFERENCE_FACTORY_H_
diff --git a/components/viz/common/surfaces/surface_reference_owner.h b/components/viz/common/surfaces/surface_reference_owner.h deleted file mode 100644 index c966fb9..0000000 --- a/components/viz/common/surfaces/surface_reference_owner.h +++ /dev/null
@@ -1,23 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_VIZ_COMMON_SURFACES_SURFACE_REFERENCE_OWNER_H_ -#define COMPONENTS_VIZ_COMMON_SURFACES_SURFACE_REFERENCE_OWNER_H_ - -#include "components/viz/common/surfaces/surface_sequence_generator.h" - -namespace viz { - -// Implementations of this interface can be passed to -// SurfaceReferenceFactory::CreateReference as the reference owner. -class SurfaceReferenceOwner { - public: - virtual ~SurfaceReferenceOwner() {} - - virtual SurfaceSequenceGenerator* GetSurfaceSequenceGenerator() = 0; -}; - -} // namespace viz - -#endif // COMPONENTS_VIZ_COMMON_SURFACES_SURFACE_REFERENCE_OWNER_H_
diff --git a/components/viz/common/surfaces/surface_sequence.h b/components/viz/common/surfaces/surface_sequence.h deleted file mode 100644 index 1b5bda9..0000000 --- a/components/viz/common/surfaces/surface_sequence.h +++ /dev/null
@@ -1,53 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_VIZ_COMMON_SURFACES_SURFACE_SEQUENCE_H_ -#define COMPONENTS_VIZ_COMMON_SURFACES_SURFACE_SEQUENCE_H_ - -#include <stddef.h> -#include <stdint.h> - -#include <tuple> - -#include "base/hash.h" -#include "components/viz/common/surfaces/frame_sink_id.h" - -namespace viz { - -// A per-surface-namespace sequence number that's used to coordinate -// dependencies between frames. A sequence number may be satisfied once, and -// may be depended on once. -struct SurfaceSequence { - SurfaceSequence() : sequence(0u) {} - SurfaceSequence(const FrameSinkId& frame_sink_id, uint32_t sequence) - : frame_sink_id(frame_sink_id), sequence(sequence) {} - bool is_valid() const { return frame_sink_id.is_valid() && sequence > 0u; } - - FrameSinkId frame_sink_id; - uint32_t sequence; -}; - -inline bool operator==(const SurfaceSequence& a, const SurfaceSequence& b) { - return a.frame_sink_id == b.frame_sink_id && a.sequence == b.sequence; -} - -inline bool operator!=(const SurfaceSequence& a, const SurfaceSequence& b) { - return !(a == b); -} - -inline bool operator<(const SurfaceSequence& a, const SurfaceSequence& b) { - return std::tie(a.frame_sink_id, a.sequence) < - std::tie(b.frame_sink_id, b.sequence); -} - -struct SurfaceSequenceHash { - size_t operator()(SurfaceSequence key) const { - return base::HashInts(static_cast<uint64_t>(key.frame_sink_id.hash()), - key.sequence); - } -}; - -} // namespace viz - -#endif // COMPONENTS_VIZ_COMMON_SURFACES_SURFACE_SEQUENCE_H_
diff --git a/components/viz/common/surfaces/surface_sequence_generator.cc b/components/viz/common/surfaces/surface_sequence_generator.cc deleted file mode 100644 index f3c351e..0000000 --- a/components/viz/common/surfaces/surface_sequence_generator.cc +++ /dev/null
@@ -1,19 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/viz/common/surfaces/surface_sequence_generator.h" -#include "components/viz/common/surfaces/surface_sequence.h" - -namespace viz { - -SurfaceSequenceGenerator::SurfaceSequenceGenerator() - : next_surface_sequence_(1u) {} - -SurfaceSequenceGenerator::~SurfaceSequenceGenerator() = default; - -SurfaceSequence SurfaceSequenceGenerator::CreateSurfaceSequence() { - return SurfaceSequence(frame_sink_id_, next_surface_sequence_++); -} - -} // namespace viz
diff --git a/components/viz/common/surfaces/surface_sequence_generator.h b/components/viz/common/surfaces/surface_sequence_generator.h deleted file mode 100644 index 1bed7d5..0000000 --- a/components/viz/common/surfaces/surface_sequence_generator.h +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_VIZ_COMMON_SURFACES_SURFACE_SEQUENCE_GENERATOR_H_ -#define COMPONENTS_VIZ_COMMON_SURFACES_SURFACE_SEQUENCE_GENERATOR_H_ - -#include <stdint.h> - -#include <tuple> - -#include "base/macros.h" - -#include "components/viz/common/surfaces/frame_sink_id.h" -#include "components/viz/common/surfaces/surface_sequence.h" -#include "components/viz/common/viz_common_export.h" - -namespace viz { - -// Generates unique surface sequences for a surface client id. -class VIZ_COMMON_EXPORT SurfaceSequenceGenerator { - public: - SurfaceSequenceGenerator(); - ~SurfaceSequenceGenerator(); - - void set_frame_sink_id(const FrameSinkId& frame_sink_id) { - frame_sink_id_ = frame_sink_id; - } - - SurfaceSequence CreateSurfaceSequence(); - - private: - FrameSinkId frame_sink_id_; - uint32_t next_surface_sequence_; - - DISALLOW_COPY_AND_ASSIGN(SurfaceSequenceGenerator); -}; - -} // namespace viz - -#endif // COMPONENTS_VIZ_COMMON_SURFACES_SURFACE_SEQUENCE_GENERATOR_H_
diff --git a/components/viz/common/surfaces/surface_sequence_generator_unittest.cc b/components/viz/common/surfaces/surface_sequence_generator_unittest.cc deleted file mode 100644 index 5d1913cc..0000000 --- a/components/viz/common/surfaces/surface_sequence_generator_unittest.cc +++ /dev/null
@@ -1,24 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/viz/common/surfaces/surface_sequence_generator.h" - -#include "components/viz/common/surfaces/surface_sequence.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace viz { -namespace { - -static constexpr FrameSinkId kArbitraryFrameSinkId(1, 1); - -TEST(SurfaceSequenceGeneratorTest, Basic) { - SurfaceSequenceGenerator generator; - generator.set_frame_sink_id(kArbitraryFrameSinkId); - SurfaceSequence sequence1 = generator.CreateSurfaceSequence(); - SurfaceSequence sequence2 = generator.CreateSurfaceSequence(); - EXPECT_NE(sequence1, sequence2); -} - -} // namespace -} // namespace viz
diff --git a/components/viz/common/switches.cc b/components/viz/common/switches.cc index 8eaf1ca6..5f911d8 100644 --- a/components/viz/common/switches.cc +++ b/components/viz/common/switches.cc
@@ -19,12 +19,6 @@ const char kDeadlineToSynchronizeSurfaces[] = "deadline-to-synchronize-surfaces"; -// Disable surface lifetime management using surface references. This enables -// adding surface sequences and disables adding temporary references. This flag -// is only checked on Android, other platforms always have surface references -// enabled. -const char kDisableSurfaceReferences[] = "disable-surface-references"; - // Enables multi-client Surface synchronization. In practice, this indicates // that LayerTreeHost expects to be given a valid viz::LocalSurfaceId provided // by the parent compositor.
diff --git a/components/viz/common/switches.h b/components/viz/common/switches.h index 6752c34..508d753 100644 --- a/components/viz/common/switches.h +++ b/components/viz/common/switches.h
@@ -14,7 +14,6 @@ // Keep list in alphabetical order. VIZ_COMMON_EXPORT extern const char kDeadlineToSynchronizeSurfaces[]; -VIZ_COMMON_EXPORT extern const char kDisableSurfaceReferences[]; VIZ_COMMON_EXPORT extern const char kEnableSurfaceSynchronization[]; VIZ_COMMON_EXPORT uint32_t GetDeadlineToSynchronizeSurfaces();
diff --git a/components/viz/host/host_frame_sink_manager.cc b/components/viz/host/host_frame_sink_manager.cc index 1719ae8d..6df9d7f 100644 --- a/components/viz/host/host_frame_sink_manager.cc +++ b/components/viz/host/host_frame_sink_manager.cc
@@ -26,10 +26,6 @@ frame_sink_manager_impl_ = frame_sink_manager_impl; frame_sink_manager_ = frame_sink_manager_impl; - - // Assign temporary references if FrameSinkManagerImpl is using them. - assign_temporary_references_ = - frame_sink_manager_impl_->surface_manager()->using_surface_references(); } void HostFrameSinkManager::BindAndSetManager(
diff --git a/components/viz/service/BUILD.gn b/components/viz/service/BUILD.gn index a2c5598..dc49222 100644 --- a/components/viz/service/BUILD.gn +++ b/components/viz/service/BUILD.gn
@@ -137,8 +137,6 @@ "hit_test/hit_test_aggregator_delegate.h", "hit_test/hit_test_manager.cc", "hit_test/hit_test_manager.h", - "surfaces/direct_surface_reference_factory.cc", - "surfaces/direct_surface_reference_factory.h", "surfaces/surface.cc", "surfaces/surface.h", "surfaces/surface_client.h",
diff --git a/components/viz/service/display/display_scheduler_unittest.cc b/components/viz/service/display/display_scheduler_unittest.cc index 7211752..335f33a 100644 --- a/components/viz/service/display/display_scheduler_unittest.cc +++ b/components/viz/service/display/display_scheduler_unittest.cc
@@ -123,7 +123,7 @@ explicit DisplaySchedulerTest(bool wait_for_all_surfaces_before_draw = false) : fake_begin_frame_source_(0.f, false), task_runner_(new base::NullTaskRunner), - surface_manager_(SurfaceManager::LifetimeType::REFERENCES, 4u), + surface_manager_(4u), scheduler_(&fake_begin_frame_source_, &surface_manager_, task_runner_.get(),
diff --git a/components/viz/service/display/skia_renderer.cc b/components/viz/service/display/skia_renderer.cc index 4f94a0e35..8aa3917 100644 --- a/components/viz/service/display/skia_renderer.cc +++ b/components/viz/service/display/skia_renderer.cc
@@ -72,12 +72,6 @@ #if BUILDFLAG(ENABLE_VULKAN) return; #endif - gpu::gles2::GLES2Interface* gl = - output_surface_->context_provider()->ContextGL(); - for (auto& pair : render_pass_backings_) { - RenderPassBacking& backing = pair.second; - gl->DeleteTextures(1, &backing.gl_id); - } } bool SkiaRenderer::CanPartialSwap() { @@ -250,22 +244,12 @@ return; #endif - RenderPassBacking& backing = render_pass_backings_[render_pass_id]; - DCHECK(backing.gl_id); - - GrGLTextureInfo texture_info; - texture_info.fID = backing.gl_id; - texture_info.fTarget = GL_TEXTURE_2D; - GrBackendTexture backend_texture(backing.size.width(), backing.size.height(), - ToGrPixelConfig(backing.format), - texture_info); - constexpr uint32_t flags = 0; - // LegacyFontHost will get LCD text and skia figures out what type to use. - SkSurfaceProps surface_props(flags, SkSurfaceProps::kLegacyFontHost_InitType); - int msaa_sample_count = 0; - non_root_surface_ = SkSurface::MakeFromBackendTextureAsRenderTarget( - output_surface_->context_provider()->GrContext(), backend_texture, - kTopLeft_GrSurfaceOrigin, msaa_sample_count, nullptr, &surface_props); + auto iter = render_pass_backings_.find(render_pass_id); + DCHECK(render_pass_backings_.end() != iter); + // This function is called after AllocateRenderPassResourceIfNeeded, so there + // should be backing ready. + RenderPassBacking& backing = iter->second; + non_root_surface_ = backing.render_pass_surface; current_canvas_ = non_root_surface_->getCanvas(); } @@ -593,19 +577,14 @@ NOTIMPLEMENTED(); return; #endif - RenderPassBacking& content_texture = - render_pass_backings_[quad->render_pass_id]; - DCHECK(content_texture.gl_id); + auto iter = render_pass_backings_.find(quad->render_pass_id); + DCHECK(render_pass_backings_.end() != iter); + // This function is called after AllocateRenderPassResourceIfNeeded, so there + // should be backing ready. + RenderPassBacking& content_texture = iter->second; - GrGLTextureInfo texture_info; - texture_info.fID = content_texture.gl_id; - texture_info.fTarget = GL_TEXTURE_2D; - GrBackendTexture backend_texture( - content_texture.size.width(), content_texture.size.height(), - ToGrPixelConfig(content_texture.format), texture_info); - sk_sp<SkImage> content = SkImage::MakeFromTexture( - output_surface_->context_provider()->GrContext(), backend_texture, - kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType, nullptr); + sk_sp<SkImage> content = + content_texture.render_pass_surface->makeImageSnapshot(); SkRect dest_rect = gfx::RectFToSkRect(QuadVertexRect()); SkRect dest_visible_rect = @@ -770,15 +749,10 @@ passes_to_delete.push_back(pair.first); } - gpu::gles2::GLES2Interface* gl = - output_surface_->context_provider()->ContextGL(); - // Delete RenderPass backings from the previous frame that will not be used // again. for (size_t i = 0; i < passes_to_delete.size(); ++i) { auto it = render_pass_backings_.find(passes_to_delete[i]); - RenderPassBacking& backing = it->second; - gl->DeleteTextures(1, &backing.gl_id); render_pass_backings_.erase(it); } } @@ -795,65 +769,62 @@ return; ContextProvider* context_provider = output_surface_->context_provider(); - gpu::gles2::GLES2Interface* gl = context_provider->ContextGL(); - const gpu::Capabilities& caps = context_provider->ContextCapabilities(); + bool capability_bgra8888 = + context_provider->ContextCapabilities().texture_format_bgra8888; + render_pass_backings_.insert(std::pair<RenderPassId, RenderPassBacking>( + render_pass_id, + RenderPassBacking(context_provider->GrContext(), requirements.size, + requirements.mipmap, capability_bgra8888, + current_frame()->current_render_pass->color_space))); +} - uint32_t texture_id; - gl->GenTextures(1, &texture_id); - gl->BindTexture(GL_TEXTURE_2D, texture_id); - - gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - // This texture will be bound as a framebuffer, so optimize for that. - if (caps.texture_usage) { - gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_USAGE_ANGLE, - GL_FRAMEBUFFER_ATTACHMENT_ANGLE); - } - - ResourceFormat backbuffer_format; - if (current_frame()->current_render_pass->color_space.IsHDR()) { +SkiaRenderer::RenderPassBacking::RenderPassBacking( + GrContext* gr_context, + const gfx::Size& size, + bool mipmap, + bool capability_bgra8888, + const gfx::ColorSpace& color_space) + : size(size), mipmap(mipmap), color_space(color_space) { + ResourceFormat format; + if (color_space.IsHDR()) { // If a platform does not support half-float renderbuffers then it should // not should request HDR rendering. - DCHECK(caps.texture_half_float_linear); - DCHECK(caps.color_buffer_half_float_rgba); - backbuffer_format = RGBA_F16; + // DCHECK(caps.texture_half_float_linear); + // DCHECK(caps.color_buffer_half_float_rgba); + format = RGBA_F16; } else { - backbuffer_format = - PlatformColor::BestSupportedTextureFormat(caps.texture_format_bgra8888); + format = PlatformColor::BestSupportedTextureFormat(capability_bgra8888); } + SkColorType color_type = ResourceFormatToClosestSkColorType(format); - // If |texture_storage| is available, then we can use TexStorage2DEXT to make - // an immutable texture backing, which allows for optimized usage. Otherwise - // we must use the traditional TexImage2D to generate the texture backing. - if (caps.texture_storage) { - GLint levels = 1; - // If |texture_npot| is availble, and mipmaps are desired, we generate a - // mipmap for each power of 2 size. This is only done when using - // TexStorage2DEXT. - if (caps.texture_npot && requirements.mipmap) { - levels += base::bits::Log2Floor( - std::max(requirements.size.width(), requirements.size.height())); - } - gl->TexStorage2DEXT(GL_TEXTURE_2D, levels, - TextureStorageFormat(backbuffer_format), - requirements.size.width(), requirements.size.height()); - } else { - gl->TexImage2D(GL_TEXTURE_2D, 0, GLInternalFormat(backbuffer_format), - requirements.size.width(), requirements.size.height(), 0, - GLDataFormat(backbuffer_format), - GLDataType(backbuffer_format), nullptr); - } + constexpr uint32_t flags = 0; + // LegacyFontHost will get LCD text and skia figures out what type to use. + SkSurfaceProps surface_props(flags, SkSurfaceProps::kLegacyFontHost_InitType); + int msaa_sample_count = 0; + SkImageInfo image_info = SkImageInfo::Make( + size.width(), size.height(), color_type, kPremul_SkAlphaType, nullptr); + render_pass_surface = SkSurface::MakeRenderTarget( + gr_context, SkBudgeted::kNo, image_info, msaa_sample_count, + kTopLeft_GrSurfaceOrigin, &surface_props, mipmap); +} - RenderPassBacking& backing = render_pass_backings_[render_pass_id]; - backing.gl_id = texture_id; - backing.size = requirements.size; - backing.mipmap = requirements.mipmap; - backing.format = backbuffer_format; - backing.color_space = current_frame()->current_render_pass->color_space; - gl->BindTexture(GL_TEXTURE_2D, 0); +SkiaRenderer::RenderPassBacking::~RenderPassBacking() {} + +SkiaRenderer::RenderPassBacking::RenderPassBacking( + SkiaRenderer::RenderPassBacking&& other) + : size(other.size), mipmap(other.mipmap), color_space(other.color_space) { + render_pass_surface = other.render_pass_surface; + other.render_pass_surface = nullptr; +} + +SkiaRenderer::RenderPassBacking& SkiaRenderer::RenderPassBacking::operator=( + SkiaRenderer::RenderPassBacking&& other) { + size = other.size; + mipmap = other.mipmap; + color_space = other.color_space; + render_pass_surface = other.render_pass_surface; + other.render_pass_surface = nullptr; + return *this; } bool SkiaRenderer::IsRenderPassResourceAllocated(
diff --git a/components/viz/service/display/skia_renderer.h b/components/viz/service/display/skia_renderer.h index 18358d4..32aa19d 100644 --- a/components/viz/service/display/skia_renderer.h +++ b/components/viz/service/display/skia_renderer.h
@@ -101,11 +101,18 @@ // A map from RenderPass id to the texture used to draw the RenderPass from. struct RenderPassBacking { - uint32_t gl_id; + sk_sp<SkSurface> render_pass_surface; gfx::Size size; bool mipmap; - ResourceFormat format; gfx::ColorSpace color_space; + RenderPassBacking(GrContext* gr_context, + const gfx::Size& size, + bool mipmap, + bool capability_bgra8888, + const gfx::ColorSpace& color_space); + ~RenderPassBacking(); + RenderPassBacking(RenderPassBacking&&); + RenderPassBacking& operator=(RenderPassBacking&&); }; base::flat_map<RenderPassId, RenderPassBacking> render_pass_backings_;
diff --git a/components/viz/service/frame_sinks/frame_sink_manager_impl.cc b/components/viz/service/frame_sinks/frame_sink_manager_impl.cc index 8617ed49..5c67eb7 100644 --- a/components/viz/service/frame_sinks/frame_sink_manager_impl.cc +++ b/components/viz/service/frame_sinks/frame_sink_manager_impl.cc
@@ -24,35 +24,21 @@ namespace viz { -FrameSinkManagerImpl::FrameSinkSourceMapping::FrameSinkSourceMapping() = +FrameSinkManagerImpl::FrameSinkData::FrameSinkData() = default; + +FrameSinkManagerImpl::FrameSinkData::FrameSinkData(FrameSinkData&& other) = default; -FrameSinkManagerImpl::FrameSinkSourceMapping::FrameSinkSourceMapping( - FrameSinkSourceMapping&& other) = default; +FrameSinkManagerImpl::FrameSinkData::~FrameSinkData() = default; -FrameSinkManagerImpl::FrameSinkSourceMapping::~FrameSinkSourceMapping() = - default; - -FrameSinkManagerImpl::FrameSinkSourceMapping& -FrameSinkManagerImpl::FrameSinkSourceMapping::operator=( - FrameSinkSourceMapping&& other) = default; - -FrameSinkManagerImpl::SinkAndSupport::SinkAndSupport() = default; - -FrameSinkManagerImpl::SinkAndSupport::SinkAndSupport(SinkAndSupport&& other) = - default; - -FrameSinkManagerImpl::SinkAndSupport::~SinkAndSupport() = default; - -FrameSinkManagerImpl::SinkAndSupport& FrameSinkManagerImpl::SinkAndSupport:: -operator=(SinkAndSupport&& other) = default; +FrameSinkManagerImpl::FrameSinkData& FrameSinkManagerImpl::FrameSinkData:: +operator=(FrameSinkData&& other) = default; FrameSinkManagerImpl::FrameSinkManagerImpl( - SurfaceManager::LifetimeType lifetime_type, uint32_t number_of_frames_to_activation_deadline, DisplayProvider* display_provider) : display_provider_(display_provider), - surface_manager_(lifetime_type, number_of_frames_to_activation_deadline), + surface_manager_(number_of_frames_to_activation_deadline), hit_test_manager_(this), binding_(this) { surface_manager_.AddObserver(&hit_test_manager_); @@ -61,11 +47,13 @@ FrameSinkManagerImpl::~FrameSinkManagerImpl() { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + + // All CompositorFrameSinkSupports and BeginFrameSources should be deleted + // before FrameSinkManagerImpl destruction. + DCHECK(support_map_.empty()); + DCHECK(registered_sources_.empty()); + video_capturers_.clear(); - // All FrameSinks should be unregistered prior to FrameSinkManager - // destruction. - compositor_frame_sinks_.clear(); - DCHECK_EQ(registered_sources_.size(), 0u); surface_manager_.RemoveObserver(this); surface_manager_.RemoveObserver(&hit_test_manager_); } @@ -105,11 +93,13 @@ video_detector_->OnFrameSinkIdInvalidated(frame_sink_id); // Destroy the [Root]CompositorFrameSinkImpl if there is one. This will result - // in UnregisterCompositorFrameSinkSupport() being called and |iter| will be - // invalidated afterwards - auto iter = compositor_frame_sinks_.find(frame_sink_id); - if (iter != compositor_frame_sinks_.end()) + // in UnregisterCompositorFrameSinkSupport() being called. + auto iter = frame_sink_data_map_.find(frame_sink_id); + if (iter != frame_sink_data_map_.end()) { iter->second.sink.reset(); + if (iter->second.empty()) + frame_sink_data_map_.erase(iter); + } } void FrameSinkManagerImpl::SetFrameSinkDebugLabel( @@ -121,7 +111,7 @@ void FrameSinkManagerImpl::CreateRootCompositorFrameSink( mojom::RootCompositorFrameSinkParamsPtr params) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - DCHECK_EQ(0u, compositor_frame_sinks_.count(params->frame_sink_id)); + DCHECK(!frame_sink_data_map_[params->frame_sink_id].sink); DCHECK(display_provider_); std::unique_ptr<ExternalBeginFrameControllerImpl> @@ -141,17 +131,16 @@ external_begin_frame_controller.get(), params->renderer_settings, &begin_frame_source); - auto frame_sink = std::make_unique<RootCompositorFrameSinkImpl>( - this, params->frame_sink_id, std::move(display), - std::move(begin_frame_source), std::move(external_begin_frame_controller), - std::move(params->compositor_frame_sink), - mojom::CompositorFrameSinkClientPtr( - std::move(params->compositor_frame_sink_client)), - std::move(params->display_private), - mojom::DisplayClientPtr(std::move(params->display_client))); - SinkAndSupport& entry = compositor_frame_sinks_[params->frame_sink_id]; - DCHECK(entry.support); // |entry| was created by RootCompositorFrameSinkImpl. - entry.sink = std::move(frame_sink); + frame_sink_data_map_[params->frame_sink_id].sink = + std::make_unique<RootCompositorFrameSinkImpl>( + this, params->frame_sink_id, std::move(display), + std::move(begin_frame_source), + std::move(external_begin_frame_controller), + std::move(params->compositor_frame_sink), + mojom::CompositorFrameSinkClientPtr( + std::move(params->compositor_frame_sink_client)), + std::move(params->display_private), + mojom::DisplayClientPtr(std::move(params->display_client))); } void FrameSinkManagerImpl::CreateCompositorFrameSink( @@ -159,13 +148,11 @@ mojom::CompositorFrameSinkRequest request, mojom::CompositorFrameSinkClientPtr client) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - DCHECK_EQ(0u, compositor_frame_sinks_.count(frame_sink_id)); + DCHECK(!frame_sink_data_map_[frame_sink_id].sink); - auto frame_sink = std::make_unique<CompositorFrameSinkImpl>( - this, frame_sink_id, std::move(request), std::move(client)); - SinkAndSupport& entry = compositor_frame_sinks_[frame_sink_id]; - DCHECK(entry.support); // |entry| was created by CompositorFrameSinkImpl. - entry.sink = std::move(frame_sink); + frame_sink_data_map_[frame_sink_id].sink = + std::make_unique<CompositorFrameSinkImpl>( + this, frame_sink_id, std::move(request), std::move(client)); } void FrameSinkManagerImpl::RegisterFrameSinkHierarchy( @@ -175,14 +162,14 @@ // then this will create an infinite loop. Might as well just crash here. CHECK(!ChildContains(child_frame_sink_id, parent_frame_sink_id)); - auto& children = frame_sink_source_map_[parent_frame_sink_id].children; + auto& children = frame_sink_data_map_[parent_frame_sink_id].children; DCHECK(!base::ContainsKey(children, child_frame_sink_id)); children.insert(child_frame_sink_id); // If the parent has no source, then attaching it to this child will // not change any downstream sources. BeginFrameSource* parent_source = - frame_sink_source_map_[parent_frame_sink_id].source; + frame_sink_data_map_[parent_frame_sink_id].source; if (!parent_source) return; @@ -198,30 +185,26 @@ // in time. This makes it possible to invalidate parent and child FrameSinkIds // independently of each other and not have an ordering dependency of // unregistering the hierarchy first before either of them. - auto iter = frame_sink_source_map_.find(parent_frame_sink_id); - DCHECK(iter != frame_sink_source_map_.end()); + auto iter = frame_sink_data_map_.find(parent_frame_sink_id); + DCHECK(iter != frame_sink_data_map_.end()); // Remove |child_frame_sink_id| from parents list of children. - auto& mapping = iter->second; - DCHECK(base::ContainsKey(mapping.children, child_frame_sink_id)); - mapping.children.erase(child_frame_sink_id); - - // Delete the FrameSinkSourceMapping for |parent_frame_sink_id| if empty. - if (!mapping.has_children() && !mapping.source) { - frame_sink_source_map_.erase(iter); - return; - } + auto& data = iter->second; + DCHECK(base::ContainsKey(data.children, child_frame_sink_id)); + data.children.erase(child_frame_sink_id); // If the parent does not have a begin frame source, then disconnecting it // will not change any of its children. - BeginFrameSource* parent_source = iter->second.source; - if (!parent_source) + if (!data.source) { + if (data.empty()) + frame_sink_data_map_.erase(iter); return; + } // TODO(enne): these walks could be done in one step. - RecursivelyDetachBeginFrameSource(child_frame_sink_id, parent_source); - for (auto& source_iter : registered_sources_) - RecursivelyAttachBeginFrameSource(source_iter.second, source_iter.first); + RecursivelyDetachBeginFrameSource(child_frame_sink_id, data.source); + for (auto& map_entry : registered_sources_) + RecursivelyAttachBeginFrameSource(map_entry.second, map_entry.first); } void FrameSinkManagerImpl::AssignTemporaryReference(const SurfaceId& surface_id, @@ -250,31 +233,30 @@ const FrameSinkId& frame_sink_id, CompositorFrameSinkSupport* support) { DCHECK(support); + DCHECK(!base::ContainsKey(support_map_, frame_sink_id)); - SinkAndSupport& entry = compositor_frame_sinks_[frame_sink_id]; - DCHECK(!entry.support); - entry.support = support; + support_map_[frame_sink_id] = support; for (auto& capturer : video_capturers_) { if (capturer->requested_target() == frame_sink_id) - capturer->SetResolvedTarget(entry.support); + capturer->SetResolvedTarget(support); } - auto it = frame_sink_source_map_.find(frame_sink_id); - if (it != frame_sink_source_map_.end() && it->second.source) + auto it = frame_sink_data_map_.find(frame_sink_id); + if (it != frame_sink_data_map_.end() && it->second.source) support->SetBeginFrameSource(it->second.source); } void FrameSinkManagerImpl::UnregisterCompositorFrameSinkSupport( const FrameSinkId& frame_sink_id) { - DCHECK_EQ(compositor_frame_sinks_.count(frame_sink_id), 1u); + DCHECK(base::ContainsKey(support_map_, frame_sink_id)); for (auto& capturer : video_capturers_) { if (capturer->requested_target() == frame_sink_id) capturer->OnTargetWillGoAway(); } - compositor_frame_sinks_.erase(frame_sink_id); + support_map_.erase(frame_sink_id); } void FrameSinkManagerImpl::RegisterBeginFrameSource( @@ -299,7 +281,7 @@ primary_source_.OnBeginFrameSourceRemoved(source); - if (frame_sink_source_map_.count(frame_sink_id) == 0u) + if (frame_sink_data_map_.count(frame_sink_id) == 0u) return; // TODO(enne): these walks could be done in one step. @@ -318,17 +300,17 @@ void FrameSinkManagerImpl::RecursivelyAttachBeginFrameSource( const FrameSinkId& frame_sink_id, BeginFrameSource* source) { - FrameSinkSourceMapping& mapping = frame_sink_source_map_[frame_sink_id]; - if (!mapping.source) { - mapping.source = source; - auto iter = compositor_frame_sinks_.find(frame_sink_id); - if (iter != compositor_frame_sinks_.end()) - iter->second.support->SetBeginFrameSource(source); + FrameSinkData& data = frame_sink_data_map_[frame_sink_id]; + if (!data.source) { + data.source = source; + auto iter = support_map_.find(frame_sink_id); + if (iter != support_map_.end()) + iter->second->SetBeginFrameSource(source); } // Copy the list of children because RecursivelyAttachBeginFrameSource() can - // modify |frame_sink_source_map_| and invalidate iterators. - base::flat_set<FrameSinkId> children = mapping.children; + // modify |frame_sink_data_map_| and invalidate iterators. + base::flat_set<FrameSinkId> children = data.children; for (const FrameSinkId& child : children) RecursivelyAttachBeginFrameSource(child, source); } @@ -336,37 +318,37 @@ void FrameSinkManagerImpl::RecursivelyDetachBeginFrameSource( const FrameSinkId& frame_sink_id, BeginFrameSource* source) { - auto iter = frame_sink_source_map_.find(frame_sink_id); - if (iter == frame_sink_source_map_.end()) + auto iter = frame_sink_data_map_.find(frame_sink_id); + if (iter == frame_sink_data_map_.end()) return; - auto& mapping = iter->second; - if (mapping.source == source) { - mapping.source = nullptr; - auto client_iter = compositor_frame_sinks_.find(frame_sink_id); - if (client_iter != compositor_frame_sinks_.end()) - client_iter->second.support->SetBeginFrameSource(nullptr); + auto& data = iter->second; + if (data.source == source) { + data.source = nullptr; + auto client_iter = support_map_.find(frame_sink_id); + if (client_iter != support_map_.end()) + client_iter->second->SetBeginFrameSource(nullptr); } - // Delete the FrameSinkSourceMapping for |frame_sink_id| if empty. - if (!mapping.has_children()) { - frame_sink_source_map_.erase(iter); + // Delete the FrameSinkData for |frame_sink_id| if empty. + if (data.empty()) { + frame_sink_data_map_.erase(iter); return; } // Copy the list of children because RecursivelyDetachBeginFrameSource() can - // modify |frame_sink_source_map_| and invalidate iterators. - base::flat_set<FrameSinkId> children = mapping.children; + // modify |frame_sink_data_map_| and invalidate iterators. + base::flat_set<FrameSinkId> children = data.children; for (const FrameSinkId& child : children) RecursivelyDetachBeginFrameSource(child, source); } CapturableFrameSink* FrameSinkManagerImpl::FindCapturableFrameSink( const FrameSinkId& frame_sink_id) { - const auto it = compositor_frame_sinks_.find(frame_sink_id); - if (it == compositor_frame_sinks_.end()) + const auto it = support_map_.find(frame_sink_id); + if (it == support_map_.end()) return nullptr; - return it->second.support; + return it->second; } void FrameSinkManagerImpl::OnCapturerConnectionLost( @@ -377,8 +359,8 @@ bool FrameSinkManagerImpl::ChildContains( const FrameSinkId& child_frame_sink_id, const FrameSinkId& search_frame_sink_id) const { - auto iter = frame_sink_source_map_.find(child_frame_sink_id); - if (iter == frame_sink_source_map_.end()) + auto iter = frame_sink_data_map_.find(child_frame_sink_id); + if (iter == frame_sink_data_map_.end()) return false; for (const FrameSinkId& child : iter->second.children) { @@ -398,8 +380,7 @@ } else { // There is no client to assign an owner for the temporary reference, so we // can drop the temporary reference safely. - if (surface_manager_.using_surface_references()) - surface_manager_.DropTemporaryReference(surface_id); + surface_manager_.DropTemporaryReference(surface_id); } }
diff --git a/components/viz/service/frame_sinks/frame_sink_manager_impl.h b/components/viz/service/frame_sinks/frame_sink_manager_impl.h index 58798be2..d919f550 100644 --- a/components/viz/service/frame_sinks/frame_sink_manager_impl.h +++ b/components/viz/service/frame_sinks/frame_sink_manager_impl.h
@@ -43,9 +43,7 @@ public FrameSinkVideoCapturerManager, public mojom::FrameSinkManager { public: - FrameSinkManagerImpl(SurfaceManager::LifetimeType lifetime_type = - SurfaceManager::LifetimeType::REFERENCES, - uint32_t number_of_frames_to_activation_deadline = 4u, + FrameSinkManagerImpl(uint32_t number_of_frames_to_activation_deadline = 4u, DisplayProvider* display_provider = nullptr); ~FrameSinkManagerImpl() override; @@ -164,37 +162,25 @@ friend class FrameSinkManagerTest; // BeginFrameSource routing information for a FrameSinkId. - struct FrameSinkSourceMapping { - FrameSinkSourceMapping(); - FrameSinkSourceMapping(FrameSinkSourceMapping&& other); - ~FrameSinkSourceMapping(); - FrameSinkSourceMapping& operator=(FrameSinkSourceMapping&& other); + struct FrameSinkData { + FrameSinkData(); + FrameSinkData(FrameSinkData&& other); + ~FrameSinkData(); + FrameSinkData& operator=(FrameSinkData&& other); - bool has_children() const { return !children.empty(); } + bool empty() const { return !source && children.empty() && !sink; } + // The currently assigned begin frame source for this client. BeginFrameSource* source = nullptr; // This represents a dag of parent -> children mapping. base::flat_set<FrameSinkId> children; - private: - DISALLOW_COPY_AND_ASSIGN(FrameSinkSourceMapping); - }; - - struct SinkAndSupport { - SinkAndSupport(); - SinkAndSupport(SinkAndSupport&& other); - ~SinkAndSupport(); - SinkAndSupport& operator=(SinkAndSupport&& other); - // CompositorFrameSinks owned here. This will be null if a // CompositorFrameSinkSupport is owned externally. std::unique_ptr<mojom::CompositorFrameSink> sink; - // This can be owned by |sink| or owned externally. - CompositorFrameSinkSupport* support = nullptr; - private: - DISALLOW_COPY_AND_ASSIGN(SinkAndSupport); + DISALLOW_COPY_AND_ASSIGN(FrameSinkData); }; void RecursivelyAttachBeginFrameSource(const FrameSinkId& frame_sink_id, @@ -220,11 +206,13 @@ // parent in the dag. base::flat_map<BeginFrameSource*, FrameSinkId> registered_sources_; - // Contains FrameSinkId hierarchy and BeginFrameSource mapping. - base::flat_map<FrameSinkId, FrameSinkSourceMapping> frame_sink_source_map_; + // Contains FrameSinkId hierarchy, BeginFrameSource mapping and maybe a + // [Root]CompositorFrameSinkImpl. + base::flat_map<FrameSinkId, FrameSinkData> frame_sink_data_map_; - // Contains (and maybe owns) the CompositorFrameSinkSupport. - base::flat_map<FrameSinkId, SinkAndSupport> compositor_frame_sinks_; + // CompositorFrameSinkSupports get added to this map on creation and removed + // on destruction. + base::flat_map<FrameSinkId, CompositorFrameSinkSupport*> support_map_; PrimaryBeginFrameSource primary_source_;
diff --git a/components/viz/service/frame_sinks/frame_sink_manager_unittest.cc b/components/viz/service/frame_sinks/frame_sink_manager_unittest.cc index 9b5a2a6d..4491baf 100644 --- a/components/viz/service/frame_sinks/frame_sink_manager_unittest.cc +++ b/components/viz/service/frame_sinks/frame_sink_manager_unittest.cc
@@ -36,8 +36,8 @@ // testing::Test implementation. void TearDown() override { - // Make sure that all FrameSinkSourceMappings have been deleted. - EXPECT_TRUE(manager_.frame_sink_source_map_.empty()); + // Make sure that all FrameSinkData has been deleted. + EXPECT_TRUE(manager_.frame_sink_data_map_.empty()); } protected:
diff --git a/components/viz/service/main/viz_main_impl.cc b/components/viz/service/main/viz_main_impl.cc index 9066f83..fb8f37b 100644 --- a/components/viz/service/main/viz_main_impl.cc +++ b/components/viz/service/main/viz_main_impl.cc
@@ -277,7 +277,6 @@ mojom::FrameSinkManagerClientPtr client( std::move(params->frame_sink_manager_client)); frame_sink_manager_ = std::make_unique<FrameSinkManagerImpl>( - SurfaceManager::LifetimeType::REFERENCES, params->number_of_frames_to_activation_deadline, display_provider_.get()); frame_sink_manager_->BindAndSetClient(std::move(params->frame_sink_manager), nullptr, std::move(client));
diff --git a/components/viz/service/surfaces/direct_surface_reference_factory.cc b/components/viz/service/surfaces/direct_surface_reference_factory.cc deleted file mode 100644 index 1cde4a6..0000000 --- a/components/viz/service/surfaces/direct_surface_reference_factory.cc +++ /dev/null
@@ -1,31 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/viz/service/surfaces/direct_surface_reference_factory.h" - -#include <vector> - -#include "components/viz/service/surfaces/surface.h" - -namespace viz { - -DirectSurfaceReferenceFactory::DirectSurfaceReferenceFactory( - base::WeakPtr<SurfaceManager> manager) - : manager_(manager) {} - -DirectSurfaceReferenceFactory::~DirectSurfaceReferenceFactory() = default; -void DirectSurfaceReferenceFactory::SatisfySequence( - const SurfaceSequence& sequence) const { - if (!manager_) - return; - manager_->SatisfySequence(sequence); -} - -void DirectSurfaceReferenceFactory::RequireSequence( - const SurfaceId& surface_id, - const SurfaceSequence& sequence) const { - manager_->RequireSequence(surface_id, sequence); -} - -} // namespace viz
diff --git a/components/viz/service/surfaces/direct_surface_reference_factory.h b/components/viz/service/surfaces/direct_surface_reference_factory.h deleted file mode 100644 index 1348578..0000000 --- a/components/viz/service/surfaces/direct_surface_reference_factory.h +++ /dev/null
@@ -1,42 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_VIZ_SERVICE_SURFACES_DIRECT_SURFACE_REFERENCE_FACTORY_H_ -#define COMPONENTS_VIZ_SERVICE_SURFACES_DIRECT_SURFACE_REFERENCE_FACTORY_H_ - -#include "base/compiler_specific.h" -#include "components/viz/common/surfaces/sequence_surface_reference_factory.h" -#include "components/viz/common/surfaces/surface_id.h" -#include "components/viz/common/surfaces/surface_sequence.h" -#include "components/viz/service/surfaces/surface_manager.h" -#include "components/viz/service/viz_service_export.h" - -namespace viz { - -class SurfaceManager; - -// The surface reference factory that interacts directly with SurfaceManager. -// You probably don't need to instantiate this class directly. -// Use SurfaceManager::reference_factory() instead. -class VIZ_SERVICE_EXPORT DirectSurfaceReferenceFactory final - : public SequenceSurfaceReferenceFactory { - public: - explicit DirectSurfaceReferenceFactory(base::WeakPtr<SurfaceManager> manager); - - private: - ~DirectSurfaceReferenceFactory() override; - - // SequenceSurfaceReferenceFactory implementation: - void SatisfySequence(const SurfaceSequence& sequence) const override; - void RequireSequence(const SurfaceId& surface_id, - const SurfaceSequence& sequence) const override; - - base::WeakPtr<SurfaceManager> manager_; - - DISALLOW_COPY_AND_ASSIGN(DirectSurfaceReferenceFactory); -}; - -} // namespace viz - -#endif // COMPONENTS_VIZ_SERVICE_SURFACES_DIRECT_SURFACE_REFERENCE_FACTORY_H_
diff --git a/components/viz/service/surfaces/surface.cc b/components/viz/service/surfaces/surface.cc index beccc68..494938d 100644 --- a/components/viz/service/surfaces/surface.cc +++ b/components/viz/service/surfaces/surface.cc
@@ -436,20 +436,6 @@ surface_id().local_surface_id(), damage_rect, active_frame_data_->frame); } -void Surface::AddDestructionDependency(SurfaceSequence sequence) { - destruction_dependencies_.push_back(sequence); -} - -void Surface::SatisfyDestructionDependencies( - base::flat_set<SurfaceSequence>* sequences, - base::flat_map<FrameSinkId, std::string>* valid_frame_sink_ids) { - base::EraseIf(destruction_dependencies_, - [sequences, valid_frame_sink_ids](SurfaceSequence seq) { - return (!!sequences->erase(seq) || - !valid_frame_sink_ids->count(seq.frame_sink_id)); - }); -} - void Surface::OnDeadline() { TRACE_EVENT1("viz", "Surface::OnDeadline", "FrameSinkId", surface_id().frame_sink_id().ToString());
diff --git a/components/viz/service/surfaces/surface.h b/components/viz/service/surfaces/surface.h index 637aa8624..9938cde 100644 --- a/components/viz/service/surfaces/surface.h +++ b/components/viz/service/surfaces/surface.h
@@ -22,7 +22,6 @@ #include "components/viz/common/quads/compositor_frame.h" #include "components/viz/common/surfaces/frame_sink_id.h" #include "components/viz/common/surfaces/surface_info.h" -#include "components/viz/common/surfaces/surface_sequence.h" #include "components/viz/service/surfaces/surface_dependency_deadline.h" #include "components/viz/service/viz_service_export.h" #include "ui/gfx/geometry/size.h" @@ -168,19 +167,6 @@ void RunDrawCallback(); void NotifyAggregatedDamage(const gfx::Rect& damage_rect); - // Add a SurfaceSequence that must be satisfied before the Surface is - // destroyed. - void AddDestructionDependency(SurfaceSequence sequence); - - // Satisfy all destruction dependencies that are contained in sequences, and - // remove them from sequences. - void SatisfyDestructionDependencies( - base::flat_set<SurfaceSequence>* sequences, - base::flat_map<FrameSinkId, std::string>* valid_id_namespaces); - size_t GetDestructionDependencyCount() const { - return destruction_dependencies_.size(); - } - const std::vector<SurfaceId>* active_referenced_surfaces() const { return active_frame_data_ ? &active_frame_data_->frame.metadata.referenced_surfaces @@ -267,7 +253,6 @@ bool closed_ = false; bool seen_first_frame_activation_ = false; const bool needs_sync_tokens_; - std::vector<SurfaceSequence> destruction_dependencies_; base::flat_set<SurfaceId> activation_dependencies_; base::flat_set<SurfaceId> late_activation_dependencies_;
diff --git a/components/viz/service/surfaces/surface_manager.cc b/components/viz/service/surfaces/surface_manager.cc index f8f667e..a8fd6a8 100644 --- a/components/viz/service/surfaces/surface_manager.cc +++ b/components/viz/service/surfaces/surface_manager.cc
@@ -16,9 +16,7 @@ #include "base/metrics/histogram_macros.h" #include "base/threading/sequenced_task_runner_handle.h" #include "components/viz/common/surfaces/parent_local_surface_id_allocator.h" -#include "components/viz/common/surfaces/stub_surface_reference_factory.h" #include "components/viz/common/surfaces/surface_info.h" -#include "components/viz/service/surfaces/direct_surface_reference_factory.h" #include "components/viz/service/surfaces/surface.h" #include "components/viz/service/surfaces/surface_client.h" @@ -45,16 +43,12 @@ SurfaceManager::TemporaryReferenceData::~TemporaryReferenceData() = default; -SurfaceManager::SurfaceManager(LifetimeType lifetime_type, - uint32_t number_of_frames_to_activation_deadline) - : lifetime_type_(lifetime_type), - dependency_tracker_(this, number_of_frames_to_activation_deadline), +SurfaceManager::SurfaceManager(uint32_t number_of_frames_to_activation_deadline) + : dependency_tracker_(this, number_of_frames_to_activation_deadline), root_surface_id_(FrameSinkId(0u, 0u), LocalSurfaceId(1u, base::UnguessableToken::Create())), weak_factory_(this) { thread_checker_.DetachFromThread(); - if (using_surface_references()) { - reference_factory_ = new StubSurfaceReferenceFactory(); // Android WebView doesn't have a task runner and doesn't need the timer. if (base::SequencedTaskRunnerHandle::IsSet()) { @@ -65,10 +59,6 @@ // TODO(kylechar): After collecting UMA stats on the number of old temporary // references, we may want to turn the timer off when there are no temporary // references to avoid waking the thread unnecessarily. - } else { - reference_factory_ = - new DirectSurfaceReferenceFactory(weak_factory_.GetWeakPtr()); - } } SurfaceManager::~SurfaceManager() { @@ -124,15 +114,14 @@ surface_map_[surface_info.id()] = std::make_unique<Surface>(surface_info, this, surface_client, begin_frame_source, needs_sync_tokens); - if (lifetime_type_ == LifetimeType::REFERENCES) { - // We can get into a situation where multiple CompositorFrames arrive for - // a FrameSink before the client can add any references for the frame. - // When the second frame with a new size arrives, the first will be - // destroyed in SurfaceFactory and then if there are no references it will - // be deleted during surface GC. A temporary reference, removed when a - // real reference is received, is added to prevent this from happening. - AddTemporaryReference(surface_info.id()); - } + // We can get into a situation where multiple CompositorFrames arrive for a + // FrameSink before the client can add any references for the frame. When + // the second frame with a new size arrives, the first will be destroyed in + // SurfaceFactory and then if there are no references it will be deleted + // during surface GC. A temporary reference, removed when a real reference + // is received, is added to prevent this from happening. + AddTemporaryReference(surface_info.id()); + for (auto& observer : observer_list_) observer.OnSurfaceCreated(surface_info.id()); return surface_map_[surface_info.id()].get(); @@ -161,23 +150,6 @@ surfaces_to_destroy_.insert(surface_id); } -void SurfaceManager::RequireSequence(const SurfaceId& surface_id, - const SurfaceSequence& sequence) { - DCHECK_EQ(lifetime_type_, LifetimeType::SEQUENCES); - auto* surface = GetSurfaceForId(surface_id); - if (!surface) { - DLOG(ERROR) << "Attempting to require callback on nonexistent surface"; - return; - } - surface->AddDestructionDependency(sequence); -} - -void SurfaceManager::SatisfySequence(const SurfaceSequence& sequence) { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - DCHECK_EQ(lifetime_type_, LifetimeType::SEQUENCES); - satisfied_sequences_.insert(sequence); -} - void SurfaceManager::RegisterFrameSinkId(const FrameSinkId& frame_sink_id) { bool inserted = valid_frame_sink_labels_.emplace(frame_sink_id, "").second; DCHECK(inserted); @@ -238,7 +210,6 @@ void SurfaceManager::AssignTemporaryReference(const SurfaceId& surface_id, const FrameSinkId& owner) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - DCHECK_EQ(lifetime_type_, LifetimeType::REFERENCES); if (!HasTemporaryReference(surface_id)) return; @@ -249,10 +220,8 @@ void SurfaceManager::DropTemporaryReference(const SurfaceId& surface_id) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - if (lifetime_type_ != LifetimeType::REFERENCES || - !HasTemporaryReference(surface_id)) { + if (!HasTemporaryReference(surface_id)) return; - } RemoveTemporaryReference(surface_id, false); } @@ -262,9 +231,7 @@ if (surfaces_to_destroy_.empty()) return; - SurfaceIdSet reachable_surfaces = using_surface_references() - ? GetLiveSurfacesForReferences() - : GetLiveSurfacesForSequences(); + SurfaceIdSet reachable_surfaces = GetLiveSurfacesForReferences(); std::vector<SurfaceId> surfaces_to_delete; @@ -301,8 +268,6 @@ } SurfaceManager::SurfaceIdSet SurfaceManager::GetLiveSurfacesForReferences() { - DCHECK(using_surface_references()); - SurfaceIdSet reachable_surfaces; // Walk down from the root and mark each SurfaceId we encounter as @@ -339,52 +304,6 @@ return reachable_surfaces; } -SurfaceManager::SurfaceIdSet SurfaceManager::GetLiveSurfacesForSequences() { - DCHECK_EQ(lifetime_type_, LifetimeType::SEQUENCES); - - // Simple mark and sweep GC. - // TODO(jbauman): Reduce the amount of work when nothing needs to be - // destroyed. - std::vector<SurfaceId> live_surfaces; - std::unordered_set<SurfaceId, SurfaceIdHash> live_surfaces_set; - - // GC roots are surfaces that have not been destroyed, or have not had all - // their destruction dependencies satisfied. - for (auto& map_entry : surface_map_) { - const SurfaceId& surface_id = map_entry.first; - Surface* surface = map_entry.second.get(); - surface->SatisfyDestructionDependencies(&satisfied_sequences_, - &valid_frame_sink_labels_); - - if (!IsMarkedForDestruction(surface_id) || - surface->GetDestructionDependencyCount() > 0) { - live_surfaces_set.insert(surface_id); - live_surfaces.push_back(surface_id); - } - } - - // Mark all surfaces reachable from live surfaces by adding them to - // live_surfaces and live_surfaces_set. - for (size_t i = 0; i < live_surfaces.size(); i++) { - Surface* surf = surface_map_[live_surfaces[i]].get(); - DCHECK(surf); - - const auto& children = GetSurfacesReferencedByParent(surf->surface_id()); - for (const SurfaceId& id : children) { - if (live_surfaces_set.count(id)) - continue; - - Surface* surf2 = GetSurfaceForId(id); - if (surf2) { - live_surfaces.push_back(id); - live_surfaces_set.insert(id); - } - } - } - - return live_surfaces_set; -} - void SurfaceManager::AddSurfaceReferenceImpl(const SurfaceId& parent_id, const SurfaceId& child_id) { if (parent_id.frame_sink_id() == child_id.frame_sink_id()) { @@ -482,9 +401,6 @@ Surface* SurfaceManager::GetLatestInFlightSurface( const SurfaceId& primary_surface_id, const SurfaceId& fallback_surface_id) { - if (!using_surface_references()) - return nullptr; - // The fallback surface must exist before we begin looking for more recent // surfaces. This guarantees that the |parent| is allowed to embed the // |fallback_surface_id| and is not guessing surface IDs.
diff --git a/components/viz/service/surfaces/surface_manager.h b/components/viz/service/surfaces/surface_manager.h index b555701..c8093532 100644 --- a/components/viz/service/surfaces/surface_manager.h +++ b/components/viz/service/surfaces/surface_manager.h
@@ -22,8 +22,6 @@ #include "base/timer/timer.h" #include "components/viz/common/surfaces/frame_sink_id.h" #include "components/viz/common/surfaces/surface_id.h" -#include "components/viz/common/surfaces/surface_reference_factory.h" -#include "components/viz/common/surfaces/surface_sequence.h" #include "components/viz/service/surfaces/surface_dependency_tracker.h" #include "components/viz/service/surfaces/surface_observer.h" #include "components/viz/service/surfaces/surface_reference.h" @@ -45,13 +43,7 @@ class VIZ_SERVICE_EXPORT SurfaceManager { public: - enum class LifetimeType { - REFERENCES, - SEQUENCES, - }; - - SurfaceManager(LifetimeType lifetime_type, - uint32_t number_of_frames_to_activation_deadline); + explicit SurfaceManager(uint32_t number_of_frames_to_activation_deadline); ~SurfaceManager(); #if DCHECK_IS_ON() @@ -64,8 +56,7 @@ // Creates a Surface for the given SurfaceClient. The surface will be // destroyed when DestroySurface is called, all of its destruction // dependencies are satisfied, and it is not reachable from the root surface. - // If LifetimeType=REFERENCES, then a temporary reference will be added to - // the new Surface. + // A temporary reference will be added to the new Surface. Surface* CreateSurface(base::WeakPtr<SurfaceClient> surface_client, const SurfaceInfo& surface_info, BeginFrameSource* begin_frame_source, @@ -110,15 +101,6 @@ void SurfaceDamageExpected(const SurfaceId& surface_id, const BeginFrameArgs& args); - // Require that the given sequence number must be satisfied (using - // SatisfySequence) before the given surface can be destroyed. - void RequireSequence(const SurfaceId& surface_id, - const SurfaceSequence& sequence); - - // Satisfies the given sequence number. Once all sequence numbers that - // a surface depends on are satisfied, the surface can be destroyed. - void SatisfySequence(const SurfaceSequence& sequence); - void RegisterFrameSinkId(const FrameSinkId& frame_sink_id); // Invalidate a frame_sink_id that might still have associated sequences, @@ -186,14 +168,6 @@ const base::flat_set<SurfaceId>& GetSurfacesThatReferenceChild( const SurfaceId& surface_id) const; - const scoped_refptr<SurfaceReferenceFactory>& reference_factory() { - return reference_factory_; - } - - bool using_surface_references() const { - return lifetime_type_ == LifetimeType::REFERENCES; - } - // Returns the most recent surface associated with the |fallback_surface_id|'s // FrameSinkId that was created prior to the current primary surface and // verified by the viz host to be owned by the fallback surface's parent. If @@ -290,9 +264,6 @@ const base::flat_set<SurfaceId>& fallback_parents, const base::Optional<FrameSinkId>& owner) const; - // Use reference or sequence based lifetime management. - LifetimeType lifetime_type_; - // SurfaceDependencyTracker needs to be destroyed after Surfaces are destroyed // because they will call back into the dependency tracker. SurfaceDependencyTracker dependency_tracker_; @@ -303,10 +274,6 @@ base::flat_set<SurfaceId> surfaces_to_destroy_; - // Set of SurfaceSequences that have been satisfied by a frame but not yet - // waited on. - base::flat_set<SurfaceSequence> satisfied_sequences_; - // Set of valid FrameSinkIds and their labels. When a FrameSinkId is removed // from this set, any remaining (surface) sequences with that FrameSinkId are // considered satisfied. @@ -320,10 +287,6 @@ // for a SurfaceId. const base::flat_set<SurfaceId> empty_surface_id_set_; - // The DirectSurfaceReferenceFactory that uses this manager to create surface - // references. - scoped_refptr<SurfaceReferenceFactory> reference_factory_; - // Keeps track of surface references for a surface. The graph of references is // stored in both directions, so we know the parents and children for each // surface.
diff --git a/components/viz/service/surfaces/surface_unittest.cc b/components/viz/service/surfaces/surface_unittest.cc index 1745dd6..c80ea0f6 100644 --- a/components/viz/service/surfaces/surface_unittest.cc +++ b/components/viz/service/surfaces/surface_unittest.cc
@@ -86,25 +86,6 @@ } } -TEST(SurfaceTest, SurfaceLifetime) { - FrameSinkManagerImpl frame_sink_manager( - SurfaceManager::LifetimeType::SEQUENCES); - SurfaceManager* surface_manager = frame_sink_manager.surface_manager(); - auto support = std::make_unique<CompositorFrameSinkSupport>( - nullptr, &frame_sink_manager, kArbitraryFrameSinkId, kIsRoot, - kNeedsSyncPoints); - - LocalSurfaceId local_surface_id(6, base::UnguessableToken::Create()); - SurfaceId surface_id(kArbitraryFrameSinkId, local_surface_id); - support->SubmitCompositorFrame(local_surface_id, - MakeDefaultCompositorFrame()); - EXPECT_TRUE(surface_manager->GetSurfaceForId(surface_id)); - support->EvictCurrentSurface(); - frame_sink_manager.surface_manager()->GarbageCollectSurfaces(); - - EXPECT_EQ(nullptr, surface_manager->GetSurfaceForId(surface_id)); -} - TEST(SurfaceTest, SurfaceIds) { for (size_t i = 0; i < 3; ++i) { ParentLocalSurfaceIdAllocator allocator;
diff --git a/content/browser/background_sync/background_sync_manager.cc b/content/browser/background_sync/background_sync_manager.cc index 8933f624..fc197cd5 100644 --- a/content/browser/background_sync/background_sync_manager.cc +++ b/content/browser/background_sync/background_sync_manager.cc
@@ -162,7 +162,7 @@ std::move(callback).Run(mojo::ConvertTo<ServiceWorkerStatusCode>(status)); } -void DidStartWorker( +void DidStartWorkerForSyncEvent( base::OnceCallback<void(ServiceWorkerVersion::StatusCallback)> task, ServiceWorkerVersion::StatusCallback callback, ServiceWorkerStatusCode start_worker_status) { @@ -775,7 +775,7 @@ if (active_version->running_status() != EmbeddedWorkerStatus::RUNNING) { active_version->RunAfterStartWorker( ServiceWorkerMetrics::EventType::SYNC, - base::BindOnce(&DidStartWorker, + base::BindOnce(&DidStartWorkerForSyncEvent, base::BindOnce(&BackgroundSyncManager::DispatchSyncEvent, weak_ptr_factory_.GetWeakPtr(), tag, std::move(active_version), last_chance),
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index 9b1fbc4d..e65679a 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc
@@ -147,6 +147,7 @@ #endif #if BUILDFLAG(USE_ZYGOTE_HANDLE) +#include "content/public/common/common_sandbox_support_linux.h" #include "content/public/common/zygote_handle.h" #include "media/base/media_switches.h" #endif @@ -284,7 +285,15 @@ kForwardSwitches, arraysize(kForwardSwitches)); GetContentClient()->browser()->AppendExtraCommandLineSwitches(cmd_line, -1); - return ZygoteHostImpl::GetInstance()->LaunchZygote(cmd_line, control_fd); + + // Start up the sandbox host process and get the file descriptor for the + // sandboxed processes to talk to it. + base::FileHandleMappingVector additional_remapped_fds; + additional_remapped_fds.emplace_back( + SandboxHostLinux::GetInstance()->GetChildSocket(), GetSandboxFD()); + + return ZygoteHostImpl::GetInstance()->LaunchZygote( + cmd_line, control_fd, std::move(additional_remapped_fds)); } void SetupSandbox(const base::CommandLine& parsed_command_line) { @@ -1553,7 +1562,6 @@ ImageTransportFactory::SetFactory(std::move(transport_factory)); } else { frame_sink_manager_impl_ = std::make_unique<viz::FrameSinkManagerImpl>( - viz::SurfaceManager::LifetimeType::REFERENCES, switches::GetDeadlineToSynchronizeSurfaces()); surface_utils::ConnectWithLocalFrameSinkManager(
diff --git a/content/browser/browser_plugin/browser_plugin_guest.cc b/content/browser/browser_plugin/browser_plugin_guest.cc index c83e5ba..af60603 100644 --- a/content/browser/browser_plugin/browser_plugin_guest.cc +++ b/content/browser/browser_plugin/browser_plugin_guest.cc
@@ -18,12 +18,10 @@ #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" #include "components/viz/common/surfaces/surface_info.h" -#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h" #include "components/viz/service/surfaces/surface.h" #include "content/browser/browser_plugin/browser_plugin_embedder.h" #include "content/browser/browser_thread_impl.h" #include "content/browser/child_process_security_policy_impl.h" -#include "content/browser/compositor/surface_utils.h" #include "content/browser/frame_host/render_frame_host_impl.h" #include "content/browser/frame_host/render_frame_proxy_host.h" #include "content/browser/frame_host/render_widget_host_view_guest.h" @@ -312,8 +310,6 @@ IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_UnlockMouse_ACK, OnUnlockMouseAck) IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_UpdateResizeParams, OnUpdateResizeParams) - IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_SatisfySequence, OnSatisfySequence) - IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_RequireSequence, OnRequireSequence) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; @@ -433,29 +429,15 @@ } void BrowserPluginGuest::SetChildFrameSurface( - const viz::SurfaceInfo& surface_info, - const viz::SurfaceSequence& sequence) { + const viz::SurfaceInfo& surface_info) { has_attached_since_surface_set_ = false; if (!switches::IsMusHostingViz()) { SendMessageToEmbedder( std::make_unique<BrowserPluginMsg_SetChildFrameSurface>( - browser_plugin_instance_id(), surface_info, sequence)); + browser_plugin_instance_id(), surface_info)); } } -void BrowserPluginGuest::OnSatisfySequence( - int instance_id, - const viz::SurfaceSequence& sequence) { - GetFrameSinkManager()->surface_manager()->SatisfySequence(sequence); -} - -void BrowserPluginGuest::OnRequireSequence( - int instance_id, - const viz::SurfaceId& id, - const viz::SurfaceSequence& sequence) { - GetFrameSinkManager()->surface_manager()->RequireSequence(id, sequence); -} - void BrowserPluginGuest::ResendEventToEmbedder( const blink::WebInputEvent& event) { if (!attached() || !owner_web_contents_)
diff --git a/content/browser/browser_plugin/browser_plugin_guest.h b/content/browser/browser_plugin/browser_plugin_guest.h index f47d039..91dd79f 100644 --- a/content/browser/browser_plugin/browser_plugin_guest.h +++ b/content/browser/browser_plugin/browser_plugin_guest.h
@@ -59,9 +59,7 @@ namespace viz { class LocalSurfaceId; -class SurfaceId; class SurfaceInfo; -struct SurfaceSequence; } // namespace viz namespace content { @@ -260,8 +258,7 @@ void PointerLockPermissionResponse(bool allow); // The next function is virtual for test purposes. - virtual void SetChildFrameSurface(const viz::SurfaceInfo& surface_info, - const viz::SurfaceSequence& sequence); + virtual void SetChildFrameSurface(const viz::SurfaceInfo& surface_info); void ResendEventToEmbedder(const blink::WebInputEvent& event); @@ -300,10 +297,6 @@ void InitInternal(const BrowserPluginHostMsg_Attach_Params& params, WebContentsImpl* owner_web_contents); - void OnSatisfySequence(int instance_id, const viz::SurfaceSequence& sequence); - void OnRequireSequence(int instance_id, - const viz::SurfaceId& id, - const viz::SurfaceSequence& sequence); // Message handlers for messages from embedder. void OnDetach(int instance_id); // Handles drag events from the embedder.
diff --git a/content/browser/browsing_data/browsing_data_remover_impl.cc b/content/browser/browsing_data/browsing_data_remover_impl.cc index b2bca5a..1c64aa5 100644 --- a/content/browser/browsing_data/browsing_data_remover_impl.cc +++ b/content/browser/browsing_data/browsing_data_remover_impl.cc
@@ -12,6 +12,7 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/callback.h" +#include "base/callback_helpers.h" #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/metrics/histogram_macros.h" @@ -288,7 +289,7 @@ // 3. Do not support partial deletion, i.e. only delete your data if // |filter_builder.IsEmptyBlacklist()|. Add a comment explaining why this // is acceptable. - base::OnceClosure synchronous_clear_operations( + base::ScopedClosureRunner synchronous_clear_operations( CreatePendingTaskCompletionClosure()); // crbug.com/140910: Many places were calling this with base::Time() as @@ -485,9 +486,6 @@ delete_begin_, delete_end_, remove_mask, filter_builder, origin_type_mask, CreatePendingTaskCompletionClosure()); } - - // Notify in case all actions taken were synchronous. - std::move(synchronous_clear_operations).Run(); } void BrowsingDataRemoverImpl::AddObserver(Observer* observer) { @@ -604,7 +602,7 @@ BrowsingDataRemoverImpl::CreatePendingTaskCompletionClosure() { DCHECK_CURRENTLY_ON(BrowserThread::UI); num_pending_tasks_++; - return base::Bind(&BrowsingDataRemoverImpl::OnTaskComplete, GetWeakPtr()); + return base::BindOnce(&BrowsingDataRemoverImpl::OnTaskComplete, GetWeakPtr()); } base::WeakPtr<BrowsingDataRemoverImpl> BrowsingDataRemoverImpl::GetWeakPtr() {
diff --git a/content/browser/frame_host/cross_process_frame_connector.cc b/content/browser/frame_host/cross_process_frame_connector.cc index 26e705e..0e77070 100644 --- a/content/browser/frame_host/cross_process_frame_connector.cc +++ b/content/browser/frame_host/cross_process_frame_connector.cc
@@ -53,8 +53,6 @@ IPC_MESSAGE_HANDLER(FrameHostMsg_SetIsInert, OnSetIsInert) IPC_MESSAGE_HANDLER(FrameHostMsg_UpdateRenderThrottlingStatus, OnUpdateRenderThrottlingStatus) - IPC_MESSAGE_HANDLER(FrameHostMsg_SatisfySequence, OnSatisfySequence) - IPC_MESSAGE_HANDLER(FrameHostMsg_RequireSequence, OnRequireSequence) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() @@ -107,21 +105,9 @@ } void CrossProcessFrameConnector::SetChildFrameSurface( - const viz::SurfaceInfo& surface_info, - const viz::SurfaceSequence& sequence) { + const viz::SurfaceInfo& surface_info) { frame_proxy_in_parent_renderer_->Send(new FrameMsg_SetChildFrameSurface( - frame_proxy_in_parent_renderer_->GetRoutingID(), surface_info, sequence)); -} - -void CrossProcessFrameConnector::OnSatisfySequence( - const viz::SurfaceSequence& sequence) { - GetFrameSinkManager()->surface_manager()->SatisfySequence(sequence); -} - -void CrossProcessFrameConnector::OnRequireSequence( - const viz::SurfaceId& id, - const viz::SurfaceSequence& sequence) { - GetFrameSinkManager()->surface_manager()->RequireSequence(id, sequence); + frame_proxy_in_parent_renderer_->GetRoutingID(), surface_info)); } void CrossProcessFrameConnector::UpdateCursor(const WebCursor& cursor) {
diff --git a/content/browser/frame_host/cross_process_frame_connector.h b/content/browser/frame_host/cross_process_frame_connector.h index 9add9fc..b6108dd 100644 --- a/content/browser/frame_host/cross_process_frame_connector.h +++ b/content/browser/frame_host/cross_process_frame_connector.h
@@ -76,8 +76,7 @@ RenderWidgetHostViewBase* GetParentRenderWidgetHostView() override; RenderWidgetHostViewBase* GetRootRenderWidgetHostView() override; void RenderProcessGone() override; - void SetChildFrameSurface(const viz::SurfaceInfo& surface_info, - const viz::SurfaceSequence& sequence) override; + void SetChildFrameSurface(const viz::SurfaceInfo& surface_info) override; void UpdateCursor(const WebCursor& cursor) override; gfx::PointF TransformPointToRootCoordSpace( const gfx::PointF& point, @@ -137,9 +136,6 @@ void OnSetIsInert(bool); void OnUpdateRenderThrottlingStatus(bool is_throttled, bool subtree_throttled); - void OnSatisfySequence(const viz::SurfaceSequence& sequence); - void OnRequireSequence(const viz::SurfaceId& id, - const viz::SurfaceSequence& sequence); // The RenderFrameProxyHost that routes messages to the parent frame's // renderer process.
diff --git a/content/browser/frame_host/frame_tree_node.cc b/content/browser/frame_host/frame_tree_node.cc index 65d872e..f7c61cb 100644 --- a/content/browser/frame_host/frame_tree_node.cc +++ b/content/browser/frame_host/frame_tree_node.cc
@@ -465,6 +465,13 @@ return did_change_flags || did_change_container_policy; } +void FrameTreeNode::TransferNavigationRequestOwnership( + RenderFrameHostImpl* render_frame_host) { + RenderFrameDevToolsAgentHost::OnResetNavigationRequest( + navigation_request_.get()); + render_frame_host->SetNavigationRequest(std::move(navigation_request_)); +} + void FrameTreeNode::CreatedNavigationRequest( std::unique_ptr<NavigationRequest> navigation_request) { CHECK(IsBrowserSideNavigationEnabled());
diff --git a/content/browser/frame_host/frame_tree_node.h b/content/browser/frame_host/frame_tree_node.h index 4a2f5b8..e71b0b6 100644 --- a/content/browser/frame_host/frame_tree_node.h +++ b/content/browser/frame_host/frame_tree_node.h
@@ -286,6 +286,12 @@ NavigationRequest* navigation_request() { return navigation_request_.get(); } + // Transfers the ownership of the NavigationRequest to |render_frame_host|. + // From ReadyToCommit to DidCommit, the NavigationRequest is owned by the + // RenderFrameHost that is committing the navigation. + void TransferNavigationRequestOwnership( + RenderFrameHostImpl* render_frame_host); + // PlzNavigate // Takes ownership of |navigation_request| and makes it the current // NavigationRequest of this frame. This corresponds to the start of a new
diff --git a/content/browser/frame_host/navigation_controller_impl_browsertest.cc b/content/browser/frame_host/navigation_controller_impl_browsertest.cc index f820882..a925693a 100644 --- a/content/browser/frame_host/navigation_controller_impl_browsertest.cc +++ b/content/browser/frame_host/navigation_controller_impl_browsertest.cc
@@ -7181,7 +7181,7 @@ FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) ->GetFrameTree() ->root(); - EXPECT_FALSE(main_frame->navigation_handle()); + EXPECT_FALSE(main_frame->GetNavigationHandle()); EXPECT_FALSE(root->navigation_request()); // Start navigating to the second page. @@ -7193,7 +7193,7 @@ EXPECT_TRUE(manager.WaitForRequestStart()); // This should create a NavigationHandle. - NavigationHandleImpl* handle = main_frame->navigation_handle(); + NavigationHandleImpl* handle = main_frame->GetNavigationHandle(); NavigationRequest* request = root->navigation_request(); if (IsBrowserSideNavigationEnabled()) { EXPECT_TRUE(request); @@ -7221,8 +7221,8 @@ EXPECT_TRUE(root->navigation_request()); EXPECT_EQ(request, root->navigation_request()); } else { - EXPECT_TRUE(main_frame->navigation_handle()); - EXPECT_EQ(handle, main_frame->navigation_handle()); + EXPECT_TRUE(main_frame->GetNavigationHandle()); + EXPECT_EQ(handle, main_frame->GetNavigationHandle()); } // Let the navigation finish. It should commit successfully.
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc index ac20cab5b..f5e34d5b 100644 --- a/content/browser/frame_host/navigation_request.cc +++ b/content/browser/frame_host/navigation_request.cc
@@ -578,9 +578,9 @@ } } -void NavigationRequest::TransferNavigationHandleOwnership( - RenderFrameHostImpl* render_frame_host) { - render_frame_host->SetNavigationHandle(std::move(navigation_handle_)); +std::unique_ptr<NavigationHandleImpl> +NavigationRequest::TakeNavigationHandle() { + return std::move(navigation_handle_); } void NavigationRequest::OnRequestRedirected( @@ -1240,9 +1240,8 @@ void NavigationRequest::CommitErrorPage( RenderFrameHostImpl* render_frame_host, const base::Optional<std::string>& error_page_content) { - TransferNavigationHandleOwnership(render_frame_host); - render_frame_host->navigation_handle()->ReadyToCommitNavigation( - render_frame_host); + frame_tree_node_->TransferNavigationRequestOwnership(render_frame_host); + navigation_handle_->ReadyToCommitNavigation(render_frame_host); render_frame_host->FailedNavigation(common_params_, request_params_, has_stale_copy_in_cache_, net_error_, error_page_content); @@ -1261,14 +1260,11 @@ render_frame_host == frame_tree_node_->render_manager()->speculative_frame_host()); - TransferNavigationHandleOwnership(render_frame_host); - + frame_tree_node_->TransferNavigationRequestOwnership(render_frame_host); render_frame_host->CommitNavigation( response_.get(), std::move(url_loader_client_endpoints_), std::move(body_), common_params_, request_params_, is_view_source_, std::move(subresource_loader_params_), devtools_navigation_token_); - - frame_tree_node_->ResetNavigationRequest(true, true); } NavigationRequest::ContentSecurityPolicyCheckResult
diff --git a/content/browser/frame_host/navigation_request.h b/content/browser/frame_host/navigation_request.h index f0a832b..925a71b8 100644 --- a/content/browser/frame_host/navigation_request.h +++ b/content/browser/frame_host/navigation_request.h
@@ -171,13 +171,8 @@ // NavigationRequest for the FrameTreeNode has been destroyed. void CreateNavigationHandle(); - // Transfers the ownership of the NavigationHandle to |render_frame_host|. - // This should be called when the navigation is ready to commit, because the - // NavigationHandle outlives the NavigationRequest. The NavigationHandle's - // lifetime is the entire navigation, while the NavigationRequest is - // destroyed when a navigation is ready for commit. - void TransferNavigationHandleOwnership( - RenderFrameHostImpl* render_frame_host); + // Returns ownership of the navigation handle. + std::unique_ptr<NavigationHandleImpl> TakeNavigationHandle(); void set_on_start_checks_complete_closure_for_testing( const base::Closure& closure) {
diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc index e327ed6..fe17841c 100644 --- a/content/browser/frame_host/navigator_impl.cc +++ b/content/browser/frame_host/navigator_impl.cc
@@ -190,7 +190,7 @@ if (is_main_frame && !is_error_page) { DidStartMainFrameNavigation(validated_url, render_frame_host->GetSiteInstance(), - render_frame_host->navigation_handle()); + render_frame_host->GetNavigationHandle()); } } @@ -238,8 +238,8 @@ // Discard the pending navigation entry if needed. int expected_pending_entry_id = - render_frame_host->navigation_handle() - ? render_frame_host->navigation_handle()->pending_nav_entry_id() + render_frame_host->GetNavigationHandle() + ? render_frame_host->GetNavigationHandle()->pending_nav_entry_id() : 0; DiscardPendingEntryIfNeeded(expected_pending_entry_id); }
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index fc3412c..c6ef1f6b 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -578,9 +578,9 @@ } RenderFrameHostImpl::~RenderFrameHostImpl() { - // Destroying navigation handle may call into delegates/observers, + // Destroying |navigation_request_| may call into delegates/observers, // so we do it early while |this| object is still in a sane state. - navigation_handle_.reset(); + navigation_request_.reset(); // Release the WebUI instances before all else as the WebUI may accesses the // RenderFrameHost during cleanup. @@ -1061,8 +1061,8 @@ DCHECK_EQ(site_instance_.get(), site_instance); // The renderer process is gone, so this frame can no longer be loading. - if (navigation_handle_) - navigation_handle_->set_net_error_code(net::ERR_ABORTED); + if (GetNavigationHandle()) + GetNavigationHandle()->set_net_error_code(net::ERR_ABORTED); ResetLoadingState(); // The renderer process is gone, so the |stream_handle_| will no longer be @@ -1496,8 +1496,8 @@ // happening in practice. See https://crbug.com/605289. // Update the error code in the NavigationHandle of the navigation. - if (navigation_handle_) { - navigation_handle_->set_net_error_code( + if (GetNavigationHandle()) { + GetNavigationHandle()->set_net_error_code( static_cast<net::Error>(params.error_code)); } @@ -1678,7 +1678,7 @@ return; } - if (!navigation_handle_) { + if (!navigation_request_) { // The browser has not been notified about the start of the load in this // renderer yet (e.g., for same-document navigations that start in the // renderer). Do it now. @@ -1759,9 +1759,14 @@ return GlobalFrameRoutingId(GetProcess()->GetID(), GetRoutingID()); } -void RenderFrameHostImpl::SetNavigationHandle( - std::unique_ptr<NavigationHandleImpl> navigation_handle) { - navigation_handle_ = std::move(navigation_handle); +NavigationHandleImpl* RenderFrameHostImpl::GetNavigationHandle() { + return navigation_request() ? navigation_request()->navigation_handle() + : nullptr; +} + +void RenderFrameHostImpl::SetNavigationRequest( + std::unique_ptr<NavigationRequest> navigation_request) { + navigation_request_ = std::move(navigation_request); } void RenderFrameHostImpl::SwapOut( @@ -2734,7 +2739,7 @@ } is_loading_ = false; - navigation_handle_.reset(); + navigation_request_.reset(); // Only inform the FrameTreeNode of a change in load state if the load state // of this RenderFrameHost is being tracked. @@ -3679,9 +3684,8 @@ // An error page is expected to commit, hence why is_loading_ is set to true. is_loading_ = true; - if (navigation_handle_) - DCHECK_NE(net::OK, navigation_handle_->GetNetErrorCode()); - frame_tree_node_->ResetNavigationRequest(true, true); + DCHECK(GetNavigationHandle() && + GetNavigationHandle()->GetNetErrorCode() != net::OK); } void RenderFrameHostImpl::SetUpMojoIfNeeded() { @@ -4368,14 +4372,19 @@ const FrameHostMsg_DidCommitProvisionalLoad_Params& params) { bool is_browser_initiated = (params.nav_entry_id != 0); + NavigationHandleImpl* navigation_handle = GetNavigationHandle(); + if (params.was_within_same_document) { // A NavigationHandle is created for browser-initiated same-document // navigation. Try to take it if it's still available and matches the // current navigation. - if (is_browser_initiated && navigation_handle_ && - navigation_handle_->IsSameDocument() && - navigation_handle_->GetURL() == params.url) { - return std::move(navigation_handle_); + if (is_browser_initiated && navigation_handle && + navigation_handle->IsSameDocument() && + navigation_handle->GetURL() == params.url) { + std::unique_ptr<NavigationHandleImpl> result_navigation_handle = + navigation_request()->TakeNavigationHandle(); + navigation_request_.reset(); + return result_navigation_handle; } // No existing NavigationHandle has been found. Create a new one, but don't @@ -4406,8 +4415,11 @@ } // Determine if the current NavigationHandle can be used. - if (navigation_handle_ && navigation_handle_->GetURL() == params.url) { - return std::move(navigation_handle_); + if (navigation_handle && navigation_handle->GetURL() == params.url) { + std::unique_ptr<NavigationHandleImpl> result_navigation_handle = + navigation_request()->TakeNavigationHandle(); + navigation_request_.reset(); + return result_navigation_handle; } // If the URL does not match what the NavigationHandle expects, treat the @@ -4426,26 +4438,22 @@ // and that it matches this handle. TODO(csharrison): The pending entry's // base url should equal |params.base_url|. This is not the case for loads // with invalid base urls. - if (navigation_handle_) { + if (navigation_handle) { NavigationEntryImpl* pending_entry = NavigationEntryImpl::FromNavigationEntry( frame_tree_node()->navigator()->GetController()->GetPendingEntry()); bool pending_entry_matches_handle = - pending_entry && - pending_entry->GetUniqueID() == - navigation_handle_->pending_nav_entry_id(); + pending_entry && pending_entry->GetUniqueID() == + navigation_handle->pending_nav_entry_id(); // TODO(csharrison): The pending entry's base url should equal // |validated_params.base_url|. This is not the case for loads with invalid // base urls. - if (navigation_handle_->GetURL() == params.base_url && + if (navigation_handle->GetURL() == params.base_url && pending_entry_matches_handle && !pending_entry->GetBaseURLForDataURL().is_empty()) { - entry_id_for_data_nav = navigation_handle_->pending_nav_entry_id(); + entry_id_for_data_nav = navigation_handle->pending_nav_entry_id(); is_renderer_initiated = pending_entry->is_renderer_initiated(); } - - // Reset any existing NavigationHandle. - navigation_handle_.reset(); } // There is no pending NavigationEntry in these cases, so pass 0 as the
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h index fee62ff..c994d60 100644 --- a/content/browser/frame_host/render_frame_host_impl.h +++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -118,6 +118,7 @@ class KeepAliveHandleFactory; class MediaInterfaceProxy; class NavigationHandleImpl; +class NavigationRequest; class PermissionServiceContext; class PresentationServiceImpl; class RenderFrameHostDelegate; @@ -377,18 +378,19 @@ int nav_entry_id() const { return nav_entry_id_; } void set_nav_entry_id(int nav_entry_id) { nav_entry_id_ = nav_entry_id; } - // A NavigationHandle for the pending navigation in this frame, if any. This + // A NavigationRequest for the pending navigation in this frame, if any. This // is cleared when the navigation commits. - NavigationHandleImpl* navigation_handle() const { - return navigation_handle_.get(); - } + NavigationRequest* navigation_request() { return navigation_request_.get(); } - // Called when a new navigation starts in this RenderFrameHost. Ownership of - // |navigation_handle| is transferred. - // PlzNavigate: called when a navigation is ready to commit in this - // RenderFrameHost. - void SetNavigationHandle( - std::unique_ptr<NavigationHandleImpl> navigation_handle); + // Returns the NavigationHandleImpl stored in the NavigationRequest returned + // by GetNavigationRequest(), if any. + NavigationHandleImpl* GetNavigationHandle(); + + // Called when a navigation is ready to commit in this + // RenderFrameHost. Transfers ownership of the NavigationRequest associated + // with the navigation to this RenderFrameHost. + void SetNavigationRequest( + std::unique_ptr<NavigationRequest> navigation_request); // Tells the renderer that this RenderFrame is being swapped out for one in a // different renderer process. It should run its unload handler and move to @@ -1231,12 +1233,9 @@ std::unique_ptr<resource_coordinator::FrameResourceCoordinator> frame_resource_coordinator_; - // Tracks a navigation happening in this frame. Note that while there can be - // two navigations in the same FrameTreeNode, there can only be one - // navigation per RenderFrameHost. - // Before the navigation is ready to be committed, the NavigationHandle for it - // is owned by the NavigationRequest. - std::unique_ptr<NavigationHandleImpl> navigation_handle_; + // Holds a NavigationRequest while waiting for the navigation it is tracking + // to commit. + std::unique_ptr<NavigationRequest> navigation_request_; // The associated WebUIImpl and its type. They will be set if the current // document is from WebUI source. Otherwise they will be null and
diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc index 2a054e4..0faad5d 100644 --- a/content/browser/frame_host/render_frame_host_manager.cc +++ b/content/browser/frame_host/render_frame_host_manager.cc
@@ -372,9 +372,9 @@ CreateRenderFrameProxyHost(old_render_frame_host->GetSiteInstance(), old_render_frame_host->render_view_host()); - // Reset any NavigationHandle in the RenderFrameHost. This will prevent any - // ongoing navigation from attempting to transfer. - old_render_frame_host->SetNavigationHandle(nullptr); + // Reset any NavigationRequest in the RenderFrameHost. A swapped out + // RenderFrameHost should not be trying to commit a navigation. + old_render_frame_host->SetNavigationRequest(nullptr); // Tell the old RenderFrameHost to swap out and be replaced by the proxy. old_render_frame_host->SwapOut(proxy, true); @@ -505,10 +505,10 @@ // navigation was started from BeginNavigation. If the navigation was // started through the NavigationController, the NavigationController has // already updated its state properly, and doesn't need to be notified. - if (speculative_render_frame_host_->navigation_handle() && + if (speculative_render_frame_host_->GetNavigationHandle() && request.from_begin_navigation()) { frame_tree_node_->navigator()->DiscardPendingEntryIfNeeded( - speculative_render_frame_host_->navigation_handle() + speculative_render_frame_host_->GetNavigationHandle() ->pending_nav_entry_id()); } DiscardUnusedFrame(UnsetSpeculativeRenderFrameHost()); @@ -544,10 +544,10 @@ // has already updated its state properly, and doesn't need to be // notified. if (speculative_render_frame_host_ && - speculative_render_frame_host_->navigation_handle() && + speculative_render_frame_host_->GetNavigationHandle() && request.from_begin_navigation()) { frame_tree_node_->navigator()->DiscardPendingEntryIfNeeded( - speculative_render_frame_host_->navigation_handle() + speculative_render_frame_host_->GetNavigationHandle() ->pending_nav_entry_id()); }
diff --git a/content/browser/frame_host/render_widget_host_view_guest.cc b/content/browser/frame_host/render_widget_host_view_guest.cc index d637a49..a8a9262 100644 --- a/content/browser/frame_host/render_widget_host_view_guest.cc +++ b/content/browser/frame_host/render_widget_host_view_guest.cc
@@ -12,7 +12,6 @@ #include "base/logging.h" #include "base/message_loop/message_loop.h" #include "build/build_config.h" -#include "components/viz/common/surfaces/surface_sequence.h" #include "components/viz/service/frame_sinks/frame_sink_manager_impl.h" #include "components/viz/service/surfaces/surface.h" #include "components/viz/service/surfaces/surface_hittest.h" @@ -369,10 +368,9 @@ } void RenderWidgetHostViewGuest::SendSurfaceInfoToEmbedderImpl( - const viz::SurfaceInfo& surface_info, - const viz::SurfaceSequence& sequence) { + const viz::SurfaceInfo& surface_info) { if (guest_ && !guest_->is_in_destruction()) - guest_->SetChildFrameSurface(surface_info, sequence); + guest_->SetChildFrameSurface(surface_info); } void RenderWidgetHostViewGuest::SubmitCompositorFrame(
diff --git a/content/browser/frame_host/render_widget_host_view_guest.h b/content/browser/frame_host/render_widget_host_view_guest.h index d07b130..3d095bf 100644 --- a/content/browser/frame_host/render_widget_host_view_guest.h +++ b/content/browser/frame_host/render_widget_host_view_guest.h
@@ -158,8 +158,7 @@ friend class RenderWidgetHostView; void SendSurfaceInfoToEmbedderImpl( - const viz::SurfaceInfo& surface_info, - const viz::SurfaceSequence& sequence) override; + const viz::SurfaceInfo& surface_info) override; RenderWidgetHostViewGuest( RenderWidgetHost* widget,
diff --git a/content/browser/frame_host/render_widget_host_view_guest_unittest.cc b/content/browser/frame_host/render_widget_host_view_guest_unittest.cc index 02f0ff67..768cdfb 100644 --- a/content/browser/frame_host/render_widget_host_view_guest_unittest.cc +++ b/content/browser/frame_host/render_widget_host_view_guest_unittest.cc
@@ -13,7 +13,6 @@ #include "base/test/scoped_task_environment.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" -#include "components/viz/common/surfaces/surface_sequence.h" #include "components/viz/service/frame_sinks/frame_sink_manager_impl.h" #include "components/viz/service/surfaces/surface.h" #include "components/viz/service/surfaces/surface_manager.h" @@ -124,8 +123,7 @@ BrowserPluginGuest::set_attached_for_test(attached); } - void SetChildFrameSurface(const viz::SurfaceInfo& surface_info, - const viz::SurfaceSequence& sequence) override { + void SetChildFrameSurface(const viz::SurfaceInfo& surface_info) override { last_surface_info_ = surface_info; }
diff --git a/content/browser/network_service_browsertest.cc b/content/browser/network_service_browsertest.cc index ecab3580..a388a96 100644 --- a/content/browser/network_service_browsertest.cc +++ b/content/browser/network_service_browsertest.cc
@@ -190,7 +190,13 @@ }; // Verifies that in-process network service works. -IN_PROC_BROWSER_TEST_F(NetworkServiceInProcessBrowserTest, Basic) { +// http://crbug.com/804204: failed on several dbg builders. +#if !defined(NDEBUG) +#define MAYBE_Basic DISABLED_Basic +#else +#define MAYBE_Basic Basic +#endif +IN_PROC_BROWSER_TEST_F(NetworkServiceInProcessBrowserTest, MAYBE_Basic) { GURL test_url = embedded_test_server()->GetURL("foo.com", "/echo"); StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>( BrowserContext::GetDefaultStoragePartition(
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc index 3cdcc91..5adf3d1 100644 --- a/content/browser/renderer_host/compositor_impl_android.cc +++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -40,7 +40,6 @@ #include "components/viz/common/gpu/vulkan_in_process_context_provider.h" #include "components/viz/common/quads/compositor_frame.h" #include "components/viz/common/surfaces/frame_sink_id_allocator.h" -#include "components/viz/common/switches.h" #include "components/viz/host/host_frame_sink_manager.h" #include "components/viz/service/display/display.h" #include "components/viz/service/display/display_scheduler.h" @@ -97,17 +96,9 @@ struct CompositorDependencies { CompositorDependencies() : frame_sink_id_allocator(kDefaultClientId) { - // TODO(crbug.com/676384): Remove flag along with surface sequences. - auto surface_lifetime_type = - base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kDisableSurfaceReferences) - ? viz::SurfaceManager::LifetimeType::SEQUENCES - : viz::SurfaceManager::LifetimeType::REFERENCES; - // TODO(danakj): Don't make a FrameSinkManagerImpl when display is in the // Gpu process, instead get the mojo pointer from the Gpu process. - frame_sink_manager_impl = - std::make_unique<viz::FrameSinkManagerImpl>(surface_lifetime_type); + frame_sink_manager_impl = std::make_unique<viz::FrameSinkManagerImpl>(); surface_utils::ConnectWithLocalFrameSinkManager( &host_frame_sink_manager, frame_sink_manager_impl.get()); } @@ -632,7 +623,6 @@ params.mutator_host = animation_host_.get(); host_ = cc::LayerTreeHost::CreateSingleThreaded(this, ¶ms); DCHECK(!host_->IsVisible()); - host_->SetFrameSinkId(frame_sink_id_); host_->SetViewportSize(size_); host_->SetDeviceScaleFactor(1);
diff --git a/content/browser/renderer_host/delegated_frame_host.cc b/content/browser/renderer_host/delegated_frame_host.cc index 653f3697..13e21d6 100644 --- a/content/browser/renderer_host/delegated_frame_host.cc +++ b/content/browser/renderer_host/delegated_frame_host.cc
@@ -18,7 +18,6 @@ #include "components/viz/common/gl_helper.h" #include "components/viz/common/quads/compositor_frame.h" #include "components/viz/common/resources/single_release_callback.h" -#include "components/viz/common/surfaces/stub_surface_reference_factory.h" #include "components/viz/common/switches.h" #include "components/viz/host/host_frame_sink_manager.h" #include "components/viz/service/frame_sinks/compositor_frame_sink_support.h" @@ -300,8 +299,7 @@ viz::SurfaceId surface_id(frame_sink_id_, client_->GetLocalSurfaceId()); client_->DelegatedFrameHostGetLayer()->SetShowPrimarySurface( - surface_id, current_frame_size_in_dip_, GetGutterColor(), - GetSurfaceReferenceFactory()); + surface_id, current_frame_size_in_dip_, GetGutterColor()); if (compositor_ && !base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kDisableResizeLock)) { compositor_->OnChildResizing(); @@ -572,8 +570,7 @@ } } else { client_->DelegatedFrameHostGetLayer()->SetShowPrimarySurface( - surface_info.id(), frame_size_in_dip, GetGutterColor(), - GetSurfaceReferenceFactory()); + surface_info.id(), frame_size_in_dip, GetGutterColor()); } client_->DelegatedFrameHostGetLayer()->SetFallbackSurfaceId( @@ -948,12 +945,4 @@ support_.reset(); } -scoped_refptr<viz::SurfaceReferenceFactory> -DelegatedFrameHost::GetSurfaceReferenceFactory() { - if (enable_viz_) - return base::MakeRefCounted<viz::StubSurfaceReferenceFactory>(); - - return GetFrameSinkManager()->surface_manager()->reference_factory(); -} - } // namespace content
diff --git a/content/browser/renderer_host/delegated_frame_host.h b/content/browser/renderer_host/delegated_frame_host.h index dcaabf1..a79724c6 100644 --- a/content/browser/renderer_host/delegated_frame_host.h +++ b/content/browser/renderer_host/delegated_frame_host.h
@@ -273,10 +273,6 @@ void CreateCompositorFrameSinkSupport(); void ResetCompositorFrameSinkSupport(); - // Returns SurfaceReferenceFactory instance. If |enable_viz| is true then it - // will be a stub factory, otherwise it will be the real factory. - scoped_refptr<viz::SurfaceReferenceFactory> GetSurfaceReferenceFactory(); - const viz::FrameSinkId frame_sink_id_; viz::LocalSurfaceId local_surface_id_; DelegatedFrameHostClient* const client_;
diff --git a/content/browser/renderer_host/frame_connector_delegate.h b/content/browser/renderer_host/frame_connector_delegate.h index 03562e8f..eeb8fa8 100644 --- a/content/browser/renderer_host/frame_connector_delegate.h +++ b/content/browser/renderer_host/frame_connector_delegate.h
@@ -23,7 +23,6 @@ namespace viz { class SurfaceId; class SurfaceInfo; -struct SurfaceSequence; } // namespace viz namespace content { @@ -64,8 +63,7 @@ // Provide the SurfaceInfo to the embedder, which becomes a reference to the // current view's Surface that is included in higher-level compositor // frames. - virtual void SetChildFrameSurface(const viz::SurfaceInfo& surface_info, - const viz::SurfaceSequence& sequence) {} + virtual void SetChildFrameSurface(const viz::SurfaceInfo& surface_info) {} // Return the rect in DIP that the RenderWidgetHostViewChildFrame's content // will render into.
diff --git a/content/browser/renderer_host/offscreen_canvas_surface_impl.cc b/content/browser/renderer_host/offscreen_canvas_surface_impl.cc index 3ec2fbb..3174275 100644 --- a/content/browser/renderer_host/offscreen_canvas_surface_impl.cc +++ b/content/browser/renderer_host/offscreen_canvas_surface_impl.cc
@@ -10,7 +10,6 @@ #include "base/memory/ptr_util.h" #include "components/viz/common/features.h" #include "components/viz/host/host_frame_sink_manager.h" -#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h" #include "components/viz/service/surfaces/surface_manager.h" #include "content/browser/compositor/surface_utils.h" @@ -77,29 +76,6 @@ // canvas } -void OffscreenCanvasSurfaceImpl::Require(const viz::SurfaceId& surface_id, - const viz::SurfaceSequence& sequence) { - // TODO(kylechar): This is a hacky workaround for https://crbug.com/796700 - // to unblock video with surfaces work. Delete function M65 branch. - if (base::FeatureList::IsEnabled(features::kVizDisplayCompositor)) - return; - - auto* surface_manager = GetFrameSinkManager()->surface_manager(); - if (!surface_manager->using_surface_references()) - surface_manager->RequireSequence(surface_id, sequence); -} - -void OffscreenCanvasSurfaceImpl::Satisfy(const viz::SurfaceSequence& sequence) { - // TODO(kylechar): This is a hacky workaround for https://crbug.com/796700 - // to unblock video with surfaces work. Delete function after M65 branch. - if (base::FeatureList::IsEnabled(features::kVizDisplayCompositor)) - return; - - auto* surface_manager = GetFrameSinkManager()->surface_manager(); - if (!surface_manager->using_surface_references()) - surface_manager->SatisfySequence(sequence); -} - void OffscreenCanvasSurfaceImpl::OnSurfaceConnectionClosed() { std::move(destroy_callback_).Run(); }
diff --git a/content/browser/renderer_host/offscreen_canvas_surface_impl.h b/content/browser/renderer_host/offscreen_canvas_surface_impl.h index b906ed61..e64b95a 100644 --- a/content/browser/renderer_host/offscreen_canvas_surface_impl.h +++ b/content/browser/renderer_host/offscreen_canvas_surface_impl.h
@@ -56,11 +56,6 @@ void OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info) override; void OnFrameTokenChanged(uint32_t frame_token) override; - // blink::mojom::OffscreenCanvasSurface implementation. - void Require(const viz::SurfaceId& surface_id, - const viz::SurfaceSequence& sequence) override; - void Satisfy(const viz::SurfaceSequence& sequence) override; - private: // Registered as a callback for when |binding_| is closed. Will call // |destroy_callback_|.
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 22c72f3..5af75c5 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -2648,7 +2648,6 @@ cc::switches::kBrowserControlsHideThreshold, cc::switches::kBrowserControlsShowThreshold, cc::switches::kRunAllCompositorStagesBeforeDraw, - switches::kDisableSurfaceReferences, switches::kEnableSurfaceSynchronization, #if BUILDFLAG(ENABLE_PLUGINS)
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc index 9a8a5ec..a8a8e31 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.cc +++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -494,9 +494,8 @@ if (using_browser_compositor_) { viz::FrameSinkId frame_sink_id = host_->AllocateFrameSinkId(false /* is_guest_view_hack */); - delegated_frame_host_.reset(new ui::DelegatedFrameHostAndroid( - &view_, CompositorImpl::GetHostFrameSinkManager(), - CompositorImpl::GetFrameSinkManager(), this, frame_sink_id)); + delegated_frame_host_ = std::make_unique<ui::DelegatedFrameHostAndroid>( + &view_, CompositorImpl::GetHostFrameSinkManager(), this, frame_sink_id); // Let the page-level input event router know about our frame sink ID // for surface-based hit testing.
diff --git a/content/browser/renderer_host/render_widget_host_view_child_frame.cc b/content/browser/renderer_host/render_widget_host_view_child_frame.cc index efab4c1..ad65cd9 100644 --- a/content/browser/renderer_host/render_widget_host_view_child_frame.cc +++ b/content/browser/renderer_host/render_widget_host_view_child_frame.cc
@@ -19,7 +19,6 @@ #include "components/viz/common/frame_sinks/copy_output_result.h" #include "components/viz/host/host_frame_sink_manager.h" #include "components/viz/service/frame_sinks/compositor_frame_sink_support.h" -#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h" #include "components/viz/service/surfaces/surface.h" #include "components/viz/service/surfaces/surface_manager.h" #include "content/browser/accessibility/browser_accessibility_manager.h" @@ -69,7 +68,6 @@ frame_sink_id_( base::checked_cast<uint32_t>(widget_host->GetProcess()->GetID()), base::checked_cast<uint32_t>(widget_host->GetRoutingID())), - next_surface_sequence_(1u), current_surface_scale_factor_(1.f), frame_connector_(nullptr), enable_viz_( @@ -586,26 +584,16 @@ void RenderWidgetHostViewChildFrame::SendSurfaceInfoToEmbedder() { if (switches::IsMusHostingViz()) return; - // TODO(kylechar): Remove sequence generation and only send surface info. - // See https://crbug.com/676384. - viz::SurfaceSequence sequence = - viz::SurfaceSequence(frame_sink_id_, next_surface_sequence_++); - viz::SurfaceManager* manager = GetFrameSinkManager()->surface_manager(); viz::SurfaceId surface_id(frame_sink_id_, last_received_local_surface_id_); - // The renderer process will satisfy this dependency when it creates a - // SurfaceLayer. - if (!manager->using_surface_references()) - manager->RequireSequence(surface_id, sequence); viz::SurfaceInfo surface_info(surface_id, current_surface_scale_factor_, current_surface_size_); - SendSurfaceInfoToEmbedderImpl(surface_info, sequence); + SendSurfaceInfoToEmbedderImpl(surface_info); } void RenderWidgetHostViewChildFrame::SendSurfaceInfoToEmbedderImpl( - const viz::SurfaceInfo& surface_info, - const viz::SurfaceSequence& sequence) { + const viz::SurfaceInfo& surface_info) { if (frame_connector_) - frame_connector_->SetChildFrameSurface(surface_info, sequence); + frame_connector_->SetChildFrameSurface(surface_info); } void RenderWidgetHostViewChildFrame::SubmitCompositorFrame( @@ -906,8 +894,7 @@ void RenderWidgetHostViewChildFrame::OnFirstSurfaceActivation( const viz::SurfaceInfo& surface_info) { - viz::SurfaceSequence sequence(frame_sink_id_, next_surface_sequence_++); - SendSurfaceInfoToEmbedderImpl(surface_info, sequence); + SendSurfaceInfoToEmbedderImpl(surface_info); } void RenderWidgetHostViewChildFrame::OnFrameTokenChanged(uint32_t frame_token) {
diff --git a/content/browser/renderer_host/render_widget_host_view_child_frame.h b/content/browser/renderer_host/render_widget_host_view_child_frame.h index 98bd278..2ca8542 100644 --- a/content/browser/renderer_host/render_widget_host_view_child_frame.h +++ b/content/browser/renderer_host/render_widget_host_view_child_frame.h
@@ -19,7 +19,6 @@ #include "components/viz/common/frame_sinks/begin_frame_source.h" #include "components/viz/common/resources/returned_resource.h" #include "components/viz/common/surfaces/surface_info.h" -#include "components/viz/common/surfaces/surface_sequence.h" #include "components/viz/host/host_frame_sink_client.h" #include "content/browser/compositor/image_transport_factory.h" #include "content/browser/renderer_host/event_with_latency_info.h" @@ -268,7 +267,6 @@ // Surface-related state. std::unique_ptr<viz::CompositorFrameSinkSupport> support_; viz::LocalSurfaceId last_received_local_surface_id_; - uint32_t next_surface_sequence_; gfx::Size current_surface_size_; float current_surface_scale_factor_; gfx::Rect last_screen_rect_; @@ -289,8 +287,7 @@ HiddenOOPIFWillNotGenerateCompositorFramesAfterNavigation); virtual void SendSurfaceInfoToEmbedderImpl( - const viz::SurfaceInfo& surface_info, - const viz::SurfaceSequence& sequence); + const viz::SurfaceInfo& surface_info); void SubmitSurfaceCopyRequest(const gfx::Rect& src_subrect, const gfx::Size& dst_size,
diff --git a/content/browser/renderer_host/render_widget_host_view_child_frame_browsertest.cc b/content/browser/renderer_host/render_widget_host_view_child_frame_browsertest.cc index 802e4a6..865e049 100644 --- a/content/browser/renderer_host/render_widget_host_view_child_frame_browsertest.cc +++ b/content/browser/renderer_host/render_widget_host_view_child_frame_browsertest.cc
@@ -5,7 +5,6 @@ #include "base/macros.h" #include "base/run_loop.h" #include "components/viz/common/surfaces/surface_id.h" -#include "components/viz/common/surfaces/surface_sequence.h" #include "content/browser/frame_host/frame_tree_node.h" #include "content/browser/mus_util.h" #include "content/browser/renderer_host/render_widget_host_view_child_frame.h" @@ -188,94 +187,4 @@ base::Unretained(this))); } -// A class to filter RequireSequence and SatisfySequence messages sent from -// an embedding renderer for its child's Surfaces. -class SurfaceRefMessageFilter : public BrowserMessageFilter { - public: - SurfaceRefMessageFilter() - : BrowserMessageFilter(FrameMsgStart), - require_message_loop_runner_(new content::MessageLoopRunner), - satisfy_message_loop_runner_(new content::MessageLoopRunner), - satisfy_received_(false), - require_received_first_(false) {} - - void WaitForRequire() { require_message_loop_runner_->Run(); } - - void WaitForSatisfy() { satisfy_message_loop_runner_->Run(); } - - bool require_received_first() { return require_received_first_; } - - protected: - ~SurfaceRefMessageFilter() override {} - - private: - // BrowserMessageFilter: - bool OnMessageReceived(const IPC::Message& message) override { - IPC_BEGIN_MESSAGE_MAP(SurfaceRefMessageFilter, message) - IPC_MESSAGE_HANDLER(FrameHostMsg_RequireSequence, OnRequire) - IPC_MESSAGE_HANDLER(FrameHostMsg_SatisfySequence, OnSatisfy) - IPC_END_MESSAGE_MAP() - return false; - } - - void OnRequire(const viz::SurfaceId& id, - const viz::SurfaceSequence sequence) { - content::BrowserThread::PostTask( - content::BrowserThread::UI, FROM_HERE, - base::BindOnce(&SurfaceRefMessageFilter::OnRequireOnUI, this)); - } - - void OnRequireOnUI() { - if (!satisfy_received_) - require_received_first_ = true; - require_message_loop_runner_->Quit(); - } - - void OnSatisfy(const viz::SurfaceSequence sequence) { - content::BrowserThread::PostTask( - content::BrowserThread::UI, FROM_HERE, - base::BindOnce(&SurfaceRefMessageFilter::OnSatisfyOnUI, this)); - } - - void OnSatisfyOnUI() { - satisfy_received_ = true; - satisfy_message_loop_runner_->Quit(); - } - - scoped_refptr<content::MessageLoopRunner> require_message_loop_runner_; - scoped_refptr<content::MessageLoopRunner> satisfy_message_loop_runner_; - bool satisfy_received_; - bool require_received_first_; - - DISALLOW_COPY_AND_ASSIGN(SurfaceRefMessageFilter); -}; - -// Test that when a child frame submits its first compositor frame, the -// embedding renderer process properly acquires and releases references to the -// new Surface. See https://crbug.com/701175. -// TODO(crbug.com/676384): Delete test with the rest of SurfaceSequence code. -IN_PROC_BROWSER_TEST_F(RenderWidgetHostViewChildFrameTest, - DISABLED_ChildFrameSurfaceReference) { - EXPECT_TRUE(NavigateToURL( - shell(), embedded_test_server()->GetURL( - "a.com", "/cross_site_iframe_factory.html?a(a)"))); - - FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) - ->GetFrameTree() - ->root(); - ASSERT_EQ(1U, root->child_count()); - - scoped_refptr<SurfaceRefMessageFilter> filter = new SurfaceRefMessageFilter(); - root->current_frame_host()->GetProcess()->AddFilter(filter.get()); - - GURL foo_url = embedded_test_server()->GetURL("foo.com", "/title1.html"); - NavigateFrameToURL(root->child_at(0), foo_url); - - // If one of these messages isn't received, this test times out. - filter->WaitForRequire(); - filter->WaitForSatisfy(); - - EXPECT_TRUE(filter->require_received_first()); -} - } // namespace content
diff --git a/content/browser/renderer_host/render_widget_host_view_child_frame_unittest.cc b/content/browser/renderer_host/render_widget_host_view_child_frame_unittest.cc index 4a48803..fe813324 100644 --- a/content/browser/renderer_host/render_widget_host_view_child_frame_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_view_child_frame_unittest.cc
@@ -16,7 +16,6 @@ #include "base/test/scoped_task_environment.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" -#include "components/viz/common/surfaces/surface_sequence.h" #include "components/viz/service/frame_sinks/compositor_frame_sink_support.h" #include "components/viz/service/frame_sinks/frame_sink_manager_impl.h" #include "components/viz/service/surfaces/surface.h" @@ -55,8 +54,7 @@ : FrameConnectorDelegate(use_zoom_for_device_scale_factor) {} ~MockFrameConnectorDelegate() override {} - void SetChildFrameSurface(const viz::SurfaceInfo& surface_info, - const viz::SurfaceSequence& sequence) override { + void SetChildFrameSurface(const viz::SurfaceInfo& surface_info) override { last_surface_info_ = surface_info; }
diff --git a/content/browser/resources/media/peer_connection_update_table.js b/content/browser/resources/media/peer_connection_update_table.js index d6795d5..208d11f 100644 --- a/content/browser/resources/media/peer_connection_update_table.js +++ b/content/browser/resources/media/peer_connection_update_table.js
@@ -122,6 +122,14 @@ update.type === 'addIceCandidateFailed') { valueContainer.parentElement.classList.add('update-log-failure'); } + // Highlight legacy streams API usage. + if (update.type === 'addStream' || update.type === 'removeStream') { + valueContainer.parentElement.classList.add( + 'update-log-legacy-api-usage'); + valueContainer.parentElement.title = update.type + ' is no longer ' + + 'part of the WebRTC API and may be removed in future versions. ' + + 'Use the addTrack/removeTrack APIs instead.' + } var value = update.value; // map internal names and values to names and events from the
diff --git a/content/browser/resources/media/webrtc_internals.css b/content/browser/resources/media/webrtc_internals.css index b8111e19..349c8c2 100644 --- a/content/browser/resources/media/webrtc_internals.css +++ b/content/browser/resources/media/webrtc_internals.css
@@ -18,6 +18,10 @@ background-color: #be2026; } +.update-log-legacy-api-usage { + background-color: #fed14b; +} + .ssrc-info-block { color: #999; font-size: 0.8em;
diff --git a/content/browser/service_worker/service_worker_context_wrapper.cc b/content/browser/service_worker/service_worker_context_wrapper.cc index e1b72f8..706b9510 100644 --- a/content/browser/service_worker/service_worker_context_wrapper.cc +++ b/content/browser/service_worker/service_worker_context_wrapper.cc
@@ -80,7 +80,7 @@ registration->ActivateWaitingVersionWhenReady(); } -void DidStartWorker( +void DidStartActiveWorker( scoped_refptr<ServiceWorkerVersion> version, ServiceWorkerContext::StartActiveWorkerCallback info_callback, base::OnceClosure error_callback, @@ -101,14 +101,15 @@ DCHECK_CURRENTLY_ON(BrowserThread::IO); if (service_worker_status == SERVICE_WORKER_OK) { // Note: There might be a remote possibility that - // |service_worker_registration|'s active version might change between here - // and DidStartWorker, so bind |active_version| to RunAfterStartWorker. + // |service_worker_registration|'s active version might change + // between here and DidStartActiveWorker, so + // bind |active_version| to RunAfterStartWorker. scoped_refptr<ServiceWorkerVersion> active_version = service_worker_registration->active_version(); DCHECK(active_version.get()); active_version->RunAfterStartWorker( ServiceWorkerMetrics::EventType::EXTERNAL_REQUEST, - base::BindOnce(&DidStartWorker, active_version, + base::BindOnce(&DidStartActiveWorker, active_version, std::move(info_callback), std::move(failure_callback))); } else { std::move(failure_callback).Run();
diff --git a/content/browser/service_worker/service_worker_dispatcher_host.cc b/content/browser/service_worker/service_worker_dispatcher_host.cc index 75c486c..acaade25 100644 --- a/content/browser/service_worker/service_worker_dispatcher_host.cc +++ b/content/browser/service_worker/service_worker_dispatcher_host.cc
@@ -167,10 +167,6 @@ IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_PostMessageToWorker, OnPostMessageToWorker) IPC_MESSAGE_HANDLER(EmbeddedWorkerHostMsg_CountFeature, OnCountFeature) - IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_IncrementServiceWorkerRefCount, - OnIncrementServiceWorkerRefCount) - IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount, - OnDecrementServiceWorkerRefCount) IPC_MESSAGE_HANDLER(ServiceWorkerHostMsg_TerminateWorker, OnTerminateWorker) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() @@ -219,6 +215,10 @@ return nullptr; } +void ServiceWorkerDispatcherHost::UnregisterServiceWorkerHandle(int handle_id) { + handles_.Remove(handle_id); +} + base::WeakPtr<ServiceWorkerDispatcherHost> ServiceWorkerDispatcherHost::AsWeakPtr() { return weak_ptr_factory_.GetWeakPtr(); @@ -376,7 +376,6 @@ // If not enough time is left to actually process the event don't even // bother starting the worker and sending the event. if (timeout && *timeout < base::TimeDelta::FromMilliseconds(100)) { - ReleaseSourceInfo(std::move(source_info)); std::move(callback).Run(SERVICE_WORKER_ERROR_TIMEOUT); return; } @@ -403,7 +402,6 @@ ServiceWorkerStatusCode start_worker_status) { DCHECK(IsValidSourceInfo(source_info)); if (start_worker_status != SERVICE_WORKER_OK) { - ReleaseSourceInfo(std::move(source_info)); std::move(callback).Run(start_worker_status); return; } @@ -428,21 +426,6 @@ std::move(event), worker->CreateSimpleEventCallback(request_id)); } -void ServiceWorkerDispatcherHost::ReleaseSourceInfo( - blink::mojom::ServiceWorkerClientInfoPtr source_info) { - // ServiceWorkerClientInfo is just a snapshot of the client. There is no need - // to do anything for it. -} - -void ServiceWorkerDispatcherHost::ReleaseSourceInfo( - blink::mojom::ServiceWorkerObjectInfoPtr source_info) { - ServiceWorkerHandle* handle = handles_.Lookup(source_info->handle_id); - DCHECK(handle); - handle->DecrementRefCount(); - if (handle->HasNoRefCount()) - handles_.Remove(source_info->handle_id); -} - void ServiceWorkerDispatcherHost::OnCountFeature(int64_t version_id, uint32_t feature) { if (!GetContext()) @@ -461,34 +444,6 @@ version->CountFeature(feature); } -void ServiceWorkerDispatcherHost::OnIncrementServiceWorkerRefCount( - int handle_id) { - TRACE_EVENT0("ServiceWorker", - "ServiceWorkerDispatcherHost::OnIncrementServiceWorkerRefCount"); - ServiceWorkerHandle* handle = handles_.Lookup(handle_id); - if (!handle) { - bad_message::ReceivedBadMessage( - this, bad_message::SWDH_INCREMENT_WORKER_BAD_HANDLE); - return; - } - handle->IncrementRefCount(); -} - -void ServiceWorkerDispatcherHost::OnDecrementServiceWorkerRefCount( - int handle_id) { - TRACE_EVENT0("ServiceWorker", - "ServiceWorkerDispatcherHost::OnDecrementServiceWorkerRefCount"); - ServiceWorkerHandle* handle = handles_.Lookup(handle_id); - if (!handle) { - bad_message::ReceivedBadMessage( - this, bad_message::SWDH_DECREMENT_WORKER_BAD_HANDLE); - return; - } - handle->DecrementRefCount(); - if (handle->HasNoRefCount()) - handles_.Remove(handle_id); -} - ServiceWorkerContextCore* ServiceWorkerDispatcherHost::GetContext() { // Temporary CHECK for debugging https://crbug.com/736203. CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
diff --git a/content/browser/service_worker/service_worker_dispatcher_host.h b/content/browser/service_worker/service_worker_dispatcher_host.h index be37ba7..3bf52e4 100644 --- a/content/browser/service_worker/service_worker_dispatcher_host.h +++ b/content/browser/service_worker/service_worker_dispatcher_host.h
@@ -98,9 +98,10 @@ // be destroyed. bool Send(IPC::Message* message) override; - // This method is virtual only for testing. + // These methods are virtual only for testing. virtual void RegisterServiceWorkerHandle( std::unique_ptr<ServiceWorkerHandle> handle); + virtual void UnregisterServiceWorkerHandle(int handle_id); ServiceWorkerHandle* FindServiceWorkerHandle(int provider_id, int64_t version_id); @@ -140,8 +141,6 @@ // IPC Message handlers void OnCountFeature(int64_t version_id, uint32_t feature); - void OnIncrementServiceWorkerRefCount(int handle_id); - void OnDecrementServiceWorkerRefCount(int handle_id); void OnPostMessageToWorker( int handle_id, int provider_id, @@ -177,8 +176,6 @@ const base::Optional<base::TimeDelta>& timeout, StatusCallback callback, ServiceWorkerStatusCode status); - void ReleaseSourceInfo(blink::mojom::ServiceWorkerClientInfoPtr source_info); - void ReleaseSourceInfo(blink::mojom::ServiceWorkerObjectInfoPtr source_info); ServiceWorkerContextCore* GetContext();
diff --git a/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc b/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc index f91b99a..efe17a1c 100644 --- a/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc +++ b/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc
@@ -392,12 +392,13 @@ // worker object information for the source attribute of the message event. provider_host_->running_hosted_version_ = version_; - // Set aside the initial refcount of the worker handle. - provider_host_->GetOrCreateServiceWorkerHandle(version_.get()); + // |info| keeps the 1st reference to |sender_worker_handle|. + blink::mojom::ServiceWorkerObjectInfoPtr info = + provider_host_->GetOrCreateServiceWorkerHandle(version_.get()); ServiceWorkerHandle* sender_worker_handle = dispatcher_host_->FindServiceWorkerHandle(provider_host_->provider_id(), version_->version_id()); - const int ref_count = sender_worker_handle->ref_count(); + EXPECT_EQ(1u, sender_worker_handle->bindings_.size()); // Set mock clock on version_ to check timeout behavior. tick_clock_.SetNowTicks(base::TimeTicks::Now()); @@ -430,12 +431,17 @@ version_, base::string16(), url::Origin::Create(version_->scope().GetOrigin()), ports, provider_host_, base::BindOnce(&SaveStatusCallback, &called, &status)); - EXPECT_EQ(ref_count + 1, sender_worker_handle->ref_count()); + // The 2nd reference to |sender_worker_handle| has been passed via the above + // dispatch of ExtendableMessageEvent. + EXPECT_EQ(2u, sender_worker_handle->bindings_.size()); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(called); EXPECT_EQ(SERVICE_WORKER_OK, status); - EXPECT_EQ(ref_count + 1, sender_worker_handle->ref_count()); + // The remote handler of ExtendableMessageEvent has released the reference to + // |service_worker_handle|, please see impl of + // EmbeddedWorkerTestHelper::OnExtendableMessageEvent() for details. + EXPECT_EQ(1u, sender_worker_handle->bindings_.size()); // Timeout of message event should not have extended life of service worker. EXPECT_EQ(remaining_time, version_->remaining_timeout());
diff --git a/content/browser/service_worker/service_worker_handle.cc b/content/browser/service_worker/service_worker_handle.cc index 8be8695..40003a3 100644 --- a/content/browser/service_worker/service_worker_handle.cc +++ b/content/browser/service_worker/service_worker_handle.cc
@@ -6,49 +6,49 @@ #include "base/memory/ptr_util.h" #include "content/browser/service_worker/service_worker_context_core.h" +#include "content/browser/service_worker/service_worker_dispatcher_host.h" #include "content/browser/service_worker/service_worker_registration.h" #include "content/browser/service_worker/service_worker_type_converters.h" #include "content/common/service_worker/service_worker_messages.h" #include "content/common/service_worker/service_worker_types.h" +#include "content/common/service_worker/service_worker_utils.h" #include "content/public/common/service_worker_modes.h" namespace content { -std::unique_ptr<ServiceWorkerHandle> ServiceWorkerHandle::Create( - base::WeakPtr<ServiceWorkerContextCore> context, - base::WeakPtr<ServiceWorkerProviderHost> provider_host, - ServiceWorkerVersion* version) { - const int handle_id = context.get() - ? context->GetNewServiceWorkerHandleId() - : blink::mojom::kInvalidServiceWorkerHandleId; - return CreateWithID(context, provider_host, version, handle_id); -} - -std::unique_ptr<ServiceWorkerHandle> ServiceWorkerHandle::CreateWithID( +// static +base::WeakPtr<ServiceWorkerHandle> ServiceWorkerHandle::Create( + ServiceWorkerDispatcherHost* dispatcher_host, base::WeakPtr<ServiceWorkerContextCore> context, base::WeakPtr<ServiceWorkerProviderHost> provider_host, ServiceWorkerVersion* version, - int handle_id) { - if (!context || !provider_host || !version) - return std::unique_ptr<ServiceWorkerHandle>(); - DCHECK(context->GetLiveRegistration(version->registration_id())); - return base::WrapUnique( - new ServiceWorkerHandle(context, provider_host, version, handle_id)); + blink::mojom::ServiceWorkerObjectInfoPtr* out_info) { + DCHECK(context && provider_host && version && out_info); + ServiceWorkerHandle* handle = + new ServiceWorkerHandle(dispatcher_host, context, provider_host, version); + *out_info = handle->CreateObjectInfo(); + return handle->AsWeakPtr(); } ServiceWorkerHandle::ServiceWorkerHandle( + ServiceWorkerDispatcherHost* dispatcher_host, base::WeakPtr<ServiceWorkerContextCore> context, base::WeakPtr<ServiceWorkerProviderHost> provider_host, - ServiceWorkerVersion* version, - int handle_id) - : context_(context), + ServiceWorkerVersion* version) + : dispatcher_host_(dispatcher_host), + context_(context), provider_host_(provider_host), - provider_id_(provider_host ? provider_host->provider_id() - : kInvalidServiceWorkerProviderId), - handle_id_(handle_id), - ref_count_(1), - version_(version) { + provider_id_(provider_host->provider_id()), + handle_id_(context->GetNewServiceWorkerHandleId()), + version_(version), + weak_ptr_factory_(this) { + DCHECK(context_ && provider_host_ && version_); + DCHECK(context_->GetLiveRegistration(version_->registration_id())); version_->AddListener(this); + bindings_.set_connection_error_handler(base::BindRepeating( + &ServiceWorkerHandle::OnConnectionError, base::Unretained(this))); + if (dispatcher_host_) + dispatcher_host_->RegisterServiceWorkerHandle(base::WrapUnique(this)); } ServiceWorkerHandle::~ServiceWorkerHandle() { @@ -72,17 +72,35 @@ info->state = mojo::ConvertTo<blink::mojom::ServiceWorkerState>(version_->status()); info->version_id = version_->version_id(); + bindings_.AddBinding(this, mojo::MakeRequest(&info->host_ptr_info)); return info; } -void ServiceWorkerHandle::IncrementRefCount() { - DCHECK_GT(ref_count_, 0); - ++ref_count_; +void ServiceWorkerHandle::RegisterIntoDispatcherHost( + ServiceWorkerDispatcherHost* dispatcher_host) { + DCHECK(ServiceWorkerUtils::IsServicificationEnabled()); + DCHECK(!dispatcher_host_); + dispatcher_host_ = dispatcher_host; + dispatcher_host_->RegisterServiceWorkerHandle(base::WrapUnique(this)); } -void ServiceWorkerHandle::DecrementRefCount() { - DCHECK_GE(ref_count_, 0); - --ref_count_; +base::WeakPtr<ServiceWorkerHandle> ServiceWorkerHandle::AsWeakPtr() { + return weak_ptr_factory_.GetWeakPtr(); +} + +void ServiceWorkerHandle::OnConnectionError() { + // If there are still bindings, |this| is still being used. + if (!bindings_.empty()) + return; + // S13nServiceWorker: This handle may have been precreated before registering + // to a dispatcher host. Just self-destruct since we're no longer needed. + if (!dispatcher_host_) { + DCHECK(ServiceWorkerUtils::IsServicificationEnabled()); + delete this; + return; + } + // Will destroy |this|. + dispatcher_host_->UnregisterServiceWorkerHandle(handle_id_); } } // namespace content
diff --git a/content/browser/service_worker/service_worker_handle.h b/content/browser/service_worker/service_worker_handle.h index 015935df..8d7d809 100644 --- a/content/browser/service_worker/service_worker_handle.h +++ b/content/browser/service_worker/service_worker_handle.h
@@ -13,63 +13,90 @@ #include "content/browser/service_worker/service_worker_version.h" #include "content/common/content_export.h" #include "content/common/service_worker/service_worker_types.h" +#include "mojo/public/cpp/bindings/associated_binding_set.h" +#include "third_party/WebKit/common/service_worker/service_worker_object.mojom.h" namespace content { class ServiceWorkerContextCore; +class ServiceWorkerDispatcherHost; + +namespace service_worker_dispatcher_host_unittest { +FORWARD_DECLARE_TEST(ServiceWorkerDispatcherHostTest, + DispatchExtendableMessageEvent); +} // namespace service_worker_dispatcher_host_unittest // Roughly corresponds to one WebServiceWorker object in the renderer process. // -// The renderer process maintains the reference count by owning a -// ServiceWorkerHandleReference for each reference it has to the service worker -// object. ServiceWorkerHandleReference creation and destruction sends an IPC to -// the browser process, which adjusts the ServiceWorkerHandle refcount. +// The WebServiceWorker object in the renderer process maintains a reference to +// |this| by owning an associated interface pointer to +// blink::mojom::ServiceWorkerObjectHost. // // Has references to the corresponding ServiceWorkerVersion in order to ensure // that the version is alive while this handle is around. class CONTENT_EXPORT ServiceWorkerHandle - : public ServiceWorkerVersion::Listener { + : public blink::mojom::ServiceWorkerObjectHost, + public ServiceWorkerVersion::Listener { public: - // Creates a handle for a live version. This may return nullptr if any of - // |context|, |provider_host| and |version| is nullptr. - static std::unique_ptr<ServiceWorkerHandle> Create( - base::WeakPtr<ServiceWorkerContextCore> context, - base::WeakPtr<ServiceWorkerProviderHost> provider_host, - ServiceWorkerVersion* version); - // Does the same, but with a specific |handle_id|. - static std::unique_ptr<ServiceWorkerHandle> CreateWithID( + // Creates a newly created instance for a live version. |out_info| holds the + // first ServiceWorkerObjectHost Mojo connection to this instance, which will + // delete itself once it detects that all the Mojo connections have gone + // away. + // + // This instance registers itself into |dispatcher_host| to be owned by the + // dispatcher host. S13nServiceWorker: |dispatcher_host| may be null. + // RegisterIntoDispatcherHost() should be called later to register the handle + // once the host is known. + static base::WeakPtr<ServiceWorkerHandle> Create( + ServiceWorkerDispatcherHost* dispatcher_host, base::WeakPtr<ServiceWorkerContextCore> context, base::WeakPtr<ServiceWorkerProviderHost> provider_host, ServiceWorkerVersion* version, - int handle_id); + blink::mojom::ServiceWorkerObjectInfoPtr* out_info); - ServiceWorkerHandle(base::WeakPtr<ServiceWorkerContextCore> context, - base::WeakPtr<ServiceWorkerProviderHost> provider_host, - ServiceWorkerVersion* version, - int handle_id); ~ServiceWorkerHandle() override; // ServiceWorkerVersion::Listener overrides. void OnVersionStateChanged(ServiceWorkerVersion* version) override; + // Establishes a new mojo connection into |bindings_|. blink::mojom::ServiceWorkerObjectInfoPtr CreateObjectInfo(); + // Should only be called on a ServiceWorkerHandle instance constructed with + // null |dispatcher_host| before. + void RegisterIntoDispatcherHost(ServiceWorkerDispatcherHost* dispatcher_host); + int provider_id() const { return provider_id_; } int handle_id() const { return handle_id_; } ServiceWorkerVersion* version() { return version_.get(); } - int ref_count() const { return ref_count_; } - bool HasNoRefCount() const { return ref_count_ <= 0; } - void IncrementRefCount(); - void DecrementRefCount(); - private: + FRIEND_TEST_ALL_PREFIXES( + service_worker_dispatcher_host_unittest::ServiceWorkerDispatcherHostTest, + DispatchExtendableMessageEvent); + + ServiceWorkerHandle(ServiceWorkerDispatcherHost* dispatcher_host, + base::WeakPtr<ServiceWorkerContextCore> context, + base::WeakPtr<ServiceWorkerProviderHost> provider_host, + ServiceWorkerVersion* version); + + base::WeakPtr<ServiceWorkerHandle> AsWeakPtr(); + + void OnConnectionError(); + + // |dispatcher_host_| may get a valid value via ctor or + // RegisterIntoDispatcherHost() function, after that |dispatcher_host_| starts + // to own |this|, then, |dispatcher_host_| is valid throughout the lifetime of + // |this|. + ServiceWorkerDispatcherHost* dispatcher_host_; base::WeakPtr<ServiceWorkerContextCore> context_; base::WeakPtr<ServiceWorkerProviderHost> provider_host_; const int provider_id_; const int handle_id_; - int ref_count_; // Created with 1. scoped_refptr<ServiceWorkerVersion> version_; + mojo::AssociatedBindingSet<blink::mojom::ServiceWorkerObjectHost> bindings_; + + base::WeakPtrFactory<ServiceWorkerHandle> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(ServiceWorkerHandle); };
diff --git a/content/browser/service_worker/service_worker_handle_unittest.cc b/content/browser/service_worker/service_worker_handle_unittest.cc index 9e639a8..c984e62 100644 --- a/content/browser/service_worker/service_worker_handle_unittest.cc +++ b/content/browser/service_worker/service_worker_handle_unittest.cc
@@ -138,9 +138,12 @@ }; TEST_F(ServiceWorkerHandleTest, OnVersionStateChanged) { - std::unique_ptr<ServiceWorkerHandle> handle = - ServiceWorkerHandle::Create(helper_->context()->AsWeakPtr(), - provider_host_->AsWeakPtr(), version_.get()); + blink::mojom::ServiceWorkerObjectInfoPtr info; + // ServiceWorkerHandle lifetime is controlled by |info| and is also owned by + // |dispatcher_host_|. + auto handle = ServiceWorkerHandle::Create( + dispatcher_host_.get(), helper_->context()->AsWeakPtr(), + provider_host_->AsWeakPtr(), version_.get(), &info); // Start the worker, and then... ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_FAILED;
diff --git a/content/browser/service_worker/service_worker_job_unittest.cc b/content/browser/service_worker/service_worker_job_unittest.cc index d9b1d59..f2f57f4 100644 --- a/content/browser/service_worker/service_worker_job_unittest.cc +++ b/content/browser/service_worker/service_worker_job_unittest.cc
@@ -63,6 +63,16 @@ handles_.push_back(std::move(handle)); } + void UnregisterServiceWorkerHandle(int handle_id) override { + auto iter = handles_.begin(); + for (; iter != handles_.end(); ++iter) { + if ((*iter)->handle_id() == handle_id) + break; + } + ASSERT_NE(handles_.end(), iter); + handles_.erase(iter); + } + void Clear() { handles_.clear(); }
diff --git a/content/browser/service_worker/service_worker_provider_host.cc b/content/browser/service_worker/service_worker_provider_host.cc index 9e688a8..627c1cc 100644 --- a/content/browser/service_worker/service_worker_provider_host.cc +++ b/content/browser/service_worker/service_worker_provider_host.cc
@@ -21,7 +21,6 @@ #include "content/browser/service_worker/service_worker_context_request_handler.h" #include "content/browser/service_worker/service_worker_controllee_request_handler.h" #include "content/browser/service_worker/service_worker_dispatcher_host.h" -#include "content/browser/service_worker/service_worker_handle.h" #include "content/browser/service_worker/service_worker_registration_object_host.h" #include "content/browser/service_worker/service_worker_script_url_loader_factory.h" #include "content/browser/service_worker/service_worker_type_converters.h" @@ -510,28 +509,27 @@ if (!context_ || !version) return blink::mojom::ServiceWorkerObjectInfo::New(); if (!dispatcher_host_) { + DCHECK(ServiceWorkerUtils::IsServicificationEnabled()); + blink::mojom::ServiceWorkerObjectInfoPtr info; // This is called before the dispatcher host is created. - auto info = blink::mojom::ServiceWorkerObjectInfo::New(); - info->handle_id = context_->GetNewServiceWorkerHandleId(); - info->url = version->script_url(); - info->state = - mojo::ConvertTo<blink::mojom::ServiceWorkerState>(version->status()); - info->version_id = version->version_id(); - precreated_controller_handle_id_ = info->handle_id; + // |precreated_controller_handle_| instance's lifetime is controlled by its + // own internal Mojo connections via |info|. + precreated_controller_handle_ = ServiceWorkerHandle::Create( + nullptr, context_, AsWeakPtr(), version, &info); return info; } ServiceWorkerHandle* handle = dispatcher_host_->FindServiceWorkerHandle( provider_id(), version->version_id()); if (handle) { - handle->IncrementRefCount(); return handle->CreateObjectInfo(); } - std::unique_ptr<ServiceWorkerHandle> new_handle( - ServiceWorkerHandle::Create(context_, AsWeakPtr(), version)); - handle = new_handle.get(); - dispatcher_host_->RegisterServiceWorkerHandle(std::move(new_handle)); - return handle->CreateObjectInfo(); + blink::mojom::ServiceWorkerObjectInfoPtr info; + // ServiceWorkerHandle lifetime is controlled by |info| and is also owned by + // |dispatcher_host_|. + ServiceWorkerHandle::Create(dispatcher_host_.get(), context_, AsWeakPtr(), + version, &info); + return info; } bool ServiceWorkerProviderHost::CanAssociateRegistration( @@ -613,16 +611,15 @@ if (!controller_) return; - if (ServiceWorkerUtils::IsServicificationEnabled()) { - // S13nServiceWorker: register the controller service worker with the - // pre-created handle ID. + if (ServiceWorkerUtils::IsServicificationEnabled() && + precreated_controller_handle_) { + // S13nServiceWorker: register the pre-created handle for the controller + // service worker with the dispatcher host, now that it exists. DCHECK_NE(blink::mojom::kInvalidServiceWorkerHandleId, - precreated_controller_handle_id_); - std::unique_ptr<ServiceWorkerHandle> new_handle( - ServiceWorkerHandle::CreateWithID(context_, AsWeakPtr(), - controller_.get(), - precreated_controller_handle_id_)); - dispatcher_host_->RegisterServiceWorkerHandle(std::move(new_handle)); + precreated_controller_handle_->handle_id()); + precreated_controller_handle_->RegisterIntoDispatcherHost( + dispatcher_host_.get()); + precreated_controller_handle_ = nullptr; } // In S13nServiceWorker case the controller is already sent in navigation
diff --git a/content/browser/service_worker/service_worker_provider_host.h b/content/browser/service_worker/service_worker_provider_host.h index c976257..227f55b3 100644 --- a/content/browser/service_worker/service_worker_provider_host.h +++ b/content/browser/service_worker/service_worker_provider_host.h
@@ -19,6 +19,7 @@ #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "base/time/time.h" +#include "content/browser/service_worker/service_worker_handle.h" #include "content/browser/service_worker/service_worker_registration.h" #include "content/common/content_export.h" #include "content/common/service_worker/service_worker_container.mojom.h" @@ -275,11 +276,10 @@ scoped_refptr<network::ResourceRequestBody> body, bool skip_service_worker); - // Used to get a ServiceWorkerObjectInfo to send to the renderer. Finds an - // existing ServiceWorkerHandle, and increments its reference count, or else - // creates a new one (initialized to ref count 1). Returns the - // ServiceWorkerObjectInfo from the handle. The renderer is expected to use - // ServiceWorkerHandleReference::Adopt to balance out the ref count. + // Used to get a ServiceWorkerObjectInfo to send to the renderer. + // The object info holds a Mojo connection to the ServiceWorkerHandle for the + // |version| to ensure the handle stays alive while the object info is alive. + // A new handle is created if one does not already exist. blink::mojom::ServiceWorkerObjectInfoPtr GetOrCreateServiceWorkerHandle( ServiceWorkerVersion* version); @@ -584,11 +584,10 @@ std::vector<base::Closure> queued_events_; // S13nServiceWorker: - // A service worker handle ID for the controller service worker that is + // A service worker handle for the controller service worker that is // pre-created before the renderer process (and therefore the dispatcher host) // is created. - int precreated_controller_handle_id_ = - blink::mojom::kInvalidServiceWorkerHandleId; + base::WeakPtr<ServiceWorkerHandle> precreated_controller_handle_; // For provider hosts that are hosting a running service worker. mojo::Binding<service_manager::mojom::InterfaceProvider>
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 3484edd..f66501cb 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -52,6 +52,7 @@ #include "content/browser/frame_host/interstitial_page_impl.h" #include "content/browser/frame_host/navigation_entry_impl.h" #include "content/browser/frame_host/navigation_handle_impl.h" +#include "content/browser/frame_host/navigation_request.h" #include "content/browser/frame_host/navigator_impl.h" #include "content/browser/frame_host/render_frame_host_impl.h" #include "content/browser/frame_host/render_frame_proxy_host.h" @@ -645,18 +646,15 @@ RenderFrameHostManager* root = GetRenderManager(); root->current_frame_host()->SetRenderFrameCreated(false); - root->current_frame_host()->SetNavigationHandle( - std::unique_ptr<NavigationHandleImpl>()); + root->current_frame_host()->SetNavigationRequest( + std::unique_ptr<NavigationRequest>()); - // PlzNavigate: clear up state specific to browser-side navigation. - if (IsBrowserSideNavigationEnabled()) { - // Do not update state as the WebContents is being destroyed. - frame_tree_.root()->ResetNavigationRequest(true, true); - if (root->speculative_frame_host()) { - root->speculative_frame_host()->SetRenderFrameCreated(false); - root->speculative_frame_host()->SetNavigationHandle( - std::unique_ptr<NavigationHandleImpl>()); - } + // Do not update state as the WebContents is being destroyed. + frame_tree_.root()->ResetNavigationRequest(true, true); + if (root->speculative_frame_host()) { + root->speculative_frame_host()->SetRenderFrameCreated(false); + root->speculative_frame_host()->SetNavigationRequest( + std::unique_ptr<NavigationRequest>()); } #if BUILDFLAG(ENABLE_PLUGINS)
diff --git a/content/browser/webrtc/webrtc_event_log_manager.cc b/content/browser/webrtc/webrtc_event_log_manager.cc index fa424b99..023577f 100644 --- a/content/browser/webrtc/webrtc_event_log_manager.cc +++ b/content/browser/webrtc/webrtc_event_log_manager.cc
@@ -11,6 +11,30 @@ namespace content { +namespace { +class PeerConnectionTrackerProxyImpl + : public WebRtcEventLogManager::PeerConnectionTrackerProxy { + public: + ~PeerConnectionTrackerProxyImpl() override = default; + + void StartEventLogOutput(WebRtcEventLogPeerConnectionKey key) override { + RenderProcessHost* host = RenderProcessHost::FromID(key.render_process_id); + if (!host) { + return; // The host has been asynchronously removed; not a problem. + } + host->Send(new PeerConnectionTracker_StartEventLogOutput(key.lid)); + } + + void StopEventLogOutput(WebRtcEventLogPeerConnectionKey key) override { + RenderProcessHost* host = RenderProcessHost::FromID(key.render_process_id); + if (!host) { + return; // The host has been asynchronously removed; not a problem. + } + host->Send(new PeerConnectionTracker_StopEventLog(key.lid)); + } +}; +} // namespace + const size_t kWebRtcEventLogManagerUnlimitedFileSize = 0; WebRtcEventLogManager* WebRtcEventLogManager::g_webrtc_event_log_manager = @@ -29,6 +53,7 @@ WebRtcEventLogManager::WebRtcEventLogManager() : local_logs_observer_(nullptr), local_logs_manager_(this), + pc_tracker_proxy_(new PeerConnectionTrackerProxyImpl), task_runner_(base::CreateSequencedTaskRunnerWithTraits( {base::MayBlock(), base::TaskPriority::BACKGROUND, base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})) { @@ -245,26 +270,25 @@ void WebRtcEventLogManager::UpdateWebRtcEventLoggingState( PeerConnectionKey peer_connection, bool enabled) { - // TODO(eladalon): Add unit tests that would make sure that we really - // instruct WebRTC to start/stop event logs. https://crbug.com/775415 DCHECK_CURRENTLY_ON(BrowserThread::UI); - RenderProcessHost* host = - RenderProcessHost::FromID(peer_connection.render_process_id); - if (!host) { - return; // The host has been asynchronously removed; not a problem. - } if (enabled) { - host->Send( - new PeerConnectionTracker_StartEventLogOutput(peer_connection.lid)); + pc_tracker_proxy_->StartEventLogOutput(peer_connection); } else { - host->Send(new PeerConnectionTracker_StopEventLog(peer_connection.lid)); + pc_tracker_proxy_->StopEventLogOutput(peer_connection); } } -void WebRtcEventLogManager::InjectClockForTesting(base::Clock* clock) { +void WebRtcEventLogManager::SetClockForTesting(base::Clock* clock) { // Testing only; no need for threading guarantees (called before anything // could be put on the TQ). - local_logs_manager_.InjectClockForTesting(clock); + local_logs_manager_.SetClockForTesting(clock); +} + +void WebRtcEventLogManager::SetPeerConnectionTrackerProxyForTesting( + std::unique_ptr<PeerConnectionTrackerProxy> pc_tracker_proxy) { + // Testing only; no need for threading guarantees (called before anything + // could be put on the TQ). + pc_tracker_proxy_ = std::move(pc_tracker_proxy); } } // namespace content
diff --git a/content/browser/webrtc/webrtc_event_log_manager.h b/content/browser/webrtc/webrtc_event_log_manager.h index 1b8e5d0..0449514 100644 --- a/content/browser/webrtc/webrtc_event_log_manager.h +++ b/content/browser/webrtc/webrtc_event_log_manager.h
@@ -6,6 +6,7 @@ #define CONTENT_BROWSER_WEBRTC_WEBRTC_EVENT_LOG_MANAGER_H_ #include <map> +#include <memory> #include <type_traits> #include "base/callback.h" @@ -30,6 +31,18 @@ class CONTENT_EXPORT WebRtcEventLogManager : protected WebRtcLocalEventLogsObserver { public: + // To turn WebRTC on and off, we go through PeerConnectionTrackerProxy. In + // order to make this toggling easily testable, PeerConnectionTrackerProxyImpl + // will send real messages to PeerConnectionTracker, whereas + // PeerConnectionTrackerProxyForTesting will be a mock that just makes sure + // the correct messages were attempted to be sent. + class PeerConnectionTrackerProxy { + public: + virtual ~PeerConnectionTrackerProxy() = default; + virtual void StartEventLogOutput(WebRtcEventLogPeerConnectionKey key) = 0; + virtual void StopEventLogOutput(WebRtcEventLogPeerConnectionKey key) = 0; + }; + // Ensures that no previous instantiation of the class was performed, then // instantiates the class and returns the object. Subsequent calls to // GetInstance() will return this object. @@ -169,7 +182,10 @@ void UpdateWebRtcEventLoggingState(PeerConnectionKey peer_connection, bool enabled); - void InjectClockForTesting(base::Clock* clock); + void SetClockForTesting(base::Clock* clock); + + void SetPeerConnectionTrackerProxyForTesting( + std::unique_ptr<PeerConnectionTrackerProxy> pc_tracker_proxy); // Observer which will be informed whenever a local log file is started or // stopped. Its callbacks are called synchronously from |task_runner_|, @@ -185,6 +201,11 @@ std::map<PeerConnectionKey, LoggingTargetBitmap> peer_connections_with_event_logging_enabled_; + // In production, this holds a small object that just tells WebRTC (via + // PeerConnectionTracker) to start/stop producing event logs for a specific + // peer connection. In (relevant) unit tests, a mock will be injected. + std::unique_ptr<PeerConnectionTrackerProxy> pc_tracker_proxy_; + // The main logic will run sequentially on this runner, on which blocking // tasks are allowed. scoped_refptr<base::SequencedTaskRunner> task_runner_;
diff --git a/content/browser/webrtc/webrtc_event_log_manager_common.h b/content/browser/webrtc/webrtc_event_log_manager_common.h index 17ed338..f95d3e9 100644 --- a/content/browser/webrtc/webrtc_event_log_manager_common.h +++ b/content/browser/webrtc/webrtc_event_log_manager_common.h
@@ -43,9 +43,9 @@ class WebRtcLocalEventLogsObserver { public: virtual ~WebRtcLocalEventLogsObserver() = default; - virtual void OnLocalLogStarted(WebRtcEventLogPeerConnectionKey pc_key, + virtual void OnLocalLogStarted(WebRtcEventLogPeerConnectionKey key, base::FilePath file_path) = 0; - virtual void OnLocalLogStopped(WebRtcEventLogPeerConnectionKey pc_key) = 0; + virtual void OnLocalLogStopped(WebRtcEventLogPeerConnectionKey key) = 0; }; } // namespace content
diff --git a/content/browser/webrtc/webrtc_event_log_manager_unittest.cc b/content/browser/webrtc/webrtc_event_log_manager_unittest.cc index 068361f..8fa5db5 100644 --- a/content/browser/webrtc/webrtc_event_log_manager_unittest.cc +++ b/content/browser/webrtc/webrtc_event_log_manager_unittest.cc
@@ -7,6 +7,7 @@ #include <algorithm> #include <memory> #include <numeric> +#include <queue> #include <string> #include <vector> @@ -62,10 +63,11 @@ } // namespace class WebRtcEventLogManagerTest : public ::testing::Test { - protected: + public: WebRtcEventLogManagerTest() : run_loop_(std::make_unique<base::RunLoop>()), - manager_(new WebRtcEventLogManager) { + manager_(new WebRtcEventLogManager), + webrtc_state_change_run_loop_(std::make_unique<base::RunLoop>()) { EXPECT_TRUE( base::CreateNewTempDirectory(FILE_PATH_LITERAL(""), &base_dir_)); if (base_dir_.empty()) { @@ -80,6 +82,8 @@ if (!base_dir_.empty()) { EXPECT_TRUE(base::DeleteFile(base_dir_, true)); } + // Guard against unexpected state changes. + EXPECT_TRUE(webrtc_state_change_instructions_.empty()); } void DestroyUnitUnderTest() { @@ -170,7 +174,38 @@ ASSERT_TRUE( base::Time::FromLocalExploded(frozen_time_exploded, &frozen_time)); frozen_clock_.SetNow(frozen_time); - manager_->InjectClockForTesting(&frozen_clock_); + manager_->SetClockForTesting(&frozen_clock_); + } + + void StartEventLogOutput(PeerConnectionKey key) { + webrtc_state_change_instructions_.emplace(key, true); + webrtc_state_change_run_loop_->QuitWhenIdle(); + } + + void StopEventLogOutput(PeerConnectionKey key) { + webrtc_state_change_instructions_.emplace(key, false); + webrtc_state_change_run_loop_->QuitWhenIdle(); + } + + void ExpectWebRtcStateChangeInstruction(int render_process_id, + int lid, + bool enabled) { + webrtc_state_change_run_loop_->Run(); + webrtc_state_change_run_loop_.reset(new base::RunLoop); + + ASSERT_FALSE(webrtc_state_change_instructions_.empty()); + auto& instruction = webrtc_state_change_instructions_.front(); + const PeerConnectionKey key(render_process_id, lid); + EXPECT_EQ(instruction.key, key); + EXPECT_EQ(instruction.enabled, enabled); + webrtc_state_change_instructions_.pop(); + } + + void SetPeerConnectionTrackerProxyForTesting( + std::unique_ptr<WebRtcEventLogManager::PeerConnectionTrackerProxy> + pc_tracker_proxy) { + manager_->SetPeerConnectionTrackerProxyForTesting( + std::move(pc_tracker_proxy)); } // Common default values. @@ -187,8 +222,44 @@ base::FilePath base_dir_; // The directory where we'll save log files. base::FilePath base_path_; // base_dir_ + log files' name prefix. + + // WebRtcEventLogManager instructs WebRTC, via PeerConnectionTracker, to + // only send WebRTC messages for certain peer connections. Some tests make + // sure that this is done correctly, by waiting for these notifications, then + // testing them. + struct WebRtcStateChangeInstruction { + WebRtcStateChangeInstruction(PeerConnectionKey key, bool enabled) + : key(key), enabled(enabled) {} + PeerConnectionKey key; + bool enabled; + }; + std::queue<WebRtcStateChangeInstruction> webrtc_state_change_instructions_; + std::unique_ptr<base::RunLoop> webrtc_state_change_run_loop_; }; +namespace { + +class PeerConnectionTrackerProxyForTesting + : public WebRtcEventLogManager::PeerConnectionTrackerProxy { + public: + explicit PeerConnectionTrackerProxyForTesting(WebRtcEventLogManagerTest* test) + : test_(test) {} + ~PeerConnectionTrackerProxyForTesting() override = default; + + void StartEventLogOutput(WebRtcEventLogPeerConnectionKey key) override { + test_->StartEventLogOutput(key); + } + + void StopEventLogOutput(WebRtcEventLogPeerConnectionKey key) override { + test_->StopEventLogOutput(key); + } + + private: + WebRtcEventLogManagerTest* const test_; +}; + +} // namespace + TEST_F(WebRtcEventLogManagerTest, LocalLogPeerConnectionAddedReturnsTrue) { EXPECT_TRUE(PeerConnectionAdded(kRenderProcessId, kPeerConnectionId)); } @@ -940,4 +1011,68 @@ ASSERT_EQ(file_path_2, expected_path_2); } +TEST_F(WebRtcEventLogManagerTest, + NoStartWebRtcSendingEventLogsWhenLocalEnabledWithoutPeerConnection) { + SetPeerConnectionTrackerProxyForTesting( + std::make_unique<PeerConnectionTrackerProxyForTesting>(this)); + ASSERT_TRUE(EnableLocalLogging()); + EXPECT_TRUE(webrtc_state_change_instructions_.empty()); +} + +TEST_F(WebRtcEventLogManagerTest, + NoStartWebRtcSendingEventLogsWhenPeerConnectionButNoLoggingEnabled) { + SetPeerConnectionTrackerProxyForTesting( + std::make_unique<PeerConnectionTrackerProxyForTesting>(this)); + ASSERT_TRUE(PeerConnectionAdded(kRenderProcessId, kPeerConnectionId)); + EXPECT_TRUE(webrtc_state_change_instructions_.empty()); +} + +TEST_F(WebRtcEventLogManagerTest, + StartWebRtcSendingEventLogsWhenLocalEnabledThenPeerConnectionAdded) { + SetPeerConnectionTrackerProxyForTesting( + std::make_unique<PeerConnectionTrackerProxyForTesting>(this)); + ASSERT_TRUE(EnableLocalLogging()); + ASSERT_TRUE(PeerConnectionAdded(kRenderProcessId, kPeerConnectionId)); + ExpectWebRtcStateChangeInstruction(kRenderProcessId, kPeerConnectionId, true); +} + +TEST_F(WebRtcEventLogManagerTest, + StartWebRtcSendingEventLogsWhenPeerConnectionAddedThenLocalEnabled) { + SetPeerConnectionTrackerProxyForTesting( + std::make_unique<PeerConnectionTrackerProxyForTesting>(this)); + ASSERT_TRUE(PeerConnectionAdded(kRenderProcessId, kPeerConnectionId)); + ASSERT_TRUE(EnableLocalLogging()); + ExpectWebRtcStateChangeInstruction(kRenderProcessId, kPeerConnectionId, true); +} + +TEST_F(WebRtcEventLogManagerTest, + InstructWebRtcToStopSendingEventLogsWhenLocalLoggingStopped) { + // Setup + SetPeerConnectionTrackerProxyForTesting( + std::make_unique<PeerConnectionTrackerProxyForTesting>(this)); + ASSERT_TRUE(PeerConnectionAdded(kRenderProcessId, kPeerConnectionId)); + ASSERT_TRUE(EnableLocalLogging()); + ExpectWebRtcStateChangeInstruction(kRenderProcessId, kPeerConnectionId, true); + + // Test + ASSERT_TRUE(DisableLocalLogging()); + ExpectWebRtcStateChangeInstruction(kRenderProcessId, kPeerConnectionId, + false); +} + +TEST_F(WebRtcEventLogManagerTest, + InstructWebRtcToStopSendingEventLogsWhenPeerConnectionRemoved) { + // Setup + SetPeerConnectionTrackerProxyForTesting( + std::make_unique<PeerConnectionTrackerProxyForTesting>(this)); + ASSERT_TRUE(PeerConnectionAdded(kRenderProcessId, kPeerConnectionId)); + ASSERT_TRUE(EnableLocalLogging()); + ExpectWebRtcStateChangeInstruction(kRenderProcessId, kPeerConnectionId, true); + + // Test + ASSERT_TRUE(PeerConnectionRemoved(kRenderProcessId, kPeerConnectionId)); + ExpectWebRtcStateChangeInstruction(kRenderProcessId, kPeerConnectionId, + false); +} + } // namespace content
diff --git a/content/browser/webrtc/webrtc_local_event_log_manager.cc b/content/browser/webrtc/webrtc_local_event_log_manager.cc index 31bbc5d..6b010b6f 100644 --- a/content/browser/webrtc/webrtc_local_event_log_manager.cc +++ b/content/browser/webrtc/webrtc_local_event_log_manager.cc
@@ -157,7 +157,7 @@ return (static_cast<size_t>(written) == output.length()); } -void WebRtcLocalEventLogManager::InjectClockForTesting(base::Clock* clock) { +void WebRtcLocalEventLogManager::SetClockForTesting(base::Clock* clock) { clock_for_testing_ = clock; }
diff --git a/content/browser/webrtc/webrtc_local_event_log_manager.h b/content/browser/webrtc/webrtc_local_event_log_manager.h index 7934e028..da6654c 100644 --- a/content/browser/webrtc/webrtc_local_event_log_manager.h +++ b/content/browser/webrtc/webrtc_local_event_log_manager.h
@@ -31,8 +31,8 @@ // This function is public, but this entire class is a protected // implementation detail of WebRtcEventLogManager, which hides this - // function from everybody except its own unit-tests. - void InjectClockForTesting(base::Clock* clock); + // function from everybody except its own unit tests. + void SetClockForTesting(base::Clock* clock); private: using PeerConnectionKey = WebRtcEventLogPeerConnectionKey;
diff --git a/content/browser/zygote_host/zygote_host_impl_linux.cc b/content/browser/zygote_host/zygote_host_impl_linux.cc index 680c08a8..900ef81 100644 --- a/content/browser/zygote_host/zygote_host_impl_linux.cc +++ b/content/browser/zygote_host/zygote_host_impl_linux.cc
@@ -14,9 +14,7 @@ #include "base/process/kill.h" #include "base/process/memory.h" #include "base/strings/string_number_conversions.h" -#include "content/browser/sandbox_host_linux.h" #include "content/common/zygote_commands_linux.h" -#include "content/public/common/common_sandbox_support_linux.h" #include "content/public/common/content_switches.h" #include "sandbox/linux/services/credentials.h" #include "sandbox/linux/services/namespace_sandbox.h" @@ -152,19 +150,17 @@ return renderer_sandbox_status_; } -pid_t ZygoteHostImpl::LaunchZygote(base::CommandLine* cmd_line, - base::ScopedFD* control_fd) { +pid_t ZygoteHostImpl::LaunchZygote( + base::CommandLine* cmd_line, + base::ScopedFD* control_fd, + base::FileHandleMappingVector additional_remapped_fds) { int fds[2]; CHECK_EQ(0, socketpair(AF_UNIX, SOCK_SEQPACKET, 0, fds)); CHECK(base::UnixDomainSocket::EnableReceiveProcessId(fds[0])); base::LaunchOptions options; - options.fds_to_remap.push_back(std::make_pair(fds[1], kZygoteSocketPairFd)); - - // Start up the sandbox host process and get the file descriptor for the - // sandboxed processes to talk to it. - const int sfd = SandboxHostLinux::GetInstance()->GetChildSocket(); - options.fds_to_remap.push_back(std::make_pair(sfd, GetSandboxFD())); + options.fds_to_remap = std::move(additional_remapped_fds); + options.fds_to_remap.emplace_back(fds[1], kZygoteSocketPairFd); base::ScopedFD dummy_fd; if (use_suid_sandbox_) {
diff --git a/content/browser/zygote_host/zygote_host_impl_linux.h b/content/browser/zygote_host/zygote_host_impl_linux.h index ee70bd6..c527996 100644 --- a/content/browser/zygote_host/zygote_host_impl_linux.h +++ b/content/browser/zygote_host/zygote_host_impl_linux.h
@@ -12,6 +12,7 @@ #include "base/command_line.h" #include "base/files/scoped_file.h" +#include "base/process/launch.h" #include "base/process/process_handle.h" #include "base/synchronization/lock.h" #include "content/public/browser/zygote_host_linux.h" @@ -36,7 +37,10 @@ void SetRendererSandboxStatus(int status); int GetRendererSandboxStatus() const override; - pid_t LaunchZygote(base::CommandLine* cmd_line, base::ScopedFD* control_fd); + pid_t LaunchZygote(base::CommandLine* cmd_line, + base::ScopedFD* control_fd, + base::FileHandleMappingVector additional_remapped_fds); + void AdjustRendererOOMScore(base::ProcessHandle process_handle, int score) override;
diff --git a/content/child/blink_platform_impl.cc b/content/child/blink_platform_impl.cc index 025d0cfb..17dbb02 100644 --- a/content/child/blink_platform_impl.cc +++ b/content/child/blink_platform_impl.cc
@@ -369,10 +369,10 @@ } std::unique_ptr<blink::WebThread> BlinkPlatformImpl::CreateThread( - const char* name) { + const blink::WebThreadCreationParams& params) { std::unique_ptr<blink::scheduler::WebThreadBase> thread = blink::scheduler::WebThreadBase::CreateWorkerThread( - name, base::Thread::Options()); + params.name, base::Thread::Options()); thread->Init(); WaitUntilWebThreadTLSUpdate(thread.get()); return std::move(thread);
diff --git a/content/child/blink_platform_impl.h b/content/child/blink_platform_impl.h index 6515ffd..24be824 100644 --- a/content/child/blink_platform_impl.h +++ b/content/child/blink_platform_impl.h
@@ -78,7 +78,8 @@ bool IsLowEndDevice() override; uint32_t GetUniqueIdForProcess() override; blink::WebString UserAgent() override; - std::unique_ptr<blink::WebThread> CreateThread(const char* name) override; + std::unique_ptr<blink::WebThread> CreateThread( + const blink::WebThreadCreationParams& params) override; std::unique_ptr<blink::WebThread> CreateWebAudioThread() override; blink::WebThread* CurrentThread() override; void RecordAction(const blink::UserMetricsAction&) override;
diff --git a/content/common/browser_plugin/browser_plugin_messages.h b/content/common/browser_plugin/browser_plugin_messages.h index 6d19348..101ccdbe 100644 --- a/content/common/browser_plugin/browser_plugin_messages.h +++ b/content/common/browser_plugin/browser_plugin_messages.h
@@ -162,15 +162,6 @@ uint64_t /* sequence_number */, viz::LocalSurfaceId /* local_surface_id */) -IPC_MESSAGE_ROUTED2(BrowserPluginHostMsg_SatisfySequence, - int /* browser_plugin_instance_id */, - viz::SurfaceSequence /* sequence */) - -IPC_MESSAGE_ROUTED3(BrowserPluginHostMsg_RequireSequence, - int /* browser_plugin_instance_id */, - viz::SurfaceId /* surface_id */, - viz::SurfaceSequence /* sequence */) - // ----------------------------------------------------------------------------- // These messages are from the browser process to the embedder. @@ -206,10 +197,9 @@ int /* browser_plugin_instance_id */, content::WebCursor /* cursor */) -IPC_MESSAGE_CONTROL3(BrowserPluginMsg_SetChildFrameSurface, +IPC_MESSAGE_CONTROL2(BrowserPluginMsg_SetChildFrameSurface, int /* browser_plugin_instance_id */, - viz::SurfaceInfo /* surface_info */, - viz::SurfaceSequence /* sequence */) + viz::SurfaceInfo /* surface_info */) // Forwards a PointerLock Unlock request to the BrowserPlugin. IPC_MESSAGE_CONTROL2(BrowserPluginMsg_SetMouseLock,
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h index 7bce348..565e406 100644 --- a/content/common/frame_messages.h +++ b/content/common/frame_messages.h
@@ -19,7 +19,6 @@ #include "build/build_config.h" #include "components/viz/common/surfaces/surface_id.h" #include "components/viz/common/surfaces/surface_info.h" -#include "components/viz/common/surfaces/surface_sequence.h" #include "content/common/content_export.h" #include "content/common/content_param_traits.h" #include "content/common/content_security_policy/csp_context.h" @@ -759,9 +758,8 @@ // ----------------------------------------------------------------------------- // Messages sent from the browser to the renderer. -IPC_MESSAGE_ROUTED2(FrameMsg_SetChildFrameSurface, - viz::SurfaceInfo /* surface_info */, - viz::SurfaceSequence /* sequence */) +IPC_MESSAGE_ROUTED1(FrameMsg_SetChildFrameSurface, + viz::SurfaceInfo /* surface_info */) // Notifies the embedding frame that the process rendering the child frame's // contents has terminated. @@ -1439,16 +1437,6 @@ bool /* is_throttled */) #endif // BUILDFLAG(ENABLE_PLUGINS) -// Satisfies a Surface destruction dependency associated with |sequence|. -IPC_MESSAGE_ROUTED1(FrameHostMsg_SatisfySequence, - viz::SurfaceSequence /* sequence */) - -// Creates a destruction dependency for the Surface specified by the given -// |surface_id|. -IPC_MESSAGE_ROUTED2(FrameHostMsg_RequireSequence, - viz::SurfaceId /* surface_id */, - viz::SurfaceSequence /* sequence */) - // Provides the result from handling BeforeUnload. |proceed| matches the return // value of the frame's beforeunload handler: true if the user decided to // proceed with leaving the page.
diff --git a/content/common/service_worker/service_worker_messages.h b/content/common/service_worker/service_worker_messages.h index 325c4900..24da92c 100644 --- a/content/common/service_worker/service_worker_messages.h +++ b/content/common/service_worker/service_worker_messages.h
@@ -110,14 +110,6 @@ url::Origin /* source_origin */, std::vector<blink::MessagePortChannel> /* sent_message_ports */) -// Increments and decrements the ServiceWorker object's reference -// counting in the browser side. The ServiceWorker object is created -// with ref-count==1 initially. -IPC_MESSAGE_CONTROL1(ServiceWorkerHostMsg_IncrementServiceWorkerRefCount, - int /* handle_id */) -IPC_MESSAGE_CONTROL1(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount, - int /* handle_id */) - // Tells the browser to terminate a service worker. Used in layout tests to // verify behavior when a service worker isn't running. IPC_MESSAGE_CONTROL1(ServiceWorkerHostMsg_TerminateWorker,
diff --git a/content/network/network_context.cc b/content/network/network_context.cc index 4c65f2a..ddd2766 100644 --- a/content/network/network_context.cc +++ b/content/network/network_context.cc
@@ -43,13 +43,11 @@ #include "net/http/http_server_properties_manager.h" #include "net/http/http_transaction_factory.h" #include "net/proxy/proxy_config.h" -#include "net/reporting/reporting_policy.h" #include "net/ssl/channel_id_service.h" #include "net/ssl/default_channel_id_store.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_builder.h" #include "services/network/proxy_config_service_mojo.h" -#include "services/network/public/cpp/network_features.h" #include "services/network/public/cpp/network_switches.h" namespace content { @@ -381,16 +379,6 @@ DCHECK(!network_context_params->enable_ftp_url_support); #endif -#if BUILDFLAG(ENABLE_REPORTING) - if (base::FeatureList::IsEnabled(features::kReporting)) - builder->set_reporting_policy(std::make_unique<net::ReportingPolicy>()); - else - builder->set_reporting_policy(nullptr); - - builder->set_network_error_logging_enabled( - base::FeatureList::IsEnabled(features::kNetworkErrorLogging)); -#endif // BUILDFLAG(ENABLE_REPORTING) - net::HttpNetworkSession::Params session_params; bool is_quic_force_disabled = false; if (quic_disabled)
diff --git a/content/network/network_context_unittest.cc b/content/network/network_context_unittest.cc index 16bddd2..f3db848e 100644 --- a/content/network/network_context_unittest.cc +++ b/content/network/network_context_unittest.cc
@@ -17,7 +17,6 @@ #include "base/run_loop.h" #include "base/strings/string_split.h" #include "base/test/mock_entropy_provider.h" -#include "base/test/scoped_feature_list.h" #include "base/test/scoped_task_environment.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" @@ -44,7 +43,6 @@ #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_builder.h" #include "net/url_request/url_request_job_factory.h" -#include "services/network/public/cpp/network_features.h" #include "services/network/public/interfaces/network_service.mojom.h" #include "services/network/public/interfaces/proxy_config.mojom.h" #include "testing/gtest/include/gtest/gtest.h" @@ -262,46 +260,6 @@ } #endif // !BUILDFLAG(DISABLE_FTP_SUPPORT) -#if BUILDFLAG(ENABLE_REPORTING) -TEST_F(NetworkContextTest, DisableReporting) { - base::test::ScopedFeatureList scoped_feature_list_; - scoped_feature_list_.InitAndDisableFeature(features::kReporting); - - std::unique_ptr<NetworkContext> network_context = - CreateContextWithParams(CreateContextParams()); - EXPECT_FALSE(network_context->url_request_context()->reporting_service()); -} - -TEST_F(NetworkContextTest, EnableReporting) { - base::test::ScopedFeatureList scoped_feature_list_; - scoped_feature_list_.InitAndEnableFeature(features::kReporting); - - std::unique_ptr<NetworkContext> network_context = - CreateContextWithParams(CreateContextParams()); - EXPECT_TRUE(network_context->url_request_context()->reporting_service()); -} - -TEST_F(NetworkContextTest, DisableNetworkErrorLogging) { - base::test::ScopedFeatureList scoped_feature_list_; - scoped_feature_list_.InitAndDisableFeature(features::kNetworkErrorLogging); - - std::unique_ptr<NetworkContext> network_context = - CreateContextWithParams(CreateContextParams()); - EXPECT_FALSE( - network_context->url_request_context()->network_error_logging_delegate()); -} - -TEST_F(NetworkContextTest, EnableNetworkErrorLogging) { - base::test::ScopedFeatureList scoped_feature_list_; - scoped_feature_list_.InitAndEnableFeature(features::kNetworkErrorLogging); - - std::unique_ptr<NetworkContext> network_context = - CreateContextWithParams(CreateContextParams()); - EXPECT_TRUE( - network_context->url_request_context()->network_error_logging_delegate()); -} -#endif // BUILDFLAG(ENABLE_REPORTING) - TEST_F(NetworkContextTest, Http09Disabled) { network::mojom::NetworkContextParamsPtr context_params = CreateContextParams();
diff --git a/content/public/android/BUILD.gn b/content/public/android/BUILD.gn index 8e3728a46..6873332c 100644 --- a/content/public/android/BUILD.gn +++ b/content/public/android/BUILD.gn
@@ -76,7 +76,6 @@ java_files = [ "java/src/org/chromium/content/app/ChromiumLinkerParams.java", - "java/src/org/chromium/content/app/ContentApplication.java", "java/src/org/chromium/content/app/ContentChildProcessService.java", "java/src/org/chromium/content/app/ContentChildProcessServiceDelegate.java", "java/src/org/chromium/content/app/ContentMain.java",
diff --git a/content/public/android/java/src/org/chromium/content/app/ContentApplication.java b/content/public/android/java/src/org/chromium/content/app/ContentApplication.java deleted file mode 100644 index f99526b..0000000 --- a/content/public/android/java/src/org/chromium/content/app/ContentApplication.java +++ /dev/null
@@ -1,34 +0,0 @@ -// Copyright 2013 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.content.app; - -import org.chromium.base.BaseChromiumApplication; -import org.chromium.base.VisibleForTesting; -import org.chromium.base.annotations.MainDex; - -/** - * Basic application functionality that should be shared among all browser applications - * based on the content layer. - */ -@MainDex -public abstract class ContentApplication extends BaseChromiumApplication { - private boolean mLibraryDependenciesInitialized; - - - @Override - public void onCreate() { - super.onCreate(); - mLibraryDependenciesInitialized = true; - } - - /** - * @return Whether the library dependencies have been initialized and it is safe to issue - * requests to load the native library. - */ - @VisibleForTesting - public boolean areLibraryDependenciesInitialized() { - return mLibraryDependenciesInitialized; - } -}
diff --git a/content/public/android/java/src/org/chromium/content/browser/SpeechRecognition.java b/content/public/android/java/src/org/chromium/content/browser/SpeechRecognition.java index 90aeb60f..f2eb964 100644 --- a/content/public/android/java/src/org/chromium/content/browser/SpeechRecognition.java +++ b/content/public/android/java/src/org/chromium/content/browser/SpeechRecognition.java
@@ -228,6 +228,7 @@ // This function destroys everything when recognition is done, taking care to properly tear // down by calling On{Sound,Audio}End if corresponding On{Audio,Sound}Start were called. private void terminate(int error) { + if (mNativeSpeechRecognizerImplAndroid == 0) return; if (mState != STATE_IDLE) { if (mState == STATE_CAPTURING_SPEECH) {
diff --git a/content/public/test/android/BUILD.gn b/content/public/test/android/BUILD.gn index ee6ce6c5..f0607ed 100644 --- a/content/public/test/android/BUILD.gn +++ b/content/public/test/android/BUILD.gn
@@ -37,7 +37,6 @@ "javatests/src/org/chromium/content/browser/test/NativeLibraryTestBase.java", "javatests/src/org/chromium/content/browser/test/NativeLibraryTestCommon.java", "javatests/src/org/chromium/content/browser/test/NativeLibraryTestRule.java", - "javatests/src/org/chromium/content/browser/test/util/ApplicationUtils.java", "javatests/src/org/chromium/content/browser/test/util/ClickUtils.java", "javatests/src/org/chromium/content/browser/test/util/Coordinates.java", "javatests/src/org/chromium/content/browser/test/util/Criteria.java",
diff --git a/content/public/test/android/javatests/src/org/chromium/content/browser/test/NativeLibraryTestCommon.java b/content/public/test/android/javatests/src/org/chromium/content/browser/test/NativeLibraryTestCommon.java index fbbdc539..51c0f9a 100644 --- a/content/public/test/android/javatests/src/org/chromium/content/browser/test/NativeLibraryTestCommon.java +++ b/content/public/test/android/javatests/src/org/chromium/content/browser/test/NativeLibraryTestCommon.java
@@ -15,7 +15,6 @@ import org.chromium.base.library_loader.LibraryProcessType; import org.chromium.base.library_loader.ProcessInitException; import org.chromium.content.browser.BrowserStartupController; -import org.chromium.content.browser.test.util.ApplicationUtils; class NativeLibraryTestCommon { private static final String PRIVATE_DATA_DIRECTORY_SUFFIX = "content"; @@ -26,8 +25,6 @@ PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX); - ApplicationUtils.waitForLibraryDependencies(instrumentation); - // LibraryLoader is not in general multithreaded; as other InstrumentationTestCase code // (specifically, ChromeBrowserProvider) uses it from the main thread we must do // likewise.
diff --git a/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/ApplicationUtils.java b/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/ApplicationUtils.java deleted file mode 100644 index ba8182cf..0000000 --- a/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/ApplicationUtils.java +++ /dev/null
@@ -1,37 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.content.browser.test.util; - -import android.app.Instrumentation; -import android.content.Context; - -import org.chromium.content.app.ContentApplication; - -/** - * Test utilities for dealing with applications. - */ -public class ApplicationUtils { - - /** - * Wait for the library dependencies to be initialized for the application being - * instrumented. - * - * @param instrumentation The test instrumentation. - */ - public static void waitForLibraryDependencies(final Instrumentation instrumentation) { - CriteriaHelper.pollUiThread(new Criteria() { - @Override - public boolean isSatisfied() { - Context context = instrumentation.getTargetContext(); - if (context == null) return false; - if (context.getApplicationContext() == null) return false; - ContentApplication application = - (ContentApplication) context.getApplicationContext(); - return application.areLibraryDependenciesInitialized(); - } - }); - } - -}
diff --git a/content/public/test/navigation_simulator.cc b/content/public/test/navigation_simulator.cc index 38e7cbc..b5924b35 100644 --- a/content/public/test/navigation_simulator.cc +++ b/content/public/test/navigation_simulator.cc
@@ -791,7 +791,7 @@ request = web_contents_->GetMainFrame()->frame_tree_node()->navigation_request(); if (!request) { - if (web_contents_->GetMainFrame()->navigation_handle() == handle_) { + if (web_contents_->GetMainFrame()->GetNavigationHandle() == handle_) { DCHECK(handle_->IsSameDocument() || !IsURLHandledByNetworkStack(handle_->GetURL())); same_document_ = handle_->IsSameDocument(); @@ -800,7 +800,7 @@ // There is no DidStartNavigation for renderer-debug URLs and the // NavigationHandle has already been passed to the main frame for commit. // Register it now. - handle_ = web_contents_->GetMainFrame()->navigation_handle(); + handle_ = web_contents_->GetMainFrame()->GetNavigationHandle(); // A navigation to a renderer-debug URL cannot commit. Simulate the // renderer process aborting it.
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index b8e28a1..cd18a5e 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn
@@ -423,8 +423,6 @@ "service_worker/service_worker_dispatcher.h", "service_worker/service_worker_fetch_context_impl.cc", "service_worker/service_worker_fetch_context_impl.h", - "service_worker/service_worker_handle_reference.cc", - "service_worker/service_worker_handle_reference.h", "service_worker/service_worker_message_filter.cc", "service_worker/service_worker_message_filter.h", "service_worker/service_worker_network_provider.cc",
diff --git a/content/renderer/browser_plugin/browser_plugin.cc b/content/renderer/browser_plugin/browser_plugin.cc index 19e2c163..d1f0501a 100644 --- a/content/renderer/browser_plugin/browser_plugin.cc +++ b/content/renderer/browser_plugin/browser_plugin.cc
@@ -141,8 +141,7 @@ void BrowserPlugin::OnSetChildFrameSurface( int browser_plugin_instance_id, - const viz::SurfaceInfo& surface_info, - const viz::SurfaceSequence& sequence) { + const viz::SurfaceInfo& surface_info) { if (!attached() || switches::IsMusHostingViz()) return; @@ -151,12 +150,7 @@ frame_rect().size()); } compositing_helper_->SetFallbackSurfaceId(surface_info.id(), - frame_rect().size(), sequence); -} - -void BrowserPlugin::SendSatisfySequence(const viz::SurfaceSequence& sequence) { - BrowserPluginManager::Get()->Send(new BrowserPluginHostMsg_SatisfySequence( - render_frame_routing_id_, browser_plugin_instance_id_, sequence)); + frame_rect().size()); } void BrowserPlugin::UpdateDOMAttribute(const std::string& attribute_name, @@ -768,8 +762,8 @@ if (!attached_) return; - compositing_helper_->SetFallbackSurfaceId( - surface_info.id(), frame_rect().size(), viz::SurfaceSequence()); + compositing_helper_->SetFallbackSurfaceId(surface_info.id(), + frame_rect().size()); } void BrowserPlugin::OnMusEmbeddedFrameSinkIdAllocated(
diff --git a/content/renderer/browser_plugin/browser_plugin.h b/content/renderer/browser_plugin/browser_plugin.h index 7480991..7df6d36 100644 --- a/content/renderer/browser_plugin/browser_plugin.h +++ b/content/renderer/browser_plugin/browser_plugin.h
@@ -34,7 +34,6 @@ namespace viz { class SurfaceInfo; -struct SurfaceSequence; } namespace content { @@ -77,9 +76,6 @@ // Indicates whether the guest should be focused. bool ShouldGuestBeFocused() const; - // Called by CompositingHelper to send current SurfaceSequence to browser. - void SendSatisfySequence(const viz::SurfaceSequence& sequence); - // Provided that a guest instance ID has been allocated, this method attaches // this BrowserPlugin instance to that guest. void Attach(); @@ -190,8 +186,7 @@ void OnResizeDueToAutoResize(int browser_plugin_instance_id, uint64_t sequence_number); void OnSetChildFrameSurface(int instance_id, - const viz::SurfaceInfo& surface_info, - const viz::SurfaceSequence& sequence); + const viz::SurfaceInfo& surface_info); void OnSetContentsOpaque(int instance_id, bool opaque); void OnSetCursor(int instance_id, const WebCursor& cursor); void OnSetMouseLock(int instance_id, bool enable);
diff --git a/content/renderer/child_frame_compositing_helper.cc b/content/renderer/child_frame_compositing_helper.cc index 01080066..fcd6a40 100644 --- a/content/renderer/child_frame_compositing_helper.cc +++ b/content/renderer/child_frame_compositing_helper.cc
@@ -6,7 +6,6 @@ #include <utility> -#include "base/command_line.h" #include "build/build_config.h" #include "cc/blink/web_layer_impl.h" #include "cc/layers/picture_image_layer.h" @@ -18,13 +17,7 @@ #include "components/viz/common/frame_sinks/copy_output_result.h" #include "components/viz/common/gpu/context_provider.h" #include "components/viz/common/resources/single_release_callback.h" -#include "components/viz/common/surfaces/sequence_surface_reference_factory.h" -#include "components/viz/common/surfaces/stub_surface_reference_factory.h" -#include "components/viz/common/switches.h" -#include "content/child/thread_safe_sender.h" -#include "content/common/browser_plugin/browser_plugin_messages.h" #include "content/common/content_switches_internal.h" -#include "content/common/frame_messages.h" #include "content/public/common/content_client.h" #include "content/public/renderer/content_renderer_client.h" #include "content/renderer/browser_plugin/browser_plugin.h" @@ -45,117 +38,6 @@ namespace content { -namespace { - -bool AreSurfaceReferencesEnabled() { -#if defined(OS_ANDROID) - return !base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kDisableSurfaceReferences); -#else - // Surface references are always enabled for non-Android platforms. - return true; -#endif -} - -class IframeSurfaceReferenceFactory - : public viz::SequenceSurfaceReferenceFactory { - public: - IframeSurfaceReferenceFactory(scoped_refptr<ThreadSafeSender> sender, - int routing_id) - : sender_(std::move(sender)), routing_id_(routing_id) {} - - void AddPendingSequence(const viz::SurfaceSequence& sequence) { - ReleasePendingSequenceIfNecessary(); - pending_sequence_ = sequence; - } - - private: - ~IframeSurfaceReferenceFactory() override { - ReleasePendingSequenceIfNecessary(); - } - - void ReleasePendingSequenceIfNecessary() const { - if (pending_sequence_.is_valid()) { - sender_->Send( - new FrameHostMsg_SatisfySequence(routing_id_, pending_sequence_)); - pending_sequence_ = viz::SurfaceSequence(); - } - } - - // cc::SequenceSurfaceReferenceFactory implementation: - void RequireSequence(const viz::SurfaceId& surface_id, - const viz::SurfaceSequence& sequence) const override { - sender_->Send( - new FrameHostMsg_RequireSequence(routing_id_, surface_id, sequence)); - // If there is a temporary reference that was waiting on a new one to be - // created, it is now safe to release it. - ReleasePendingSequenceIfNecessary(); - } - - void SatisfySequence(const viz::SurfaceSequence& sequence) const override { - sender_->Send(new FrameHostMsg_SatisfySequence(routing_id_, sequence)); - } - - const scoped_refptr<ThreadSafeSender> sender_; - mutable viz::SurfaceSequence pending_sequence_; - const int routing_id_; - - DISALLOW_COPY_AND_ASSIGN(IframeSurfaceReferenceFactory); -}; - -class BrowserPluginSurfaceReferenceFactory - : public viz::SequenceSurfaceReferenceFactory { - public: - BrowserPluginSurfaceReferenceFactory(scoped_refptr<ThreadSafeSender> sender, - int routing_id, - int browser_plugin_instance_id) - : sender_(std::move(sender)), - routing_id_(routing_id), - browser_plugin_instance_id_(browser_plugin_instance_id) {} - - void AddPendingSequence(const viz::SurfaceSequence& sequence) { - ReleasePendingSequenceIfNecessary(); - pending_sequence_ = sequence; - } - - private: - ~BrowserPluginSurfaceReferenceFactory() override { - ReleasePendingSequenceIfNecessary(); - } - - void ReleasePendingSequenceIfNecessary() const { - if (pending_sequence_.is_valid()) { - sender_->Send(new BrowserPluginHostMsg_SatisfySequence( - routing_id_, browser_plugin_instance_id_, pending_sequence_)); - pending_sequence_ = viz::SurfaceSequence(); - } - } - - // cc::SequenceSurfaceRefrenceFactory implementation: - void SatisfySequence(const viz::SurfaceSequence& seq) const override { - sender_->Send(new BrowserPluginHostMsg_SatisfySequence( - routing_id_, browser_plugin_instance_id_, seq)); - } - - void RequireSequence(const viz::SurfaceId& surface_id, - const viz::SurfaceSequence& sequence) const override { - sender_->Send(new BrowserPluginHostMsg_RequireSequence( - routing_id_, browser_plugin_instance_id_, surface_id, sequence)); - // If there is a temporary reference that was waiting on a new one to be - // created, it is now safe to release it. - ReleasePendingSequenceIfNecessary(); - } - - const scoped_refptr<ThreadSafeSender> sender_; - mutable viz::SurfaceSequence pending_sequence_; - const int routing_id_; - const int browser_plugin_instance_id_; - - DISALLOW_COPY_AND_ASSIGN(BrowserPluginSurfaceReferenceFactory); -}; - -} // namespace - ChildFrameCompositingHelper* ChildFrameCompositingHelper::CreateForBrowserPlugin( const base::WeakPtr<BrowserPlugin>& browser_plugin) { @@ -180,24 +62,7 @@ : host_routing_id_(host_routing_id), browser_plugin_(browser_plugin), render_frame_proxy_(render_frame_proxy), - frame_(frame), - enable_surface_references_(AreSurfaceReferencesEnabled()) { - // In some tests there is no RenderThreadImpl instance. - if (enable_surface_references_ || !RenderThreadImpl::current()) { - surface_reference_factory_ = new viz::StubSurfaceReferenceFactory(); - } else { - scoped_refptr<ThreadSafeSender> sender( - RenderThreadImpl::current()->thread_safe_sender()); - if (render_frame_proxy_) { - surface_reference_factory_ = - new IframeSurfaceReferenceFactory(sender, host_routing_id_); - } else { - surface_reference_factory_ = new BrowserPluginSurfaceReferenceFactory( - sender, host_routing_id_, - browser_plugin_->browser_plugin_instance_id()); - } - } -} + frame_(frame) {} ChildFrameCompositingHelper::~ChildFrameCompositingHelper() { } @@ -264,7 +129,7 @@ last_primary_surface_id_ = surface_id; - surface_layer_ = cc::SurfaceLayer::Create(surface_reference_factory_); + surface_layer_ = cc::SurfaceLayer::Create(); surface_layer_->SetMasksToBounds(true); surface_layer_->SetBackgroundColor(SK_ColorTRANSPARENT); @@ -288,26 +153,11 @@ void ChildFrameCompositingHelper::SetFallbackSurfaceId( const viz::SurfaceId& surface_id, - const gfx::Size& frame_size_in_dip, - const viz::SurfaceSequence& sequence) { + const gfx::Size& frame_size_in_dip) { if (fallback_surface_id_ == surface_id) return; fallback_surface_id_ = surface_id; - // The RWHV creates a destruction dependency on the surface that needs to be - // satisfied. The reference factory will satisfy it when a new reference has - // been created. - if (!enable_surface_references_) { - if (render_frame_proxy_) { - static_cast<IframeSurfaceReferenceFactory*>( - surface_reference_factory_.get()) - ->AddPendingSequence(sequence); - } else { - static_cast<BrowserPluginSurfaceReferenceFactory*>( - surface_reference_factory_.get()) - ->AddPendingSequence(sequence); - } - } if (!surface_layer_) { SetPrimarySurfaceId(surface_id, frame_size_in_dip);
diff --git a/content/renderer/child_frame_compositing_helper.h b/content/renderer/child_frame_compositing_helper.h index d67244a..9ef0a2cc 100644 --- a/content/renderer/child_frame_compositing_helper.h +++ b/content/renderer/child_frame_compositing_helper.h
@@ -16,14 +16,9 @@ #include "base/memory/weak_ptr.h" #include "cc/layers/surface_layer.h" #include "components/viz/common/surfaces/surface_id.h" -#include "components/viz/common/surfaces/surface_reference_factory.h" #include "content/common/content_export.h" #include "ui/gfx/geometry/size.h" -namespace cc { -struct SurfaceSequence; -} - namespace blink { class WebLayer; class WebPluginContainer; @@ -56,8 +51,7 @@ void SetPrimarySurfaceId(const viz::SurfaceId& surface_id, const gfx::Size& frame_size_in_dip); void SetFallbackSurfaceId(const viz::SurfaceId& surface_id, - const gfx::Size& frame_size_in_dip, - const viz::SurfaceSequence& sequence); + const gfx::Size& frame_size_in_dip); void UpdateVisibility(bool); void ChildFrameGone(); @@ -94,13 +88,6 @@ std::unique_ptr<blink::WebLayer> web_layer_; blink::WebRemoteFrame* frame_; - // If surface references are enabled use a stub reference factory. - // TODO(kylechar): Remove variable along with surface sequences. - // See https://crbug.com/676384. - bool enable_surface_references_; - - scoped_refptr<viz::SurfaceReferenceFactory> surface_reference_factory_; - DISALLOW_COPY_AND_ASSIGN(ChildFrameCompositingHelper); };
diff --git a/content/renderer/gpu/render_widget_compositor.cc b/content/renderer/gpu/render_widget_compositor.cc index 69305da..77411b2a 100644 --- a/content/renderer/gpu/render_widget_compositor.cc +++ b/content/renderer/gpu/render_widget_compositor.cc
@@ -1273,7 +1273,6 @@ void RenderWidgetCompositor::SetFrameSinkId( const viz::FrameSinkId& frame_sink_id) { frame_sink_id_ = frame_sink_id; - layer_tree_host_->SetFrameSinkId(frame_sink_id); } void RenderWidgetCompositor::SetPaintedDeviceScaleFactor(float device_scale) {
diff --git a/content/renderer/mus/mus_embedded_frame.cc b/content/renderer/mus/mus_embedded_frame.cc index 81aadcbe..f3a08923 100644 --- a/content/renderer/mus/mus_embedded_frame.cc +++ b/content/renderer/mus/mus_embedded_frame.cc
@@ -12,7 +12,6 @@ #include "components/viz/client/client_layer_tree_frame_sink.h" #include "components/viz/client/hit_test_data_provider.h" #include "components/viz/client/local_surface_id_provider.h" -#include "components/viz/common/surfaces/surface_sequence.h" #include "content/renderer/mus/renderer_window_tree_client.h" #include "services/ui/public/cpp/property_type_converters.h" #include "services/ui/public/interfaces/window_manager.mojom.h"
diff --git a/content/renderer/mus/renderer_window_tree_client.cc b/content/renderer/mus/renderer_window_tree_client.cc index 0305fe24..7447b54 100644 --- a/content/renderer/mus/renderer_window_tree_client.cc +++ b/content/renderer/mus/renderer_window_tree_client.cc
@@ -12,7 +12,6 @@ #include "components/viz/client/client_layer_tree_frame_sink.h" #include "components/viz/client/hit_test_data_provider.h" #include "components/viz/client/local_surface_id_provider.h" -#include "components/viz/common/surfaces/surface_sequence.h" #include "content/renderer/mash_util.h" #include "content/renderer/mus/mus_embedded_frame.h" #include "content/renderer/mus/mus_embedded_frame_delegate.h"
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 4ff4df9..011ee69 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -137,7 +137,6 @@ #include "content/renderer/resource_timing_info_conversions.h" #include "content/renderer/savable_resources.h" #include "content/renderer/screen_orientation/screen_orientation_dispatcher.h" -#include "content/renderer/service_worker/service_worker_handle_reference.h" #include "content/renderer/service_worker/service_worker_network_provider.h" #include "content/renderer/service_worker/service_worker_provider_context.h" #include "content/renderer/service_worker/web_service_worker_provider_impl.h"
diff --git a/content/renderer/render_frame_proxy.cc b/content/renderer/render_frame_proxy.cc index 8f83112..1b131852 100644 --- a/content/renderer/render_frame_proxy.cc +++ b/content/renderer/render_frame_proxy.cc
@@ -340,8 +340,7 @@ } void RenderFrameProxy::SetChildFrameSurface( - const viz::SurfaceInfo& surface_info, - const viz::SurfaceSequence& sequence) { + const viz::SurfaceInfo& surface_info) { // If this WebFrame has already been detached, its parent will be null. This // can happen when swapping a WebRemoteFrame with a WebLocalFrame, where this // message may arrive after the frame was removed from the frame tree, but @@ -354,7 +353,7 @@ frame_rect().size()); } compositing_helper_->SetFallbackSurfaceId(surface_info.id(), - frame_rect().size(), sequence); + frame_rect().size()); } bool RenderFrameProxy::OnMessageReceived(const IPC::Message& msg) { @@ -424,9 +423,8 @@ } void RenderFrameProxy::OnSetChildFrameSurface( - const viz::SurfaceInfo& surface_info, - const viz::SurfaceSequence& sequence) { - SetChildFrameSurface(surface_info, sequence); + const viz::SurfaceInfo& surface_info) { + SetChildFrameSurface(surface_info); } void RenderFrameProxy::OnUpdateOpener(int opener_routing_id) { @@ -736,7 +734,7 @@ #if defined(USE_AURA) void RenderFrameProxy::OnMusEmbeddedFrameSurfaceChanged( const viz::SurfaceInfo& surface_info) { - SetChildFrameSurface(surface_info, viz::SurfaceSequence()); + SetChildFrameSurface(surface_info); } void RenderFrameProxy::OnMusEmbeddedFrameSinkIdAllocated(
diff --git a/content/renderer/render_frame_proxy.h b/content/renderer/render_frame_proxy.h index 10554f05..bf21044 100644 --- a/content/renderer/render_frame_proxy.h +++ b/content/renderer/render_frame_proxy.h
@@ -31,7 +31,6 @@ namespace viz { class SurfaceInfo; -struct SurfaceSequence; } namespace content { @@ -198,8 +197,7 @@ void ResendResizeParams(); - void SetChildFrameSurface(const viz::SurfaceInfo& surface_info, - const viz::SurfaceSequence& sequence); + void SetChildFrameSurface(const viz::SurfaceInfo& surface_info); // IPC::Listener bool OnMessageReceived(const IPC::Message& msg) override; @@ -208,8 +206,8 @@ void OnDeleteProxy(); void OnChildFrameProcessGone(); void OnCompositorFrameSwapped(const IPC::Message& message); - void OnSetChildFrameSurface(const viz::SurfaceInfo& surface_info, - const viz::SurfaceSequence& sequence); + // TODO(fsamuel): Rename OnFirstSurfaceActivation(). + void OnSetChildFrameSurface(const viz::SurfaceInfo& surface_info); void OnUpdateOpener(int opener_routing_id); void OnViewChanged(const viz::FrameSinkId& frame_sink_id); void OnDidStopLoading(); @@ -295,6 +293,6 @@ DISALLOW_COPY_AND_ASSIGN(RenderFrameProxy); }; -} // namespace +} // namespace content #endif // CONTENT_RENDERER_RENDER_FRAME_PROXY_H_
diff --git a/content/renderer/service_worker/service_worker_context_client.cc b/content/renderer/service_worker/service_worker_context_client.cc index 82468087..81d1fa7 100644 --- a/content/renderer/service_worker/service_worker_context_client.cc +++ b/content/renderer/service_worker/service_worker_context_client.cc
@@ -31,6 +31,7 @@ #include "content/public/renderer/child_url_loader_factory_getter.h" #include "content/public/renderer/content_renderer_client.h" #include "content/public/renderer/document_state.h" +#include "content/public/renderer/worker_thread.h" #include "content/renderer/loader/request_extra_data.h" #include "content/renderer/loader/web_data_consumer_handle_impl.h" #include "content/renderer/loader/web_url_loader_impl.h" @@ -42,7 +43,6 @@ #include "content/renderer/service_worker/embedded_worker_instance_client_impl.h" #include "content/renderer/service_worker/service_worker_dispatcher.h" #include "content/renderer/service_worker/service_worker_fetch_context_impl.h" -#include "content/renderer/service_worker/service_worker_handle_reference.h" #include "content/renderer/service_worker/service_worker_network_provider.h" #include "content/renderer/service_worker/service_worker_provider_context.h" #include "content/renderer/service_worker/service_worker_timeout_timer.h" @@ -358,6 +358,97 @@ // This frees the ref to the internal data of |response|. } +template <typename Signature> +class CallbackWrapperOnWorkerThread; + +// Always lives (create/run/destroy) on the same one worker thread. +// This is needed because we're using Mojo ThreadSafeAssociatedInterfacePtr for +// |context_->service_worker_host|, so we need to ensure Web*Callbacks are +// destructed on the worker thread. If the worker thread dies before the +// callback is run, this gets notified in WillStopCurrentWorkerThread() and +// deletes itself and the callback on the worker thread, otherwise, it runs the +// callback on the worker thread as normal and deletes itself. +// +// TODO(leonhsl): Once we can detach ServiceWorkerHost interface's association +// on the legacy IPC channel, we can avoid using +// ThreadSafeAssociatedInterfacePtr for |context_->service_worker_host|, then we +// can eliminate this wrapping mechanism. +template <typename... Args> +class CallbackWrapperOnWorkerThread<void(Args...)> + : public WorkerThread::Observer { + public: + using Signature = void(Args...); + + static base::WeakPtr<CallbackWrapperOnWorkerThread<Signature>> Create( + base::OnceCallback<Signature> callback) { + // |wrapper| controls its own lifetime via WorkerThread::Observer + // implementation. + auto* wrapper = + new CallbackWrapperOnWorkerThread<Signature>(std::move(callback)); + return wrapper->weak_ptr_factory_.GetWeakPtr(); + } + + ~CallbackWrapperOnWorkerThread() override { + DCHECK_GT(WorkerThread::GetCurrentId(), 0); + WorkerThread::RemoveObserver(this); + } + + void Run(Args... args) { + DCHECK(callback_); + std::move(callback_).Run(std::forward<Args>(args)...); + delete this; + } + + private: + explicit CallbackWrapperOnWorkerThread(base::OnceCallback<Signature> callback) + : callback_(std::move(callback)), weak_ptr_factory_(this) { + DCHECK_GT(WorkerThread::GetCurrentId(), 0); + WorkerThread::AddObserver(this); + } + + // WorkerThread::Observer implementation. + void WillStopCurrentWorkerThread() override { delete this; } + + base::OnceCallback<Signature> callback_; + base::WeakPtrFactory<CallbackWrapperOnWorkerThread> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(CallbackWrapperOnWorkerThread); +}; + +template <typename Signature> +base::OnceCallback<Signature> WrapCallbackThreadSafe( + base::OnceCallback<Signature> callback) { + return base::BindOnce( + &CallbackWrapperOnWorkerThread<Signature>::Run, + CallbackWrapperOnWorkerThread<Signature>::Create(std::move(callback))); +} + +void DidGetClients( + std::unique_ptr<blink::WebServiceWorkerClientsCallbacks> callbacks, + std::vector<blink::mojom::ServiceWorkerClientInfoPtr> clients) { + blink::WebServiceWorkerClientsInfo info; + blink::WebVector<blink::WebServiceWorkerClientInfo> web_clients( + clients.size()); + for (size_t i = 0; i < clients.size(); ++i) + web_clients[i] = ToWebServiceWorkerClientInfo(*(clients[i])); + info.clients.Swap(web_clients); + callbacks->OnSuccess(info); +} + +void DidClaimClients( + std::unique_ptr<blink::WebServiceWorkerClientsClaimCallbacks> callbacks, + blink::mojom::ServiceWorkerErrorType error, + const base::Optional<std::string>& error_msg) { + if (error != blink::mojom::ServiceWorkerErrorType::kNone) { + DCHECK(error_msg); + callbacks->OnError(blink::WebServiceWorkerError( + error, blink::WebString::FromUTF8(*error_msg))); + return; + } + DCHECK(!error_msg); + callbacks->OnSuccess(); +} + } // namespace // Holding data that needs to be bound to the worker context on the @@ -697,14 +788,10 @@ DCHECK(callbacks); auto options = blink::mojom::ServiceWorkerClientQueryOptions::New( weboptions.include_uncontrolled, weboptions.client_type); - // base::Unretained(this) is safe because the callback passed to - // GetClients() is owned by |context_->service_worker_host|, whose only - // owner is |this| and won't outlive |this|. (*context_->service_worker_host) - ->GetClients( - std::move(options), - base::BindOnce(&ServiceWorkerContextClient::OnDidGetClients, - base::Unretained(this), std::move(callbacks))); + ->GetClients(std::move(options), + WrapCallbackThreadSafe( + base::BindOnce(&DidGetClients, std::move(callbacks)))); } void ServiceWorkerContextClient::OpenNewTab( @@ -1241,13 +1328,9 @@ std::unique_ptr<blink::WebServiceWorkerClientsClaimCallbacks> callbacks) { DCHECK(callbacks); DCHECK(context_->service_worker_host); - // base::Unretained(this) is safe because the callback passed to - // ClaimClients() is owned by |context_->service_worker_host|, whose only - // owner is |this| and won't outlive |this|. (*context_->service_worker_host) - ->ClaimClients( - base::BindOnce(&ServiceWorkerContextClient::OnDidClaimClients, - base::Unretained(this), std::move(callbacks))); + ->ClaimClients(WrapCallbackThreadSafe( + base::BindOnce(&DidClaimClients, std::move(callbacks)))); } void ServiceWorkerContextClient::DispatchOrQueueFetchEvent( @@ -1478,14 +1561,12 @@ blink::mojom::kInvalidServiceWorkerHandleId && event->source_info_for_service_worker->version_id != blink::mojom::kInvalidServiceWorkerVersionId); - std::unique_ptr<ServiceWorkerHandleReference> handle = - ServiceWorkerHandleReference::Adopt( - std::move(event->source_info_for_service_worker), sender_); ServiceWorkerDispatcher* dispatcher = ServiceWorkerDispatcher::GetOrCreateThreadSpecificInstance( sender_.get(), main_thread_task_runner_.get()); scoped_refptr<WebServiceWorkerImpl> worker = - dispatcher->GetOrCreateServiceWorker(std::move(handle)); + dispatcher->GetOrCreateServiceWorker( + std::move(event->source_info_for_service_worker)); proxy_->DispatchExtendableMessageEvent( request_id, blink::WebString::FromUTF16(event->message), event->source_origin, @@ -1628,20 +1709,6 @@ context_->client_callbacks.Remove(request_id); } -void ServiceWorkerContextClient::OnDidGetClients( - std::unique_ptr<blink::WebServiceWorkerClientsCallbacks> callbacks, - std::vector<blink::mojom::ServiceWorkerClientInfoPtr> clients) { - TRACE_EVENT0("ServiceWorker", - "ServiceWorkerContextClient::OnDidGetClients"); - blink::WebServiceWorkerClientsInfo info; - blink::WebVector<blink::WebServiceWorkerClientInfo> web_clients( - clients.size()); - for (size_t i = 0; i < clients.size(); ++i) - web_clients[i] = ToWebServiceWorkerClientInfo(*(clients[i])); - info.clients.Swap(web_clients); - callbacks->OnSuccess(info); -} - void ServiceWorkerContextClient::OnOpenWindowResponse( int request_id, const blink::mojom::ServiceWorkerClientInfo& client) { @@ -1754,24 +1821,6 @@ context_->skip_waiting_callbacks.Remove(request_id); } -void ServiceWorkerContextClient::OnDidClaimClients( - std::unique_ptr<blink::WebServiceWorkerClientsClaimCallbacks> callbacks, - blink::mojom::ServiceWorkerErrorType error, - const base::Optional<std::string>& error_msg) { - TRACE_EVENT0("ServiceWorker", - "ServiceWorkerContextClient::OnDidClaimClients"); - - if (error != blink::mojom::ServiceWorkerErrorType::kNone) { - DCHECK(error_msg); - callbacks->OnError(blink::WebServiceWorkerError( - error, blink::WebString::FromUTF8(*error_msg))); - return; - } - - DCHECK(!error_msg); - callbacks->OnSuccess(); -} - void ServiceWorkerContextClient::Ping(PingCallback callback) { std::move(callback).Run(); }
diff --git a/content/renderer/service_worker/service_worker_context_client.h b/content/renderer/service_worker/service_worker_context_client.h index 3e6edae3..2decc63 100644 --- a/content/renderer/service_worker/service_worker_context_client.h +++ b/content/renderer/service_worker/service_worker_context_client.h
@@ -360,9 +360,6 @@ void OnDidGetClient(int request_id, const blink::mojom::ServiceWorkerClientInfo& client); - void OnDidGetClients( - std::unique_ptr<blink::WebServiceWorkerClientsCallbacks> callbacks, - std::vector<blink::mojom::ServiceWorkerClientInfoPtr> clients); void OnOpenWindowResponse( int request_id, const blink::mojom::ServiceWorkerClientInfo& client); @@ -375,10 +372,6 @@ const blink::mojom::ServiceWorkerClientInfo& client); void OnNavigateClientError(int request_id, const GURL& url); void OnDidSkipWaiting(int request_id); - void OnDidClaimClients( - std::unique_ptr<blink::WebServiceWorkerClientsClaimCallbacks> callbacks, - blink::mojom::ServiceWorkerErrorType error, - const base::Optional<std::string>& error_msg); // Called to resolve the FetchEvent.preloadResponse promise. void OnNavigationPreloadResponse( int fetch_event_id,
diff --git a/content/renderer/service_worker/service_worker_dispatcher.cc b/content/renderer/service_worker/service_worker_dispatcher.cc index a38b326..b87dd6c 100644 --- a/content/renderer/service_worker/service_worker_dispatcher.cc +++ b/content/renderer/service_worker/service_worker_dispatcher.cc
@@ -18,7 +18,6 @@ #include "content/common/service_worker/service_worker_messages.h" #include "content/common/service_worker/service_worker_types.h" #include "content/public/common/content_constants.h" -#include "content/renderer/service_worker/service_worker_handle_reference.h" #include "content/renderer/service_worker/service_worker_provider_context.h" #include "content/renderer/service_worker/web_service_worker_impl.h" #include "third_party/WebKit/common/service_worker/service_worker_error_type.mojom.h" @@ -111,18 +110,17 @@ scoped_refptr<WebServiceWorkerImpl> ServiceWorkerDispatcher::GetOrCreateServiceWorker( - std::unique_ptr<ServiceWorkerHandleReference> handle_ref) { - if (!handle_ref) + blink::mojom::ServiceWorkerObjectInfoPtr info) { + if (!info || info->handle_id == blink::mojom::kInvalidServiceWorkerHandleId || + info->version_id == blink::mojom::kInvalidServiceWorkerVersionId) return nullptr; - WorkerObjectMap::iterator found = - service_workers_.find(handle_ref->handle_id()); + WorkerObjectMap::iterator found = service_workers_.find(info->handle_id); if (found != service_workers_.end()) return found->second; // WebServiceWorkerImpl constructor calls AddServiceWorker. - return new WebServiceWorkerImpl(std::move(handle_ref), - thread_safe_sender_.get()); + return new WebServiceWorkerImpl(std::move(info), thread_safe_sender_.get()); } void ServiceWorkerDispatcher::OnServiceWorkerStateChanged(
diff --git a/content/renderer/service_worker/service_worker_dispatcher.h b/content/renderer/service_worker/service_worker_dispatcher.h index c5e1559..de1b9931 100644 --- a/content/renderer/service_worker/service_worker_dispatcher.h +++ b/content/renderer/service_worker/service_worker_dispatcher.h
@@ -37,7 +37,6 @@ namespace content { -class ServiceWorkerHandleReference; class ThreadSafeSender; class WebServiceWorkerImpl; @@ -54,9 +53,9 @@ void OnMessageReceived(const IPC::Message& msg); // Returns the existing service worker or a newly created one with the given - // handle reference. Returns nullptr if the given reference is invalid. + // object info. Returns nullptr if the given object info is invalid. scoped_refptr<WebServiceWorkerImpl> GetOrCreateServiceWorker( - std::unique_ptr<ServiceWorkerHandleReference> handle_ref); + blink::mojom::ServiceWorkerObjectInfoPtr info); static ServiceWorkerDispatcher* GetOrCreateThreadSpecificInstance( scoped_refptr<ThreadSafeSender> thread_safe_sender, @@ -70,10 +69,6 @@ return main_thread_task_runner_.get(); } - scoped_refptr<ThreadSafeSender> thread_safe_sender() { - return thread_safe_sender_; - } - private: using WorkerObjectMap = std::map<int, WebServiceWorkerImpl*>;
diff --git a/content/renderer/service_worker/service_worker_dispatcher_unittest.cc b/content/renderer/service_worker/service_worker_dispatcher_unittest.cc index 8be7e30..a18ad62 100644 --- a/content/renderer/service_worker/service_worker_dispatcher_unittest.cc +++ b/content/renderer/service_worker/service_worker_dispatcher_unittest.cc
@@ -6,109 +6,40 @@ #include "base/macros.h" #include "base/message_loop/message_loop.h" -#include "content/child/thread_safe_sender.h" #include "content/common/service_worker/service_worker_container.mojom.h" -#include "content/common/service_worker/service_worker_messages.h" #include "content/common/service_worker/service_worker_types.h" -#include "content/renderer/service_worker/service_worker_handle_reference.h" #include "content/renderer/service_worker/service_worker_provider_context.h" #include "content/renderer/service_worker/web_service_worker_impl.h" -#include "content/renderer/service_worker/web_service_worker_registration_impl.h" -#include "ipc/ipc_sync_message_filter.h" -#include "ipc/ipc_test_sink.h" #include "mojo/public/cpp/bindings/associated_binding_set.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/WebKit/common/service_worker/service_worker_error_type.mojom.h" -#include "third_party/WebKit/common/service_worker/service_worker_registration.mojom.h" +#include "third_party/WebKit/common/service_worker/service_worker_object.mojom.h" namespace content { namespace { -class MockServiceWorkerRegistrationObjectHost - : public blink::mojom::ServiceWorkerRegistrationObjectHost { +class MockServiceWorkerObjectHost + : public blink::mojom::ServiceWorkerObjectHost { public: - MockServiceWorkerRegistrationObjectHost() { - bindings_.set_connection_error_handler( - base::Bind(&MockServiceWorkerRegistrationObjectHost::OnConnectionError, - base::Unretained(this))); - } - ~MockServiceWorkerRegistrationObjectHost() override = default; + MockServiceWorkerObjectHost(int32_t handle_id, int64_t version_id) + : handle_id_(handle_id), version_id_(version_id) {} + ~MockServiceWorkerObjectHost() override = default; - void AddBinding( - blink::mojom::ServiceWorkerRegistrationObjectHostAssociatedRequest - request) { - bindings_.AddBinding(this, std::move(request)); - } - - blink::mojom::ServiceWorkerRegistrationObjectAssociatedRequest - CreateRegistrationObjectRequest() { - if (!remote_registration_) - return mojo::MakeRequest(&remote_registration_); - return nullptr; + blink::mojom::ServiceWorkerObjectInfoPtr CreateObjectInfo() { + auto info = blink::mojom::ServiceWorkerObjectInfo::New(); + info->handle_id = handle_id_; + info->version_id = version_id_; + bindings_.AddBinding(this, mojo::MakeRequest(&info->host_ptr_info)); + return info; } int GetBindingCount() const { return bindings_.size(); } private: - // Implements blink::mojom::ServiceWorkerRegistrationObjectHost. - void Update(UpdateCallback callback) override { - std::move(callback).Run(blink::mojom::ServiceWorkerErrorType::kNone, - base::nullopt); - } - void Unregister(UnregisterCallback callback) override { - std::move(callback).Run(blink::mojom::ServiceWorkerErrorType::kNone, - base::nullopt); - } - void EnableNavigationPreload( - bool enable, - EnableNavigationPreloadCallback callback) override { - std::move(callback).Run(blink::mojom::ServiceWorkerErrorType::kNone, - base::nullopt); - } - void GetNavigationPreloadState( - GetNavigationPreloadStateCallback callback) override { - std::move(callback).Run(blink::mojom::ServiceWorkerErrorType::kNone, - base::nullopt, nullptr); - } - void SetNavigationPreloadHeader( - const std::string& value, - SetNavigationPreloadHeaderCallback callback) override { - std::move(callback).Run(blink::mojom::ServiceWorkerErrorType::kNone, - base::nullopt); - } - - void OnConnectionError() { - // If there are still bindings, |this| is still being used. - if (!bindings_.empty()) - return; - // Will destroy corresponding remote WebServiceWorkerRegistrationImpl - // instance. - remote_registration_.reset(); - } - - mojo::AssociatedBindingSet<blink::mojom::ServiceWorkerRegistrationObjectHost> - bindings_; - blink::mojom::ServiceWorkerRegistrationObjectAssociatedPtr - remote_registration_; -}; - -class ServiceWorkerTestSender : public ThreadSafeSender { - public: - explicit ServiceWorkerTestSender(IPC::TestSink* ipc_sink) - : ThreadSafeSender(nullptr, nullptr), - ipc_sink_(ipc_sink) {} - - bool Send(IPC::Message* message) override { - return ipc_sink_->Send(message); - } - - private: - ~ServiceWorkerTestSender() override {} - - IPC::TestSink* ipc_sink_; - - DISALLOW_COPY_AND_ASSIGN(ServiceWorkerTestSender); + int32_t handle_id_; + int64_t version_id_; + mojo::AssociatedBindingSet<blink::mojom::ServiceWorkerObjectHost> bindings_; }; } // namespace @@ -118,83 +49,63 @@ ServiceWorkerDispatcherTest() {} void SetUp() override { - sender_ = new ServiceWorkerTestSender(&ipc_sink_); - dispatcher_.reset(new ServiceWorkerDispatcher(sender_.get(), nullptr)); - } - - blink::mojom::ServiceWorkerRegistrationObjectInfoPtr - CreateServiceWorkerRegistrationObjectInfo() { - auto info = blink::mojom::ServiceWorkerRegistrationObjectInfo::New(); - info->registration_id = 20; - remote_registration_object_host_.AddBinding( - mojo::MakeRequest(&info->host_ptr_info)); - info->request = - remote_registration_object_host_.CreateRegistrationObjectRequest(); - - info->active = blink::mojom::ServiceWorkerObjectInfo::New(); - info->active->handle_id = 100; - info->active->version_id = 200; - info->waiting = blink::mojom::ServiceWorkerObjectInfo::New(); - info->waiting->handle_id = 101; - info->waiting->version_id = 201; - info->installing = blink::mojom::ServiceWorkerObjectInfo::New(); - info->installing->handle_id = 102; - info->installing->version_id = 202; - return info; + dispatcher_.reset( + new ServiceWorkerDispatcher(nullptr /* thread_safe_sender */, + nullptr /* main_thread_task_runner */)); } bool ContainsServiceWorker(int handle_id) { return ContainsKey(dispatcher_->service_workers_, handle_id); } - std::unique_ptr<ServiceWorkerHandleReference> Adopt( - blink::mojom::ServiceWorkerObjectInfoPtr info) { - return ServiceWorkerHandleReference::Adopt( - std::move(info), dispatcher_->thread_safe_sender()); - } - ServiceWorkerDispatcher* dispatcher() { return dispatcher_.get(); } - ThreadSafeSender* thread_safe_sender() { return sender_.get(); } - IPC::TestSink* ipc_sink() { return &ipc_sink_; } private: base::MessageLoop message_loop_; - IPC::TestSink ipc_sink_; std::unique_ptr<ServiceWorkerDispatcher> dispatcher_; - scoped_refptr<ServiceWorkerTestSender> sender_; - MockServiceWorkerRegistrationObjectHost remote_registration_object_host_; DISALLOW_COPY_AND_ASSIGN(ServiceWorkerDispatcherTest); }; TEST_F(ServiceWorkerDispatcherTest, GetServiceWorker) { - blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info = - CreateServiceWorkerRegistrationObjectInfo(); + scoped_refptr<WebServiceWorkerImpl> worker1; + scoped_refptr<WebServiceWorkerImpl> worker2; + auto mock_service_worker_object_host = + std::make_unique<MockServiceWorkerObjectHost>(100 /* handle_id */, + 200 /* version_id */); + ASSERT_EQ(0, mock_service_worker_object_host->GetBindingCount()); - // Should return a worker object newly created with the given reference. - scoped_refptr<WebServiceWorkerImpl> worker( - dispatcher()->GetOrCreateServiceWorker(Adopt(info->installing->Clone()))); - EXPECT_TRUE(worker); - EXPECT_TRUE(ContainsServiceWorker(info->installing->handle_id)); - EXPECT_EQ(0UL, ipc_sink()->message_count()); + // Should return a worker object newly created with the 1st given |info|. + { + blink::mojom::ServiceWorkerObjectInfoPtr info = + mock_service_worker_object_host->CreateObjectInfo(); + EXPECT_EQ(1, mock_service_worker_object_host->GetBindingCount()); + int handle_id = info->handle_id; + worker1 = dispatcher()->GetOrCreateServiceWorker(std::move(info)); + EXPECT_TRUE(worker1); + EXPECT_TRUE(ContainsServiceWorker(handle_id)); + // |worker1| is holding the 1st blink::mojom::ServiceWorkerObjectHost Mojo + // connection to |mock_service_worker_object_host|. + EXPECT_EQ(1, mock_service_worker_object_host->GetBindingCount()); + } - // Should return the same worker object and release the given reference. - scoped_refptr<WebServiceWorkerImpl> existing_worker = - dispatcher()->GetOrCreateServiceWorker( - Adopt(std::move(info->installing))); - EXPECT_EQ(worker, existing_worker); - ASSERT_EQ(1UL, ipc_sink()->message_count()); - EXPECT_EQ(static_cast<uint32_t>( - ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID), - ipc_sink()->GetMessageAt(0)->type()); - ipc_sink()->ClearMessages(); + // Should return the same worker object and release the 2nd given |info|. + { + blink::mojom::ServiceWorkerObjectInfoPtr info = + mock_service_worker_object_host->CreateObjectInfo(); + EXPECT_EQ(2, mock_service_worker_object_host->GetBindingCount()); + worker2 = dispatcher()->GetOrCreateServiceWorker(std::move(info)); + EXPECT_EQ(worker1, worker2); + base::RunLoop().RunUntilIdle(); + // The Mojo connection kept by |info| should be released. + EXPECT_EQ(1, mock_service_worker_object_host->GetBindingCount()); + } // Should return nullptr when a given object is invalid. scoped_refptr<WebServiceWorkerImpl> invalid_worker = dispatcher()->GetOrCreateServiceWorker( - Adopt(blink::mojom::ServiceWorkerObjectInfo::New())); + blink::mojom::ServiceWorkerObjectInfo::New()); EXPECT_FALSE(invalid_worker); - EXPECT_EQ(0UL, ipc_sink()->message_count()); } } // namespace content
diff --git a/content/renderer/service_worker/service_worker_handle_reference.cc b/content/renderer/service_worker/service_worker_handle_reference.cc deleted file mode 100644 index f51a5d3..0000000 --- a/content/renderer/service_worker/service_worker_handle_reference.cc +++ /dev/null
@@ -1,38 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/renderer/service_worker/service_worker_handle_reference.h" - -#include "base/memory/ptr_util.h" -#include "content/child/thread_safe_sender.h" -#include "content/common/service_worker/service_worker_messages.h" -#include "third_party/WebKit/common/service_worker/service_worker_object.mojom.h" - -namespace content { - -std::unique_ptr<ServiceWorkerHandleReference> -ServiceWorkerHandleReference::Adopt( - blink::mojom::ServiceWorkerObjectInfoPtr info, - scoped_refptr<ThreadSafeSender> sender) { - DCHECK(sender); - if (info->handle_id == blink::mojom::kInvalidServiceWorkerHandleId) - return nullptr; - return base::WrapUnique( - new ServiceWorkerHandleReference(std::move(info), std::move(sender))); -} - -ServiceWorkerHandleReference::ServiceWorkerHandleReference( - blink::mojom::ServiceWorkerObjectInfoPtr info, - scoped_refptr<ThreadSafeSender> sender) - : info_(std::move(info)), sender_(sender) { - DCHECK_NE(info_->handle_id, blink::mojom::kInvalidServiceWorkerHandleId); -} - -ServiceWorkerHandleReference::~ServiceWorkerHandleReference() { - DCHECK_NE(info_->handle_id, blink::mojom::kInvalidServiceWorkerHandleId); - sender_->Send(new ServiceWorkerHostMsg_DecrementServiceWorkerRefCount( - info_->handle_id)); -} - -} // namespace content
diff --git a/content/renderer/service_worker/service_worker_handle_reference.h b/content/renderer/service_worker/service_worker_handle_reference.h deleted file mode 100644 index c692a0f56..0000000 --- a/content/renderer/service_worker/service_worker_handle_reference.h +++ /dev/null
@@ -1,50 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_HANDLE_REFERENCE_H_ -#define CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_HANDLE_REFERENCE_H_ - -#include <stdint.h> - -#include <memory> - -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "content/common/content_export.h" -#include "content/common/service_worker/service_worker_types.h" -#include "third_party/WebKit/common/service_worker/service_worker_object.mojom.h" - -namespace content { - -class ThreadSafeSender; - -// Represents an interprocess reference to ServiceWorkerHandle managed in the -// browser process. The constructor and destructor sends a message to increment -// or decrement the reference count to the browser process. -class CONTENT_EXPORT ServiceWorkerHandleReference { - public: - // Creates a new ServiceWorkerHandleReference by adopting a ref-count. If - // the handle id is kInvalidServiceWorkerHandleId, returns null instead. - static std::unique_ptr<ServiceWorkerHandleReference> Adopt( - blink::mojom::ServiceWorkerObjectInfoPtr info, - scoped_refptr<ThreadSafeSender> sender); - - ~ServiceWorkerHandleReference(); - - int handle_id() const { return info_->handle_id; } - const GURL& url() const { return info_->url; } - blink::mojom::ServiceWorkerState state() const { return info_->state; } - int64_t version_id() const { return info_->version_id; } - - private: - ServiceWorkerHandleReference(blink::mojom::ServiceWorkerObjectInfoPtr info, - scoped_refptr<ThreadSafeSender> sender); - blink::mojom::ServiceWorkerObjectInfoPtr info_; - scoped_refptr<ThreadSafeSender> sender_; - DISALLOW_COPY_AND_ASSIGN(ServiceWorkerHandleReference); -}; - -} // namespace content - -#endif // CONTENT_RENDERER_SERVICE_WORKER_SERVICE_WORKER_HANDLE_REFERENCE_H_
diff --git a/content/renderer/service_worker/service_worker_network_provider.cc b/content/renderer/service_worker/service_worker_network_provider.cc index 92c1059..3f9e54b 100644 --- a/content/renderer/service_worker/service_worker_network_provider.cc +++ b/content/renderer/service_worker/service_worker_network_provider.cc
@@ -16,7 +16,6 @@ #include "content/renderer/loader/request_extra_data.h" #include "content/renderer/render_thread_impl.h" #include "content/renderer/service_worker/service_worker_dispatcher.h" -#include "content/renderer/service_worker/service_worker_handle_reference.h" #include "content/renderer/service_worker/service_worker_provider_context.h" #include "ipc/ipc_sync_channel.h" #include "mojo/public/cpp/bindings/associated_group.h" @@ -327,7 +326,7 @@ info->provider_id, std::move(info->client_request), std::move(info->host_ptr_info)); context_->SetRegistrationForServiceWorkerGlobalScope( - std::move(info->registration), sender); + std::move(info->registration)); if (info->script_loader_factory_ptr_info.is_valid()) { script_loader_factory_.Bind(
diff --git a/content/renderer/service_worker/service_worker_provider_context.cc b/content/renderer/service_worker/service_worker_provider_context.cc index da91715..f552cc5 100644 --- a/content/renderer/service_worker/service_worker_provider_context.cc +++ b/content/renderer/service_worker/service_worker_provider_context.cc
@@ -19,7 +19,6 @@ #include "content/public/renderer/child_url_loader_factory_getter.h" #include "content/renderer/service_worker/controller_service_worker_connector.h" #include "content/renderer/service_worker/service_worker_dispatcher.h" -#include "content/renderer/service_worker/service_worker_handle_reference.h" #include "content/renderer/service_worker/service_worker_subresource_loader.h" #include "content/renderer/service_worker/web_service_worker_impl.h" #include "content/renderer/service_worker/web_service_worker_registration_impl.h" @@ -43,7 +42,7 @@ ~ProviderStateForClient() = default; // |controller| will be set by SetController() and taken by TakeController(). - std::unique_ptr<ServiceWorkerHandleReference> controller; + blink::mojom::ServiceWorkerObjectInfoPtr controller; // Keeps version id of the current controller service worker object. int64_t controller_version_id = blink::mojom::kInvalidServiceWorkerVersionId; @@ -89,12 +88,9 @@ struct ServiceWorkerProviderContext::ProviderStateForServiceWorker { ProviderStateForServiceWorker() = default; ~ProviderStateForServiceWorker() = default; - // These are valid until TakeRegistrationForServiceWorkerGlobalScope() is - // called. + // |registration| is set by SetRegistrationForServiceWorkerGlobalScope() and + // taken by TakeRegistrationForServiceWorkerGlobalScope(). blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration; - std::unique_ptr<ServiceWorkerHandleReference> installing; - std::unique_ptr<ServiceWorkerHandleReference> waiting; - std::unique_ptr<ServiceWorkerHandleReference> active; }; // For service worker clients. @@ -147,20 +143,11 @@ ServiceWorkerProviderContext::~ServiceWorkerProviderContext() = default; void ServiceWorkerProviderContext::SetRegistrationForServiceWorkerGlobalScope( - blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration, - scoped_refptr<ThreadSafeSender> sender) { + blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration) { DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence()); ProviderStateForServiceWorker* state = state_for_service_worker_.get(); DCHECK(state); DCHECK(!state->registration); - DCHECK(!state->installing && !state->waiting && !state->active); - - state->installing = ServiceWorkerHandleReference::Adopt( - std::move(registration->installing), sender); - state->waiting = ServiceWorkerHandleReference::Adopt( - std::move(registration->waiting), sender); - state->active = ServiceWorkerHandleReference::Adopt( - std::move(registration->active), sender); state->registration = std::move(registration); } @@ -177,24 +164,14 @@ DCHECK_NE(state->registration->registration_id, blink::mojom::kInvalidServiceWorkerRegistrationId); - ServiceWorkerDispatcher* dispatcher = - ServiceWorkerDispatcher::GetThreadSpecificInstance(); - DCHECK(dispatcher); DCHECK(state->registration->request.is_pending()); scoped_refptr<WebServiceWorkerRegistrationImpl> registration = WebServiceWorkerRegistrationImpl::CreateForServiceWorkerGlobalScope( std::move(state->registration), std::move(io_task_runner)); - registration->SetInstalling( - dispatcher->GetOrCreateServiceWorker(std::move(state->installing))); - registration->SetWaiting( - dispatcher->GetOrCreateServiceWorker(std::move(state->waiting))); - registration->SetActive( - dispatcher->GetOrCreateServiceWorker(std::move(state->active))); - return registration; } -std::unique_ptr<ServiceWorkerHandleReference> +blink::mojom::ServiceWorkerObjectInfoPtr ServiceWorkerProviderContext::TakeController() { DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence()); DCHECK(state_for_client_); @@ -278,15 +255,6 @@ ServiceWorkerDispatcher* dispatcher = ServiceWorkerDispatcher::GetThreadSpecificInstance(); DCHECK(dispatcher); - std::unique_ptr<ServiceWorkerHandleReference> installing = - ServiceWorkerHandleReference::Adopt(std::move(info->installing), - dispatcher->thread_safe_sender()); - std::unique_ptr<ServiceWorkerHandleReference> waiting = - ServiceWorkerHandleReference::Adopt(std::move(info->waiting), - dispatcher->thread_safe_sender()); - std::unique_ptr<ServiceWorkerHandleReference> active = - ServiceWorkerHandleReference::Adopt(std::move(info->active), - dispatcher->thread_safe_sender()); auto found = state_for_client_->registrations_.find(info->registration_id); if (found != state_for_client_->registrations_.end()) { @@ -302,13 +270,6 @@ scoped_refptr<WebServiceWorkerRegistrationImpl> registration = WebServiceWorkerRegistrationImpl::CreateForServiceWorkerClient( std::move(info), weak_factory_.GetWeakPtr()); - - registration->SetInstalling( - dispatcher->GetOrCreateServiceWorker(std::move(installing))); - registration->SetWaiting( - dispatcher->GetOrCreateServiceWorker(std::move(waiting))); - registration->SetActive( - dispatcher->GetOrCreateServiceWorker(std::move(active))); return registration; } @@ -336,22 +297,22 @@ DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence()); ProviderStateForClient* state = state_for_client_.get(); DCHECK(state); - DCHECK(!state->controller || state->controller->handle_id() != + DCHECK(!state->controller || state->controller->handle_id != blink::mojom::kInvalidServiceWorkerHandleId); - ServiceWorkerDispatcher* dispatcher = - ServiceWorkerDispatcher::GetThreadSpecificInstance(); auto& controller = controller_info->object_info; state->controller_version_id = controller->version_id; - state->controller = ServiceWorkerHandleReference::Adopt( - std::move(controller), dispatcher->thread_safe_sender()); + state->controller = + controller->handle_id != blink::mojom::kInvalidServiceWorkerHandleId + ? std::move(controller) + : nullptr; // Propagate the controller to workers related to this provider. if (state->controller) { for (const auto& worker : state->worker_clients) { // This is a Mojo interface call to the (dedicated or shared) worker // thread. - worker->SetControllerServiceWorker(state->controller->version_id()); + worker->SetControllerServiceWorker(state->controller->version_id); } } for (blink::mojom::WebFeature feature : used_features) @@ -406,17 +367,12 @@ const base::string16& message, std::vector<mojo::ScopedMessagePipeHandle> message_pipes) { DCHECK(main_thread_task_runner_->RunsTasksInCurrentSequence()); - ServiceWorkerDispatcher* dispatcher = - ServiceWorkerDispatcher::GetThreadSpecificInstance(); - std::unique_ptr<ServiceWorkerHandleReference> source_handle = - ServiceWorkerHandleReference::Adopt(std::move(source), - dispatcher->thread_safe_sender()); ProviderStateForClient* state = state_for_client_.get(); DCHECK(state); if (state->web_service_worker_provider) { state->web_service_worker_provider->PostMessageToClient( - std::move(source_handle), message, std::move(message_pipes)); + std::move(source), message, std::move(message_pipes)); } }
diff --git a/content/renderer/service_worker/service_worker_provider_context.h b/content/renderer/service_worker/service_worker_provider_context.h index 440315d..f6551f0 100644 --- a/content/renderer/service_worker/service_worker_provider_context.h +++ b/content/renderer/service_worker/service_worker_provider_context.h
@@ -37,7 +37,6 @@ class ServiceWorkerProviderContextTest; } // namespace service_worker_provider_context_unittest -class ServiceWorkerHandleReference; class WebServiceWorkerRegistrationImpl; struct ServiceWorkerProviderContextDeleter; @@ -100,22 +99,15 @@ // SetRegistrationForServiceWorkerGlobalScope() is called during the setup for // service worker startup, so it is guaranteed to be called before // TakeRegistrationForServiceWorkerGlobalScope(). - // |sender| is to initialize ServiceWorkerHandleReference which still needs to - // send legacy Incre/Decre IPCs, will disappear together with class - // ServiceWorkerHandleReference once ServiceWorkerObjectInfo starts to retain - // reference to ServiceWorkerHandle in the browser process. void SetRegistrationForServiceWorkerGlobalScope( - blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration, - scoped_refptr<ThreadSafeSender> sender); + blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration); // For service worker execution contexts. Used for initializing // ServiceWorkerGlobalScope#registration. Called on the worker thread. // This takes the registration that was passed to // SetRegistrationForServiceWorkerScope(), then creates a new // WebServiceWorkerRegistrationImpl instance and returns it. |io_task_runner| - // is used to initialize WebServiceWorkerRegistrationImpl. While creating the - // WebServiceWorkerRegistrationImpl, increments interprocess references to its - // versions via ServiceWorkerHandleReference. + // is used to initialize WebServiceWorkerRegistrationImpl. scoped_refptr<WebServiceWorkerRegistrationImpl> TakeRegistrationForServiceWorkerGlobalScope( scoped_refptr<base::SingleThreadTaskRunner> io_task_runner); @@ -124,9 +116,9 @@ // worker object (ServiceWorkerContainer#controller). int64_t GetControllerVersionId(); - // For service worker clients. Takes the controller service worker object set - // by SetController() if any, otherwise returns nullptr. - std::unique_ptr<ServiceWorkerHandleReference> TakeController(); + // For service worker clients. Takes the controller service worker object info + // set by SetController() if any, otherwise returns nullptr. + blink::mojom::ServiceWorkerObjectInfoPtr TakeController(); // S13nServiceWorker: // For service worker clients. Returns URLLoaderFactory for loading
diff --git a/content/renderer/service_worker/service_worker_provider_context_unittest.cc b/content/renderer/service_worker/service_worker_provider_context_unittest.cc index a5bc07b2..20a11b57 100644 --- a/content/renderer/service_worker/service_worker_provider_context_unittest.cc +++ b/content/renderer/service_worker/service_worker_provider_context_unittest.cc
@@ -21,7 +21,6 @@ #include "content/renderer/loader/child_url_loader_factory_getter_impl.h" #include "content/renderer/service_worker/controller_service_worker_connector.h" #include "content/renderer/service_worker/service_worker_dispatcher.h" -#include "content/renderer/service_worker/service_worker_handle_reference.h" #include "content/renderer/service_worker/service_worker_provider_context.h" #include "content/renderer/service_worker/web_service_worker_impl.h" #include "content/renderer/service_worker/web_service_worker_registration_impl.h" @@ -32,6 +31,7 @@ #include "services/network/public/interfaces/url_loader_factory.mojom.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/WebKit/common/service_worker/service_worker_error_type.mojom.h" +#include "third_party/WebKit/common/service_worker/service_worker_object.mojom.h" #include "third_party/WebKit/common/service_worker/service_worker_provider_type.mojom.h" #include "third_party/WebKit/common/service_worker/service_worker_registration.mojom.h" #include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerProviderClient.h" @@ -41,27 +41,55 @@ namespace content { namespace service_worker_provider_context_unittest { +class MockServiceWorkerObjectHost + : public blink::mojom::ServiceWorkerObjectHost { + public: + MockServiceWorkerObjectHost(int32_t handle_id, int64_t version_id) + : handle_id_(handle_id), version_id_(version_id) {} + ~MockServiceWorkerObjectHost() override = default; + + blink::mojom::ServiceWorkerObjectInfoPtr CreateObjectInfo() { + auto info = blink::mojom::ServiceWorkerObjectInfo::New(); + info->handle_id = handle_id_; + info->version_id = version_id_; + bindings_.AddBinding(this, mojo::MakeRequest(&info->host_ptr_info)); + return info; + } + + int GetBindingCount() const { return bindings_.size(); } + + private: + int32_t handle_id_; + int64_t version_id_; + mojo::AssociatedBindingSet<blink::mojom::ServiceWorkerObjectHost> bindings_; +}; + class MockServiceWorkerRegistrationObjectHost : public blink::mojom::ServiceWorkerRegistrationObjectHost { public: - MockServiceWorkerRegistrationObjectHost() { + explicit MockServiceWorkerRegistrationObjectHost(int64_t registration_id) + : registration_id_(registration_id) { bindings_.set_connection_error_handler( base::Bind(&MockServiceWorkerRegistrationObjectHost::OnConnectionError, base::Unretained(this))); } ~MockServiceWorkerRegistrationObjectHost() override = default; - void AddBinding( - blink::mojom::ServiceWorkerRegistrationObjectHostAssociatedRequest - request) { - bindings_.AddBinding(this, std::move(request)); - } + blink::mojom::ServiceWorkerRegistrationObjectInfoPtr CreateObjectInfo( + MockServiceWorkerObjectHost* active, + MockServiceWorkerObjectHost* waiting, + MockServiceWorkerObjectHost* installing) { + auto info = blink::mojom::ServiceWorkerRegistrationObjectInfo::New(); + info->registration_id = registration_id_; + bindings_.AddBinding(this, mojo::MakeRequest(&info->host_ptr_info)); + info->request = remote_registration_ + ? nullptr + : mojo::MakeRequest(&remote_registration_); - blink::mojom::ServiceWorkerRegistrationObjectAssociatedRequest - CreateRegistrationObjectRequest() { - if (!remote_registration_) - return mojo::MakeRequest(&remote_registration_); - return nullptr; + info->active = active->CreateObjectInfo(); + info->waiting = waiting->CreateObjectInfo(); + info->installing = installing->CreateObjectInfo(); + return info; } int GetBindingCount() const { return bindings_.size(); } @@ -103,6 +131,7 @@ remote_registration_.reset(); } + int64_t registration_id_; mojo::AssociatedBindingSet<blink::mojom::ServiceWorkerRegistrationObjectHost> bindings_; blink::mojom::ServiceWorkerRegistrationObjectAssociatedPtr @@ -256,27 +285,6 @@ std::move(fake_loader_factory), nullptr); } - blink::mojom::ServiceWorkerRegistrationObjectInfoPtr - CreateServiceWorkerRegistrationObjectInfo() { - auto info = blink::mojom::ServiceWorkerRegistrationObjectInfo::New(); - info->registration_id = 20; - remote_registration_object_host_.AddBinding( - mojo::MakeRequest(&info->host_ptr_info)); - info->request = - remote_registration_object_host_.CreateRegistrationObjectRequest(); - - info->active = blink::mojom::ServiceWorkerObjectInfo::New(); - info->active->handle_id = 100; - info->active->version_id = 200; - info->waiting = blink::mojom::ServiceWorkerObjectInfo::New(); - info->waiting->handle_id = 101; - info->waiting->version_id = 201; - info->installing = blink::mojom::ServiceWorkerObjectInfo::New(); - info->installing->handle_id = 102; - info->installing->version_id = 202; - return info; - } - void StartRequest(network::mojom::URLLoaderFactory* factory, const GURL& url) { network::ResourceRequest request; @@ -300,17 +308,12 @@ ThreadSafeSender* thread_safe_sender() { return sender_.get(); } IPC::TestSink* ipc_sink() { return &ipc_sink_; } - const MockServiceWorkerRegistrationObjectHost& - remote_registration_object_host() const { - return remote_registration_object_host_; - } protected: base::MessageLoop message_loop_; IPC::TestSink ipc_sink_; std::unique_ptr<ServiceWorkerDispatcher> dispatcher_; scoped_refptr<ServiceWorkerTestSender> sender_; - MockServiceWorkerRegistrationObjectHost remote_registration_object_host_; // S13nServiceWorker: base::test::ScopedFeatureList scoped_feature_list_; @@ -320,13 +323,31 @@ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerProviderContextTest); }; -TEST_F(ServiceWorkerProviderContextTest, CreateForController) { - // Assume that these objects are passed from the browser process and own - // references to browser-side registration/worker representations. +TEST_F(ServiceWorkerProviderContextTest, + CreateForServiceWorkerExecutionContext) { + auto active_host = std::make_unique<MockServiceWorkerObjectHost>( + 100 /* handle_id */, 200 /* version_id */); + auto waiting_host = std::make_unique<MockServiceWorkerObjectHost>( + 101 /* handle_id */, 201 /* version_id */); + auto installing_host = std::make_unique<MockServiceWorkerObjectHost>( + 102 /* handle_id */, 202 /* version_id */); + ASSERT_EQ(0, active_host->GetBindingCount()); + ASSERT_EQ(0, waiting_host->GetBindingCount()); + ASSERT_EQ(0, installing_host->GetBindingCount()); + auto mock_registration_object_host = + std::make_unique<MockServiceWorkerRegistrationObjectHost>( + 10 /* registration_id */); + ASSERT_EQ(0, mock_registration_object_host->GetBindingCount()); + blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration_info = - CreateServiceWorkerRegistrationObjectInfo(); + mock_registration_object_host->CreateObjectInfo( + active_host.get(), waiting_host.get(), installing_host.get()); // ServiceWorkerRegistrationObjectHost Mojo connection has been added. - ASSERT_EQ(1, remote_registration_object_host().GetBindingCount()); + EXPECT_EQ(1, mock_registration_object_host->GetBindingCount()); + // ServiceWorkerObjectHost Mojo connections have been added. + EXPECT_EQ(1, active_host->GetBindingCount()); + EXPECT_EQ(1, waiting_host->GetBindingCount()); + EXPECT_EQ(1, installing_host->GetBindingCount()); // Set up ServiceWorkerProviderContext for ServiceWorkerGlobalScope. const int kProviderId = 10; @@ -335,35 +356,32 @@ // The passed references should be adopted and owned by the provider context. provider_context->SetRegistrationForServiceWorkerGlobalScope( - std::move(registration_info), thread_safe_sender()); + std::move(registration_info)); EXPECT_EQ(0UL, ipc_sink()->message_count()); // Destruction of the provider context should release references to the // associated registration and its versions. provider_context = nullptr; - ASSERT_EQ(3UL, ipc_sink()->message_count()); - EXPECT_EQ(static_cast<uint32_t>( - ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID), - ipc_sink()->GetMessageAt(0)->type()); - EXPECT_EQ(static_cast<uint32_t>( - ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID), - ipc_sink()->GetMessageAt(1)->type()); - EXPECT_EQ(static_cast<uint32_t>( - ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID), - ipc_sink()->GetMessageAt(2)->type()); - // ServiceWorkerRegistrationObjectHost Mojo connection got broken. base::RunLoop().RunUntilIdle(); - EXPECT_EQ(0, remote_registration_object_host().GetBindingCount()); + // ServiceWorkerRegistrationObjectHost Mojo connection got broken. + EXPECT_EQ(0, mock_registration_object_host->GetBindingCount()); + // ServiceWorkerObjectHost Mojo connections got broken. + EXPECT_EQ(0, active_host->GetBindingCount()); + EXPECT_EQ(0, waiting_host->GetBindingCount()); + EXPECT_EQ(0, installing_host->GetBindingCount()); } TEST_F(ServiceWorkerProviderContextTest, SetController) { const int kProviderId = 10; { - // Assume that these objects are passed from the browser process and own - // references to browser-side registration/worker representations. - blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration_info = - CreateServiceWorkerRegistrationObjectInfo(); + auto mock_service_worker_object_host = + std::make_unique<MockServiceWorkerObjectHost>(100 /* handle_id */, + 200 /* version_id */); + ASSERT_EQ(0, mock_service_worker_object_host->GetBindingCount()); + blink::mojom::ServiceWorkerObjectInfoPtr worker_info = + mock_service_worker_object_host->CreateObjectInfo(); + EXPECT_EQ(1, mock_service_worker_object_host->GetBindingCount()); // (1) In the case there is no WebSWProviderClient but SWProviderContext for // the provider, the passed reference should be adopted and owned by the @@ -378,7 +396,7 @@ ipc_sink()->ClearMessages(); auto info = mojom::ControllerServiceWorkerInfo::New(); - info->object_info = std::move(registration_info->active); + info->object_info = std::move(worker_info); container_ptr->SetController(std::move(info), std::vector<blink::mojom::WebFeature>(), true); base::RunLoop().RunUntilIdle(); @@ -387,18 +405,20 @@ // Destruction of the provider context should release references to the // the controller. provider_context = nullptr; - ASSERT_EQ(1UL, ipc_sink()->message_count()); - EXPECT_EQ(static_cast<uint32_t>( - ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID), - ipc_sink()->GetMessageAt(0)->type()); + base::RunLoop().RunUntilIdle(); + // ServiceWorkerObjectHost Mojo connection got broken. + EXPECT_EQ(0, mock_service_worker_object_host->GetBindingCount()); ipc_sink()->ClearMessages(); } { - // Assume that these objects are passed from the browser process and own - // references to browser-side registration/worker representations. - blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration_info = - CreateServiceWorkerRegistrationObjectInfo(); + auto mock_service_worker_object_host = + std::make_unique<MockServiceWorkerObjectHost>(101 /* handle_id */, + 201 /* version_id */); + ASSERT_EQ(0, mock_service_worker_object_host->GetBindingCount()); + blink::mojom::ServiceWorkerObjectInfoPtr worker_info = + mock_service_worker_object_host->CreateObjectInfo(); + EXPECT_EQ(1, mock_service_worker_object_host->GetBindingCount()); // (2) In the case there are both SWProviderContext and SWProviderClient for // the provider, the passed reference should be adopted by the provider @@ -424,16 +444,14 @@ ipc_sink()->ClearMessages(); auto info = mojom::ControllerServiceWorkerInfo::New(); - info->object_info = std::move(registration_info->active); + info->object_info = std::move(worker_info); container_ptr->SetController(std::move(info), std::vector<blink::mojom::WebFeature>(), true); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(client->was_set_controller_called()); - ASSERT_EQ(1UL, ipc_sink()->message_count()); - EXPECT_EQ(static_cast<uint32_t>( - ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID), - ipc_sink()->GetMessageAt(0)->type()); + // ServiceWorkerObjectHost Mojo connection got broken. + EXPECT_EQ(0, mock_service_worker_object_host->GetBindingCount()); } } @@ -464,7 +482,7 @@ std::vector<blink::mojom::WebFeature>(), true); base::RunLoop().RunUntilIdle(); - EXPECT_EQ(nullptr, provider_context->TakeController()); + EXPECT_FALSE(provider_context->TakeController()); EXPECT_TRUE(client->was_set_controller_called()); } @@ -474,17 +492,25 @@ EnableS13nServiceWorker(); const int kProviderId = 10; - // Assume that these objects are passed from the browser process and own - // references to browser-side registration/worker representations. - blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration_info = - CreateServiceWorkerRegistrationObjectInfo(); + auto active_host = std::make_unique<MockServiceWorkerObjectHost>( + 100 /* handle_id */, 200 /* version_id */); + auto waiting_host = std::make_unique<MockServiceWorkerObjectHost>( + 101 /* handle_id */, 201 /* version_id */); + ASSERT_EQ(0, active_host->GetBindingCount()); + ASSERT_EQ(0, waiting_host->GetBindingCount()); + blink::mojom::ServiceWorkerObjectInfoPtr active_worker_info = + active_host->CreateObjectInfo(); + blink::mojom::ServiceWorkerObjectInfoPtr waiting_worker_info = + waiting_host->CreateObjectInfo(); + EXPECT_EQ(1, active_host->GetBindingCount()); + EXPECT_EQ(1, waiting_host->GetBindingCount()); // (1) Test if setting the controller via the CTOR works. FakeControllerServiceWorker fake_controller1; auto controller_info1 = mojom::ControllerServiceWorkerInfo::New(); mojom::ControllerServiceWorkerPtr controller_ptr1; fake_controller1.Clone(mojo::MakeRequest(&controller_ptr1)); - controller_info1->object_info = std::move(registration_info->active); + controller_info1->object_info = std::move(active_worker_info); controller_info1->endpoint = controller_ptr1.PassInterface(); mojom::ServiceWorkerContainerAssociatedPtr container_ptr; @@ -515,7 +541,7 @@ auto controller_info2 = mojom::ControllerServiceWorkerInfo::New(); mojom::ControllerServiceWorkerPtr controller_ptr2; fake_controller2.Clone(mojo::MakeRequest(&controller_ptr2)); - controller_info2->object_info = std::move(registration_info->waiting); + controller_info2->object_info = std::move(waiting_worker_info); controller_info2->endpoint = controller_ptr2.PassInterface(); container_ptr->SetController(std::move(controller_info2), std::vector<blink::mojom::WebFeature>(), true); @@ -524,10 +550,8 @@ // released. ipc_sink()->ClearMessages(); base::RunLoop().RunUntilIdle(); - EXPECT_EQ(1UL, ipc_sink()->message_count()); - EXPECT_EQ(static_cast<uint32_t>( - ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID), - ipc_sink()->GetMessageAt(0)->type()); + EXPECT_EQ(0UL, ipc_sink()->message_count()); + EXPECT_EQ(0, active_host->GetBindingCount()); // Subresource loader factory must be available, and should be the same // one as we got before. @@ -554,10 +578,8 @@ // released. ipc_sink()->ClearMessages(); base::RunLoop().RunUntilIdle(); - EXPECT_EQ(1UL, ipc_sink()->message_count()); - EXPECT_EQ(static_cast<uint32_t>( - ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID), - ipc_sink()->GetMessageAt(0)->type()); + EXPECT_EQ(0UL, ipc_sink()->message_count()); + EXPECT_EQ(0, waiting_host->GetBindingCount()); // Subresource loader factory must not be available. EXPECT_EQ(nullptr, provider_context->GetSubresourceLoaderFactory()); @@ -611,10 +633,13 @@ TEST_F(ServiceWorkerProviderContextTest, PostMessageToClient) { const int kProviderId = 10; - // Assume that these objects are passed from the browser process and own - // references to browser-side registration/worker representations. - blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration_info = - CreateServiceWorkerRegistrationObjectInfo(); + auto mock_service_worker_object_host = + std::make_unique<MockServiceWorkerObjectHost>(100 /* handle_id */, + 200 /* version_id */); + ASSERT_EQ(0, mock_service_worker_object_host->GetBindingCount()); + blink::mojom::ServiceWorkerObjectInfoPtr worker_info = + mock_service_worker_object_host->CreateObjectInfo(); + EXPECT_EQ(1, mock_service_worker_object_host->GetBindingCount()); mojom::ServiceWorkerContainerHostAssociatedPtrInfo host_ptr_info; mojom::ServiceWorkerContainerHostAssociatedRequest host_request = @@ -635,17 +660,14 @@ ipc_sink()->ClearMessages(); container_ptr->PostMessageToClient( - std::move(registration_info->active), base::string16(), + std::move(worker_info), base::string16(), std::vector<mojo::ScopedMessagePipeHandle>()); base::RunLoop().RunUntilIdle(); // The passed reference should be owned by the provider client (but the // reference is immediately released by the mock provider client). EXPECT_TRUE(client->was_dispatch_message_event_called()); - ASSERT_EQ(1UL, ipc_sink()->message_count()); - EXPECT_EQ(static_cast<uint32_t>( - ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID), - ipc_sink()->GetMessageAt(0)->type()); + EXPECT_EQ(0, mock_service_worker_object_host->GetBindingCount()); } TEST_F(ServiceWorkerProviderContextTest, CountFeature) { @@ -690,13 +712,33 @@ auto provider_context = base::MakeRefCounted<ServiceWorkerProviderContext>( kProviderId, nullptr, nullptr); - blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info = - CreateServiceWorkerRegistrationObjectInfo(); - int64_t registration_id = info->registration_id; - ASSERT_EQ(1, remote_registration_object_host().GetBindingCount()); + auto active_host = std::make_unique<MockServiceWorkerObjectHost>( + 100 /* handle_id */, 200 /* version_id */); + auto waiting_host = std::make_unique<MockServiceWorkerObjectHost>( + 101 /* handle_id */, 201 /* version_id */); + auto installing_host = std::make_unique<MockServiceWorkerObjectHost>( + 102 /* handle_id */, 202 /* version_id */); + ASSERT_EQ(0, active_host->GetBindingCount()); + ASSERT_EQ(0, waiting_host->GetBindingCount()); + ASSERT_EQ(0, installing_host->GetBindingCount()); + const int64_t registration_id = 10; + auto mock_registration_object_host = + std::make_unique<MockServiceWorkerRegistrationObjectHost>( + registration_id); + ASSERT_EQ(0, mock_registration_object_host->GetBindingCount()); + + blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration_info = + mock_registration_object_host->CreateObjectInfo( + active_host.get(), waiting_host.get(), installing_host.get()); + // ServiceWorkerRegistrationObjectHost Mojo connection has been added. + EXPECT_EQ(1, mock_registration_object_host->GetBindingCount()); + // ServiceWorkerObjectHost Mojo connections have been added. + EXPECT_EQ(1, active_host->GetBindingCount()); + EXPECT_EQ(1, waiting_host->GetBindingCount()); + EXPECT_EQ(1, installing_host->GetBindingCount()); provider_context->SetRegistrationForServiceWorkerGlobalScope( - std::move(info), thread_safe_sender()); + std::move(registration_info)); EXPECT_EQ(0UL, ipc_sink()->message_count()); // Should return a newly created registration object which adopts all @@ -707,31 +749,25 @@ blink::scheduler::GetSingleThreadTaskRunnerForTesting()); EXPECT_TRUE(registration); EXPECT_EQ(registration_id, registration->RegistrationId()); - EXPECT_EQ(1, remote_registration_object_host().GetBindingCount()); + EXPECT_EQ(1, mock_registration_object_host->GetBindingCount()); ASSERT_EQ(0UL, ipc_sink()->message_count()); ipc_sink()->ClearMessages(); // The registration dtor decrements the refcounts. registration = nullptr; - ASSERT_EQ(3UL, ipc_sink()->message_count()); - EXPECT_EQ(static_cast<uint32_t>( - ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID), - ipc_sink()->GetMessageAt(0)->type()); - EXPECT_EQ(static_cast<uint32_t>( - ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID), - ipc_sink()->GetMessageAt(1)->type()); - EXPECT_EQ(static_cast<uint32_t>( - ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID), - ipc_sink()->GetMessageAt(2)->type()); - // The Mojo connection has been dropped. + ASSERT_EQ(0UL, ipc_sink()->message_count()); base::RunLoop().RunUntilIdle(); - EXPECT_EQ(0, remote_registration_object_host().GetBindingCount()); + // ServiceWorkerRegistrationObjectHost Mojo connection got broken. + EXPECT_EQ(0, mock_registration_object_host->GetBindingCount()); + // ServiceWorkerObjectHost Mojo connections got broken. + EXPECT_EQ(0, active_host->GetBindingCount()); + EXPECT_EQ(0, waiting_host->GetBindingCount()); + EXPECT_EQ(0, installing_host->GetBindingCount()); } TEST_F(ServiceWorkerProviderContextTest, GetOrAdoptRegistration) { scoped_refptr<WebServiceWorkerRegistrationImpl> registration1; scoped_refptr<WebServiceWorkerRegistrationImpl> registration2; - int64_t registration_id = blink::mojom::kInvalidServiceWorkerRegistrationId; // Set up ServiceWorkerProviderContext for ServiceWorkerGlobalScope. const int kProviderId = 10; auto provider_context = base::MakeRefCounted<ServiceWorkerProviderContext>( @@ -739,54 +775,75 @@ nullptr, nullptr /* controller_info */, nullptr /* loader_factory_getter */); + auto active_host = std::make_unique<MockServiceWorkerObjectHost>( + 100 /* handle_id */, 200 /* version_id */); + auto waiting_host = std::make_unique<MockServiceWorkerObjectHost>( + 101 /* handle_id */, 201 /* version_id */); + auto installing_host = std::make_unique<MockServiceWorkerObjectHost>( + 102 /* handle_id */, 202 /* version_id */); + ASSERT_EQ(0, active_host->GetBindingCount()); + ASSERT_EQ(0, waiting_host->GetBindingCount()); + ASSERT_EQ(0, installing_host->GetBindingCount()); + const int64_t registration_id = 10; + auto mock_registration_object_host = + std::make_unique<MockServiceWorkerRegistrationObjectHost>( + registration_id); + ASSERT_EQ(0, mock_registration_object_host->GetBindingCount()); + { - blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info = - CreateServiceWorkerRegistrationObjectInfo(); - registration_id = info->registration_id; - // The 1st ServiceWorkerRegistrationObjectHost Mojo connection has been - // added. - ASSERT_EQ(1, remote_registration_object_host().GetBindingCount()); + blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration_info = + mock_registration_object_host->CreateObjectInfo( + active_host.get(), waiting_host.get(), installing_host.get()); + // ServiceWorkerRegistrationObjectHost Mojo connection has been added. + EXPECT_EQ(1, mock_registration_object_host->GetBindingCount()); + // ServiceWorkerObjectHost Mojo connections have been added. + EXPECT_EQ(1, active_host->GetBindingCount()); + EXPECT_EQ(1, waiting_host->GetBindingCount()); + EXPECT_EQ(1, installing_host->GetBindingCount()); ASSERT_FALSE(ContainsRegistration(provider_context.get(), registration_id)); // Should return a registration object newly created with adopting the // refcounts. registration1 = provider_context->GetOrCreateRegistrationForServiceWorkerClient( - std::move(info)); + std::move(registration_info)); EXPECT_TRUE(registration1); EXPECT_TRUE(ContainsRegistration(provider_context.get(), registration_id)); EXPECT_EQ(registration_id, registration1->RegistrationId()); - EXPECT_EQ(1, remote_registration_object_host().GetBindingCount()); + EXPECT_EQ(1, mock_registration_object_host->GetBindingCount()); EXPECT_EQ(0UL, ipc_sink()->message_count()); } ipc_sink()->ClearMessages(); { - blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info = - CreateServiceWorkerRegistrationObjectInfo(); - // The 2nd Mojo connection has been added. - ASSERT_EQ(2, remote_registration_object_host().GetBindingCount()); + blink::mojom::ServiceWorkerRegistrationObjectInfoPtr registration_info = + mock_registration_object_host->CreateObjectInfo( + active_host.get(), waiting_host.get(), installing_host.get()); + // ServiceWorkerRegistrationObjectHost Mojo connection has been added. + EXPECT_EQ(2, mock_registration_object_host->GetBindingCount()); + // ServiceWorkerObjectHost Mojo connections have been added. + EXPECT_EQ(2, active_host->GetBindingCount()); + EXPECT_EQ(2, waiting_host->GetBindingCount()); + EXPECT_EQ(2, installing_host->GetBindingCount()); + // Should return the same registration object without incrementing the // refcounts. registration2 = provider_context->GetOrCreateRegistrationForServiceWorkerClient( - std::move(info)); + std::move(registration_info)); EXPECT_TRUE(registration2); EXPECT_EQ(registration1, registration2); - // The 2nd Mojo connection has been dropped. base::RunLoop().RunUntilIdle(); - EXPECT_EQ(1, remote_registration_object_host().GetBindingCount()); - ASSERT_EQ(3UL, ipc_sink()->message_count()); - EXPECT_EQ(static_cast<uint32_t>( - ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID), - ipc_sink()->GetMessageAt(0)->type()); - EXPECT_EQ(static_cast<uint32_t>( - ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID), - ipc_sink()->GetMessageAt(1)->type()); - EXPECT_EQ(static_cast<uint32_t>( - ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID), - ipc_sink()->GetMessageAt(2)->type()); + ASSERT_EQ(0UL, ipc_sink()->message_count()); + // The 2nd ServiceWorkerRegistrationObjectHost Mojo connection has been + // dropped. + EXPECT_EQ(1, mock_registration_object_host->GetBindingCount()); + // The corresponding ServiceWorkerObjectHost Mojo connections have been + // dropped. + EXPECT_EQ(1, active_host->GetBindingCount()); + EXPECT_EQ(1, waiting_host->GetBindingCount()); + EXPECT_EQ(1, installing_host->GetBindingCount()); } ipc_sink()->ClearMessages(); @@ -794,20 +851,15 @@ // The registration dtor decrements the refcounts. registration1 = nullptr; registration2 = nullptr; - ASSERT_EQ(3UL, ipc_sink()->message_count()); - EXPECT_EQ(static_cast<uint32_t>( - ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID), - ipc_sink()->GetMessageAt(0)->type()); - EXPECT_EQ(static_cast<uint32_t>( - ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID), - ipc_sink()->GetMessageAt(1)->type()); - EXPECT_EQ(static_cast<uint32_t>( - ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID), - ipc_sink()->GetMessageAt(2)->type()); - // The 1st Mojo connection has been dropped. base::RunLoop().RunUntilIdle(); EXPECT_FALSE(ContainsRegistration(provider_context.get(), registration_id)); - EXPECT_EQ(0, remote_registration_object_host().GetBindingCount()); + ASSERT_EQ(0UL, ipc_sink()->message_count()); + // The 1st ServiceWorkerRegistrationObjectHost Mojo connection got broken. + EXPECT_EQ(0, mock_registration_object_host->GetBindingCount()); + // The corresponding ServiceWorkerObjectHost Mojo connections got broken. + EXPECT_EQ(0, active_host->GetBindingCount()); + EXPECT_EQ(0, waiting_host->GetBindingCount()); + EXPECT_EQ(0, installing_host->GetBindingCount()); } } // namespace service_worker_provider_context_unittest
diff --git a/content/renderer/service_worker/service_worker_timeout_timer.cc b/content/renderer/service_worker/service_worker_timeout_timer.cc index b6e0abd..669134f 100644 --- a/content/renderer/service_worker/service_worker_timeout_timer.cc +++ b/content/renderer/service_worker/service_worker_timeout_timer.cc
@@ -113,6 +113,9 @@ iter = inflight_events_.erase(iter); id_event_map_.erase(event_id); std::move(callback).Run(); + // Shut down the worker as soon as possible since the worker may have gone + // into bad state. + zero_idle_timer_delay_ = true; } // If |inflight_events_| is empty, the worker is now idle.
diff --git a/content/renderer/service_worker/service_worker_timeout_timer.h b/content/renderer/service_worker/service_worker_timeout_timer.h index 7d657a1..f134353 100644 --- a/content/renderer/service_worker/service_worker_timeout_timer.h +++ b/content/renderer/service_worker/service_worker_timeout_timer.h
@@ -28,7 +28,9 @@ // S13nServiceWorker: // 1) Event timeout: when an event starts, StartEvent() records the expiration // time of the event (kEventTimeout). If EndEvent() has not been called within -// the timeout time, |abort_callback| passed to StartEvent() is called. +// the timeout time, |abort_callback| passed to StartEvent() is called. Also, +// |zero_idle_timer_delay_| is set to true to shut down the worker as soon as +// possible since the worker may have gone into bad state. // 2) Idle timeout: when a certain time has passed (kIdleDelay) since all of // events have ended, ServiceWorkerTimeoutTimer calls the |idle_callback|. // |idle_callback| will be continuously called at a certain interval
diff --git a/content/renderer/service_worker/service_worker_timeout_timer_unittest.cc b/content/renderer/service_worker/service_worker_timeout_timer_unittest.cc index ff3af3ae..90997c76 100644 --- a/content/renderer/service_worker/service_worker_timeout_timer_unittest.cc +++ b/content/renderer/service_worker/service_worker_timeout_timer_unittest.cc
@@ -148,11 +148,9 @@ ServiceWorkerTimeoutTimer::kUpdateInterval + base::TimeDelta::FromSeconds(1)); + // |event| should have been aborted, and at the same time, the idle timeout + // should also be fired since there has been an aborted event. EXPECT_TRUE(event.has_aborted()); - EXPECT_FALSE(is_idle); - task_runner()->FastForwardBy(ServiceWorkerTimeoutTimer::kIdleDelay + - base::TimeDelta::FromSeconds(1)); - EXPECT_TRUE(is_idle); }
diff --git a/content/renderer/service_worker/web_service_worker_impl.cc b/content/renderer/service_worker/web_service_worker_impl.cc index c078c10b..560f5ddc 100644 --- a/content/renderer/service_worker/web_service_worker_impl.cc +++ b/content/renderer/service_worker/web_service_worker_impl.cc
@@ -11,9 +11,7 @@ #include "content/child/thread_safe_sender.h" #include "content/common/service_worker/service_worker_messages.h" #include "content/renderer/service_worker/service_worker_dispatcher.h" -#include "content/renderer/service_worker/service_worker_handle_reference.h" #include "content/renderer/service_worker/web_service_worker_provider_impl.h" -#include "third_party/WebKit/common/service_worker/service_worker_object.mojom.h" #include "third_party/WebKit/public/platform/WebRuntimeFeatures.h" #include "third_party/WebKit/public/platform/WebSecurityOrigin.h" #include "third_party/WebKit/public/platform/WebString.h" @@ -44,18 +42,17 @@ } // namespace WebServiceWorkerImpl::WebServiceWorkerImpl( - std::unique_ptr<ServiceWorkerHandleReference> handle_ref, + blink::mojom::ServiceWorkerObjectInfoPtr info, ThreadSafeSender* thread_safe_sender) - : handle_ref_(std::move(handle_ref)), - state_(handle_ref_->state()), + : info_(std::move(info)), + state_(info_->state), thread_safe_sender_(thread_safe_sender), proxy_(nullptr) { - DCHECK_NE(blink::mojom::kInvalidServiceWorkerHandleId, - handle_ref_->handle_id()); + DCHECK_NE(blink::mojom::kInvalidServiceWorkerHandleId, info_->handle_id); ServiceWorkerDispatcher* dispatcher = ServiceWorkerDispatcher::GetThreadSpecificInstance(); DCHECK(dispatcher); - dispatcher->AddServiceWorker(handle_ref_->handle_id(), this); + dispatcher->AddServiceWorker(info_->handle_id, this); } void WebServiceWorkerImpl::OnStateChanged( @@ -77,7 +74,7 @@ } blink::WebURL WebServiceWorkerImpl::Url() const { - return handle_ref_->url(); + return info_->url; } blink::mojom::ServiceWorkerState WebServiceWorkerImpl::GetState() const { @@ -90,14 +87,14 @@ const WebSecurityOrigin& source_origin, blink::WebVector<blink::MessagePortChannel> channels) { thread_safe_sender_->Send(new ServiceWorkerHostMsg_PostMessageToWorker( - handle_ref_->handle_id(), + info_->handle_id, static_cast<WebServiceWorkerProviderImpl*>(provider)->provider_id(), message.Utf16(), url::Origin(source_origin), channels.ReleaseVector())); } void WebServiceWorkerImpl::Terminate() { thread_safe_sender_->Send( - new ServiceWorkerHostMsg_TerminateWorker(handle_ref_->handle_id())); + new ServiceWorkerHostMsg_TerminateWorker(info_->handle_id)); } // static @@ -113,7 +110,7 @@ ServiceWorkerDispatcher* dispatcher = ServiceWorkerDispatcher::GetThreadSpecificInstance(); if (dispatcher) - dispatcher->RemoveServiceWorker(handle_ref_->handle_id()); + dispatcher->RemoveServiceWorker(info_->handle_id); } } // namespace content
diff --git a/content/renderer/service_worker/web_service_worker_impl.h b/content/renderer/service_worker/web_service_worker_impl.h index 0bba378..9c4fd16c 100644 --- a/content/renderer/service_worker/web_service_worker_impl.h +++ b/content/renderer/service_worker/web_service_worker_impl.h
@@ -13,6 +13,7 @@ #include "base/memory/ref_counted.h" #include "base/strings/string16.h" #include "content/common/content_export.h" +#include "third_party/WebKit/common/service_worker/service_worker_object.mojom.h" #include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorker.h" #include "third_party/WebKit/public/web/WebFrame.h" @@ -22,21 +23,21 @@ namespace content { -class ServiceWorkerHandleReference; class ThreadSafeSender; // Each instance corresponds to one ServiceWorker object in JS context, and // is held by ServiceWorker object in Blink's C++ layer via // WebServiceWorker::Handle. // -// Each instance holds one ServiceWorkerHandleReference so that -// corresponding ServiceWorkerHandle doesn't go away in the browser process -// while the ServiceWorker object is alive. +// Each instance holds one Mojo connection for interface +// blink::mojom::ServiceWorkerObjectHost inside |info_|, so the corresponding +// ServiceWorkerHandle doesn't go away in the browser process while the +// ServiceWorker object is alive. class CONTENT_EXPORT WebServiceWorkerImpl : public blink::WebServiceWorker, public base::RefCounted<WebServiceWorkerImpl> { public: - WebServiceWorkerImpl(std::unique_ptr<ServiceWorkerHandleReference> handle_ref, + WebServiceWorkerImpl(blink::mojom::ServiceWorkerObjectInfoPtr info, ThreadSafeSender* thread_safe_sender); void OnStateChanged(blink::mojom::ServiceWorkerState new_state); @@ -62,7 +63,7 @@ friend class base::RefCounted<WebServiceWorkerImpl>; ~WebServiceWorkerImpl() override; - std::unique_ptr<ServiceWorkerHandleReference> handle_ref_; + blink::mojom::ServiceWorkerObjectInfoPtr info_; blink::mojom::ServiceWorkerState state_; scoped_refptr<ThreadSafeSender> thread_safe_sender_; blink::WebServiceWorkerProxy* proxy_;
diff --git a/content/renderer/service_worker/web_service_worker_provider_impl.cc b/content/renderer/service_worker/web_service_worker_provider_impl.cc index 8264f15..9a0fc62 100644 --- a/content/renderer/service_worker/web_service_worker_provider_impl.cc +++ b/content/renderer/service_worker/web_service_worker_provider_impl.cc
@@ -12,7 +12,6 @@ #include "content/child/thread_safe_sender.h" #include "content/common/service_worker/service_worker_utils.h" #include "content/renderer/service_worker/service_worker_dispatcher.h" -#include "content/renderer/service_worker/service_worker_handle_reference.h" #include "content/renderer/service_worker/service_worker_provider_context.h" #include "content/renderer/service_worker/web_service_worker_impl.h" #include "content/renderer/service_worker/web_service_worker_registration_impl.h" @@ -64,9 +63,10 @@ if (!provider_client_) return; - std::unique_ptr<ServiceWorkerHandleReference> controller = + blink::mojom::ServiceWorkerObjectInfoPtr controller = context_->TakeController(); - if (!controller) + if (!controller || + controller->handle_id == blink::mojom::kInvalidServiceWorkerHandleId) return; SetController(std::move(controller), context_->used_features(), false /* notify_controllerchange */); @@ -190,7 +190,7 @@ } void WebServiceWorkerProviderImpl::SetController( - std::unique_ptr<ServiceWorkerHandleReference> controller, + blink::mojom::ServiceWorkerObjectInfoPtr controller, const std::set<blink::mojom::WebFeature>& features, bool should_notify_controller_change) { if (!provider_client_) @@ -205,14 +205,14 @@ } void WebServiceWorkerProviderImpl::PostMessageToClient( - std::unique_ptr<ServiceWorkerHandleReference> source_handle, + blink::mojom::ServiceWorkerObjectInfoPtr source, const base::string16& message, std::vector<mojo::ScopedMessagePipeHandle> message_pipes) { if (!provider_client_) return; scoped_refptr<WebServiceWorkerImpl> source_worker = - GetDispatcher()->GetOrCreateServiceWorker(std::move(source_handle)); + GetDispatcher()->GetOrCreateServiceWorker(std::move(source)); auto message_ports = blink::MessagePortChannel::CreateFromHandles(std::move(message_pipes)); provider_client_->DispatchMessageEvent(
diff --git a/content/renderer/service_worker/web_service_worker_provider_impl.h b/content/renderer/service_worker/web_service_worker_provider_impl.h index ef1ed83..1ff7906 100644 --- a/content/renderer/service_worker/web_service_worker_provider_impl.h +++ b/content/renderer/service_worker/web_service_worker_provider_impl.h
@@ -25,7 +25,6 @@ namespace content { class ServiceWorkerDispatcher; -class ServiceWorkerHandleReference; class ServiceWorkerProviderContext; class ThreadSafeSender; @@ -59,13 +58,13 @@ blink::WebString* error_message) override; // Sets the ServiceWorkerContainer#controller for this provider. It's not // used when this WebServiceWorkerProvider is for a service worker context. - void SetController(std::unique_ptr<ServiceWorkerHandleReference> controller, + void SetController(blink::mojom::ServiceWorkerObjectInfoPtr controller, const std::set<blink::mojom::WebFeature>& features, bool should_notify_controller_change); // Posts a message to the ServiceWorkerContainer for this provider. // Corresponds to Client#postMessage(). void PostMessageToClient( - std::unique_ptr<ServiceWorkerHandleReference> source_handle, + blink::mojom::ServiceWorkerObjectInfoPtr source, const base::string16& message, std::vector<mojo::ScopedMessagePipeHandle> message_pipes); // For UseCounter purposes. Called when the controller service worker used a
diff --git a/content/renderer/service_worker/web_service_worker_registration_impl.cc b/content/renderer/service_worker/web_service_worker_registration_impl.cc index 0e769d0..9cca686 100644 --- a/content/renderer/service_worker/web_service_worker_registration_impl.cc +++ b/content/renderer/service_worker/web_service_worker_registration_impl.cc
@@ -14,7 +14,6 @@ #include "content/child/child_process.h" #include "content/common/service_worker/service_worker_types.h" #include "content/renderer/service_worker/service_worker_dispatcher.h" -#include "content/renderer/service_worker/service_worker_handle_reference.h" #include "content/renderer/service_worker/service_worker_provider_context.h" #include "content/renderer/service_worker/web_service_worker_impl.h" #include "content/renderer/service_worker/web_service_worker_provider_impl.h" @@ -148,6 +147,7 @@ base::Unretained(impl.get()), std::move(impl->info_->request))); impl->state_ = LifecycleState::kAttachedAndBound; + impl->RefreshVersionAttributes(); return impl; } @@ -163,6 +163,7 @@ impl->host_for_client_.Bind(std::move(impl->info_->host_ptr_info)); impl->BindRequest(std::move(impl->info_->request)); impl->state_ = LifecycleState::kAttachedAndBound; + impl->RefreshVersionAttributes(); return impl; } @@ -178,39 +179,7 @@ DCHECK(!host_for_client_); host_for_client_.Bind(std::move(info_->host_ptr_info)); state_ = LifecycleState::kAttachedAndBound; -} - -void WebServiceWorkerRegistrationImpl::SetInstalling( - const scoped_refptr<WebServiceWorkerImpl>& service_worker) { - if (state_ == LifecycleState::kDetached) - return; - DCHECK_EQ(LifecycleState::kAttachedAndBound, state_); - if (proxy_) - proxy_->SetInstalling(WebServiceWorkerImpl::CreateHandle(service_worker)); - else - queued_tasks_.push_back(QueuedTask(INSTALLING, service_worker)); -} - -void WebServiceWorkerRegistrationImpl::SetWaiting( - const scoped_refptr<WebServiceWorkerImpl>& service_worker) { - if (state_ == LifecycleState::kDetached) - return; - DCHECK_EQ(LifecycleState::kAttachedAndBound, state_); - if (proxy_) - proxy_->SetWaiting(WebServiceWorkerImpl::CreateHandle(service_worker)); - else - queued_tasks_.push_back(QueuedTask(WAITING, service_worker)); -} - -void WebServiceWorkerRegistrationImpl::SetActive( - const scoped_refptr<WebServiceWorkerImpl>& service_worker) { - if (state_ == LifecycleState::kDetached) - return; - DCHECK_EQ(LifecycleState::kAttachedAndBound, state_); - if (proxy_) - proxy_->SetActive(WebServiceWorkerImpl::CreateHandle(service_worker)); - else - queued_tasks_.push_back(QueuedTask(ACTIVE, service_worker)); + RefreshVersionAttributes(); } void WebServiceWorkerRegistrationImpl::SetProxy( @@ -461,6 +430,66 @@ registration_id_); } +void WebServiceWorkerRegistrationImpl::SetInstalling( + blink::mojom::ServiceWorkerObjectInfoPtr info) { + if (state_ == LifecycleState::kDetached) + return; + DCHECK_EQ(LifecycleState::kAttachedAndBound, state_); + + ServiceWorkerDispatcher* dispatcher = + ServiceWorkerDispatcher::GetThreadSpecificInstance(); + DCHECK(dispatcher); + scoped_refptr<WebServiceWorkerImpl> service_worker = + dispatcher->GetOrCreateServiceWorker(std::move(info)); + if (proxy_) + proxy_->SetInstalling(WebServiceWorkerImpl::CreateHandle(service_worker)); + else + queued_tasks_.push_back(QueuedTask(INSTALLING, service_worker)); +} + +void WebServiceWorkerRegistrationImpl::SetWaiting( + blink::mojom::ServiceWorkerObjectInfoPtr info) { + if (state_ == LifecycleState::kDetached) + return; + DCHECK_EQ(LifecycleState::kAttachedAndBound, state_); + + ServiceWorkerDispatcher* dispatcher = + ServiceWorkerDispatcher::GetThreadSpecificInstance(); + DCHECK(dispatcher); + scoped_refptr<WebServiceWorkerImpl> service_worker = + dispatcher->GetOrCreateServiceWorker(std::move(info)); + if (proxy_) + proxy_->SetWaiting(WebServiceWorkerImpl::CreateHandle(service_worker)); + else + queued_tasks_.push_back(QueuedTask(WAITING, service_worker)); +} + +void WebServiceWorkerRegistrationImpl::SetActive( + blink::mojom::ServiceWorkerObjectInfoPtr info) { + if (state_ == LifecycleState::kDetached) + return; + DCHECK_EQ(LifecycleState::kAttachedAndBound, state_); + + ServiceWorkerDispatcher* dispatcher = + ServiceWorkerDispatcher::GetThreadSpecificInstance(); + DCHECK(dispatcher); + scoped_refptr<WebServiceWorkerImpl> service_worker = + dispatcher->GetOrCreateServiceWorker(std::move(info)); + if (proxy_) + proxy_->SetActive(WebServiceWorkerImpl::CreateHandle(service_worker)); + else + queued_tasks_.push_back(QueuedTask(ACTIVE, service_worker)); +} + +void WebServiceWorkerRegistrationImpl::RefreshVersionAttributes() { + DCHECK(info_->installing); + SetInstalling(std::move(info_->installing)); + DCHECK(info_->waiting); + SetWaiting(std::move(info_->waiting)); + DCHECK(info_->active); + SetActive(std::move(info_->active)); +} + void WebServiceWorkerRegistrationImpl::SetVersionAttributes( int changed_mask, blink::mojom::ServiceWorkerObjectInfoPtr installing, @@ -487,21 +516,15 @@ ChangedVersionAttributesMask mask(changed_mask); if (mask.installing_changed()) { DCHECK(installing); - SetInstalling(dispatcher->GetOrCreateServiceWorker( - ServiceWorkerHandleReference::Adopt(std::move(installing), - dispatcher->thread_safe_sender()))); + SetInstalling(std::move(installing)); } if (mask.waiting_changed()) { DCHECK(waiting); - SetWaiting(dispatcher->GetOrCreateServiceWorker( - ServiceWorkerHandleReference::Adopt(std::move(waiting), - dispatcher->thread_safe_sender()))); + SetWaiting(std::move(waiting)); } if (mask.active_changed()) { DCHECK(active); - SetActive(dispatcher->GetOrCreateServiceWorker( - ServiceWorkerHandleReference::Adopt(std::move(active), - dispatcher->thread_safe_sender()))); + SetActive(std::move(active)); } }
diff --git a/content/renderer/service_worker/web_service_worker_registration_impl.h b/content/renderer/service_worker/web_service_worker_registration_impl.h index 04dbd38..fedd009 100644 --- a/content/renderer/service_worker/web_service_worker_registration_impl.h +++ b/content/renderer/service_worker/web_service_worker_registration_impl.h
@@ -17,6 +17,7 @@ #include "content/common/content_export.h" #include "mojo/public/cpp/bindings/associated_binding.h" #include "third_party/WebKit/common/service_worker/service_worker_error_type.mojom.h" +#include "third_party/WebKit/common/service_worker/service_worker_object.mojom.h" #include "third_party/WebKit/common/service_worker/service_worker_registration.mojom.h" #include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWorkerRegistration.h" @@ -94,10 +95,6 @@ void AttachForServiceWorkerClient( blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info); - void SetInstalling(const scoped_refptr<WebServiceWorkerImpl>& service_worker); - void SetWaiting(const scoped_refptr<WebServiceWorkerImpl>& service_worker); - void SetActive(const scoped_refptr<WebServiceWorkerImpl>& service_worker); - // blink::WebServiceWorkerRegistration overrides. void SetProxy(blink::WebServiceWorkerRegistrationProxy* proxy) override; blink::WebServiceWorkerRegistrationProxy* Proxy() override; @@ -132,6 +129,13 @@ base::WeakPtr<ServiceWorkerProviderContext> provider_context); ~WebServiceWorkerRegistrationImpl() override; + void SetInstalling(blink::mojom::ServiceWorkerObjectInfoPtr info); + void SetWaiting(blink::mojom::ServiceWorkerObjectInfoPtr info); + void SetActive(blink::mojom::ServiceWorkerObjectInfoPtr info); + // Refreshes the JavaScript ServiceWorkerRegistration object (|proxy_|) with + // the {installing,waiting,active} service worker object infos from |info_|. + void RefreshVersionAttributes(); + // Implements blink::mojom::ServiceWorkerRegistrationObject. void SetVersionAttributes( int changed_mask,
diff --git a/content/renderer/shared_worker/embedded_shared_worker_stub.cc b/content/renderer/shared_worker/embedded_shared_worker_stub.cc index 0a4f82d..746ce45 100644 --- a/content/renderer/shared_worker/embedded_shared_worker_stub.cc +++ b/content/renderer/shared_worker/embedded_shared_worker_stub.cc
@@ -22,7 +22,6 @@ #include "content/renderer/loader/request_extra_data.h" #include "content/renderer/render_thread_impl.h" #include "content/renderer/renderer_blink_platform_impl.h" -#include "content/renderer/service_worker/service_worker_handle_reference.h" #include "content/renderer/service_worker/service_worker_network_provider.h" #include "content/renderer/service_worker/service_worker_provider_context.h" #include "content/renderer/service_worker/worker_fetch_context_impl.h"
diff --git a/content/shell/android/shell_apk/src/org/chromium/content_shell_apk/ContentShellApplication.java b/content/shell/android/shell_apk/src/org/chromium/content_shell_apk/ContentShellApplication.java index 9384f7b..d9846520 100644 --- a/content/shell/android/shell_apk/src/org/chromium/content_shell_apk/ContentShellApplication.java +++ b/content/shell/android/shell_apk/src/org/chromium/content_shell_apk/ContentShellApplication.java
@@ -7,17 +7,16 @@ import android.content.Context; import org.chromium.base.ApplicationStatus; +import org.chromium.base.BaseChromiumApplication; import org.chromium.base.CommandLine; import org.chromium.base.ContextUtils; import org.chromium.base.PathUtils; -import org.chromium.content.app.ContentApplication; /** * Entry point for the content shell application. Handles initialization of information that needs * to be shared across the main activity and the child services created. */ -public class ContentShellApplication extends ContentApplication { - +public class ContentShellApplication extends BaseChromiumApplication { public static final String COMMAND_LINE_FILE = "/data/local/tmp/content-shell-command-line"; private static final String PRIVATE_DATA_DIRECTORY_SUFFIX = "content_shell";
diff --git a/content/shell/browser/layout_test/layout_test_browser_main.cc b/content/shell/browser/layout_test/layout_test_browser_main.cc index 289894f..90c85a0d 100644 --- a/content/shell/browser/layout_test/layout_test_browser_main.cc +++ b/content/shell/browser/layout_test/layout_test_browser_main.cc
@@ -88,9 +88,8 @@ std::cout << "#READY\n"; std::cout.flush(); - base::CommandLine::StringVector args = - base::CommandLine::ForCurrentProcess()->GetArgs(); - content::TestInfoExtractor test_extractor(args); + content::TestInfoExtractor test_extractor( + *base::CommandLine::ForCurrentProcess()); bool ran_at_least_once = false; std::unique_ptr<content::TestInfo> test_info; while ((test_info = test_extractor.GetNextTest())) {
diff --git a/content/shell/browser/layout_test/test_info_extractor.cc b/content/shell/browser/layout_test/test_info_extractor.cc index 9804e95d..2f3aaa2 100644 --- a/content/shell/browser/layout_test/test_info_extractor.cc +++ b/content/shell/browser/layout_test/test_info_extractor.cc
@@ -15,6 +15,14 @@ #include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "net/base/filename_util.h" +#include "net/base/ip_address.h" +#include "net/base/ip_endpoint.h" +#include "net/base/url_util.h" + +#if defined(OS_FUCHSIA) +#include <sys/socket.h> +#include <unistd.h> +#endif namespace content { @@ -42,6 +50,43 @@ } #endif // defined(OS_ANDROID) +#if defined(OS_FUCHSIA) +// Fuchsia doesn't support stdin stream for packaged apps. This means that when +// running content_shell on Fuchsia it's not possible to use stdin to pass list +// of tests. To workaround this issue for layout tests we redirect stdin stream +// to a TCP socket connected to the layout test runner. The runner uses +// --stdin-redirect to specify address and port for stdin redirection. +constexpr char kStdinRedirectSwitch[] = "stdin-redirect"; + +void ConnectStdinSocket(const std::string& host_and_port) { + std::string host; + int port; + net::IPAddress address; + if (!net::ParseHostAndPort(host_and_port, &host, &port) || + !address.AssignFromIPLiteral(host)) { + LOG(FATAL) << "Invalid stdin address: " << host_and_port; + } + + sockaddr_storage sockaddr_storage; + sockaddr* addr = reinterpret_cast<sockaddr*>(&sockaddr_storage); + socklen_t addr_len = sizeof(sockaddr_storage); + net::IPEndPoint endpoint(address, port); + bool converted = endpoint.ToSockAddr(addr, &addr_len); + CHECK(converted); + + int fd = socket(addr->sa_family, SOCK_STREAM, 0); + PCHECK(fd >= 0); + int result = connect(fd, addr, addr_len); + PCHECK(result == 0) << "Failed to connect to " << host_and_port; + + result = dup2(fd, STDIN_FILENO); + PCHECK(result == STDIN_FILENO) << "Failed to dup socket to stdin"; + + PCHECK(close(fd) == 0); +} + +#endif // defined(OS_FUCHSIA) + std::unique_ptr<TestInfo> GetTestInfoFromLayoutTestName( const std::string& test_name) { // A test name is formated like file:///path/to/test'--pixel-test'pixelhash @@ -116,9 +161,13 @@ current_working_directory(current_working_directory) {} TestInfo::~TestInfo() {} -TestInfoExtractor::TestInfoExtractor( - const base::CommandLine::StringVector& cmd_args) - : cmdline_args_(cmd_args), cmdline_position_(0) {} +TestInfoExtractor::TestInfoExtractor(const base::CommandLine& cmd_line) + : cmdline_args_(cmd_line.GetArgs()), cmdline_position_(0) { +#if defined(OS_FUCHSIA) + if (cmd_line.HasSwitch(kStdinRedirectSwitch)) + ConnectStdinSocket(cmd_line.GetSwitchValueASCII(kStdinRedirectSwitch)); +#endif // defined(OS_FUCHSIA) +} TestInfoExtractor::~TestInfoExtractor() {}
diff --git a/content/shell/browser/layout_test/test_info_extractor.h b/content/shell/browser/layout_test/test_info_extractor.h index 560e5c0..452c6fe59 100644 --- a/content/shell/browser/layout_test/test_info_extractor.h +++ b/content/shell/browser/layout_test/test_info_extractor.h
@@ -32,7 +32,7 @@ class TestInfoExtractor { public: - explicit TestInfoExtractor(const base::CommandLine::StringVector& cmd_args); + explicit TestInfoExtractor(const base::CommandLine& cmd_line); ~TestInfoExtractor(); std::unique_ptr<TestInfo> GetNextTest();
diff --git a/content/shell/browser/shell_url_request_context_getter.cc b/content/shell/browser/shell_url_request_context_getter.cc index 6afa9c8e..f8463618 100644 --- a/content/shell/browser/shell_url_request_context_getter.cc +++ b/content/shell/browser/shell_url_request_context_getter.cc
@@ -34,13 +34,13 @@ #include "net/http/http_network_session.h" #include "net/proxy/proxy_config_service.h" #include "net/proxy/proxy_service.h" +#include "net/reporting/reporting_feature.h" #include "net/reporting/reporting_policy.h" #include "net/reporting/reporting_service.h" #include "net/ssl/channel_id_service.h" #include "net/ssl/default_channel_id_store.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_builder.h" -#include "services/network/public/cpp/network_features.h" #include "services/network/public/cpp/network_switches.h" #include "url/url_constants.h"
diff --git a/content/shell/test_runner/event_sender.cc b/content/shell/test_runner/event_sender.cc index 36a9fb8..69d72e2 100644 --- a/content/shell/test_runner/event_sender.cc +++ b/content/shell/test_runner/event_sender.cc
@@ -41,6 +41,7 @@ #include "third_party/WebKit/public/web/WebKit.h" #include "third_party/WebKit/public/web/WebLocalFrame.h" #include "third_party/WebKit/public/web/WebPagePopup.h" +#include "third_party/WebKit/public/web/WebUserGestureIndicator.h" #include "third_party/WebKit/public/web/WebView.h" #include "ui/events/blink/blink_event_util.h" #include "ui/events/keycodes/dom/keycode_converter.h" @@ -619,6 +620,7 @@ void MouseScrollBy(gin::Arguments* args); void ScheduleAsynchronousClick(gin::Arguments* args); void ScheduleAsynchronousKeyDown(gin::Arguments* args); + void ConsumeUserActivation(); void MouseDown(gin::Arguments* args); void MouseUp(gin::Arguments* args); void SetMouseButtonState(gin::Arguments* args); @@ -753,6 +755,8 @@ &EventSenderBindings::ScheduleAsynchronousClick) .SetMethod("scheduleAsynchronousKeyDown", &EventSenderBindings::ScheduleAsynchronousKeyDown) + .SetMethod("consumeUserActivation", + &EventSenderBindings::ConsumeUserActivation) .SetProperty("forceLayoutOnEvents", &EventSenderBindings::ForceLayoutOnEvents, &EventSenderBindings::SetForceLayoutOnEvents) @@ -1072,6 +1076,11 @@ static_cast<KeyLocationCode>(location)); } +void EventSenderBindings::ConsumeUserActivation() { + if (sender_) + sender_->ConsumeUserActivation(); +} + void EventSenderBindings::MouseDown(gin::Arguments* args) { if (!sender_) return; @@ -2258,6 +2267,11 @@ modifiers, location)); } +void EventSender::ConsumeUserActivation() { + blink::WebUserGestureIndicator::ConsumeUserGesture( + view()->MainFrame()->ToWebLocalFrame()); +} + double EventSender::GetCurrentEventTimeSec() { return (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF() + time_offset_ms_ / 1000.0;
diff --git a/content/shell/test_runner/event_sender.h b/content/shell/test_runner/event_sender.h index b401231f..8010338 100644 --- a/content/shell/test_runner/event_sender.h +++ b/content/shell/test_runner/event_sender.h
@@ -172,6 +172,9 @@ void ScheduleAsynchronousKeyDown(const std::string& code_str, int modifiers, KeyLocationCode location); + // Consumes the transient user activation state for follow-up tests that don't + // expect it. + void ConsumeUserActivation(); double GetCurrentEventTimeSec();
diff --git a/content/test/test_render_frame_host.cc b/content/test/test_render_frame_host.cc index b686f96..e418e79 100644 --- a/content/test/test_render_frame_host.cc +++ b/content/test/test_render_frame_host.cc
@@ -188,12 +188,12 @@ return; } - navigation_handle()->CallWillRedirectRequestForTesting(new_url, false, GURL(), - false); + GetNavigationHandle()->CallWillRedirectRequestForTesting(new_url, false, + GURL(), false); } void TestRenderFrameHost::SimulateNavigationCommit(const GURL& url) { - if (frame_tree_node()->navigation_request()) + if (frame_tree_node_->navigation_request()) PrepareForCommit(); bool is_auto_subframe = @@ -267,20 +267,20 @@ } void TestRenderFrameHost::SimulateNavigationErrorPageCommit() { - CHECK(navigation_handle()); + CHECK(GetNavigationHandle()); GURL error_url = GURL(kUnreachableWebDataURL); OnDidStartProvisionalLoad(error_url, std::vector<GURL>(), base::TimeTicks::Now()); FrameHostMsg_DidCommitProvisionalLoad_Params params; params.nav_entry_id = 0; params.did_create_new_entry = true; - params.url = navigation_handle()->GetURL(); + params.url = GetNavigationHandle()->GetURL(); params.transition = GetParent() ? ui::PAGE_TRANSITION_MANUAL_SUBFRAME : ui::PAGE_TRANSITION_LINK; params.was_within_same_document = false; params.url_is_unreachable = true; - params.page_state = PageState::CreateForTesting(navigation_handle()->GetURL(), - false, nullptr, nullptr); + params.page_state = PageState::CreateForTesting( + GetNavigationHandle()->GetURL(), false, nullptr, nullptr); SendNavigateWithParams(¶ms); } @@ -472,12 +472,12 @@ void TestRenderFrameHost::SendNavigateWithParamsAndInterfaceProvider( FrameHostMsg_DidCommitProvisionalLoad_Params* params, service_manager::mojom::InterfaceProviderRequest request) { - if (navigation_handle()) { + if (GetNavigationHandle()) { scoped_refptr<net::HttpResponseHeaders> response_headers = new net::HttpResponseHeaders(std::string()); response_headers->AddHeader(std::string("Content-Type: ") + contents_mime_type_); - navigation_handle()->set_response_headers_for_testing(response_headers); + GetNavigationHandle()->set_response_headers_for_testing(response_headers); } DidCommitProvisionalLoad( std::make_unique<FrameHostMsg_DidCommitProvisionalLoad_Params>(*params),
diff --git a/docs/testing/web_platform_tests.md b/docs/testing/web_platform_tests.md index 269ece1..1b564ab 100644 --- a/docs/testing/web_platform_tests.md +++ b/docs/testing/web_platform_tests.md
@@ -199,6 +199,9 @@ account](https://help.github.com/articles/adding-an-email-address-to-your-github-account/) to link your exported commits to your GitHub profile. +If you are a Googler, you can also register your GitHub account at go/github, +making it easier for other Googlers to find you. + ### What if there are conflicts? This cannot be avoided entirely as the two repositories are independent, but
diff --git a/docs/win_cross.md b/docs/win_cross.md index 926a552..f1cfcd8 100644 --- a/docs/win_cross.md +++ b/docs/win_cross.md
@@ -8,7 +8,7 @@ * goma. Sorry. ([internal bug](http://b/64390790)) You can use the [jumbo build](jumbo.md) for faster build times. -* mini_installer ([bug](https://crbug.com/762073)) +* renderer processes crash at startup ([bug](https://crbug.com/803591)) * on Mac hosts, building a 32-bit chrome ([bug](https://crbug.com/794838)) All other targets build fine (including `chrome`, `browser_tests`, ...). @@ -51,6 +51,12 @@ ninja -C out/gnwin base_unittests.exe +## Copying and running chrome + +A convenient way to copy chrome over to a Windows box is to build the +`mini_installer` target. Then, copy just `mini_installer.exe` over +to the Windows box and run it to install the chrome you just built. + ## Running tests on swarming You can run the Windows binaries you built on swarming, like so:
diff --git a/extensions/browser/api/messaging/BUILD.gn b/extensions/browser/api/messaging/BUILD.gn index 12a8e0f..2683c5a5f 100644 --- a/extensions/browser/api/messaging/BUILD.gn +++ b/extensions/browser/api/messaging/BUILD.gn
@@ -25,6 +25,7 @@ ] deps = [ + "//base", "//content/public/browser", "//content/public/common", "//extensions/common",
diff --git a/extensions/renderer/resources/guest_view/guest_view_container.js b/extensions/renderer/resources/guest_view/guest_view_container.js index 2ef77f4f..b0fda86b 100644 --- a/extensions/renderer/resources/guest_view/guest_view_container.js +++ b/extensions/renderer/resources/guest_view/guest_view_container.js
@@ -58,7 +58,8 @@ if (document.readyState == 'loading') return; - registerInternalElement(guestViewContainerType.VIEW_TYPE.toLowerCase()); + registerInternalElement( + $String.toLowerCase(guestViewContainerType.VIEW_TYPE)); registerGuestViewElement(guestViewContainerType); window.removeEventListener(event.type, listener, useCapture); }, useCapture); @@ -292,10 +293,9 @@ guestViewContainerType.setupElement(proto); } - window[guestViewContainerType.VIEW_TYPE] = - DocumentNatives.RegisterElement( - guestViewContainerType.VIEW_TYPE.toLowerCase(), - {prototype: proto}); + window[guestViewContainerType.VIEW_TYPE] = DocumentNatives.RegisterElement( + $String.toLowerCase(guestViewContainerType.VIEW_TYPE), + {prototype: proto}); // Delete the callbacks so developers cannot call them and produce unexpected // behavior.
diff --git a/extensions/renderer/resources/guest_view/guest_view_deny.js b/extensions/renderer/resources/guest_view/guest_view_deny.js index 395594e..b6735604 100644 --- a/extensions/renderer/resources/guest_view/guest_view_deny.js +++ b/extensions/renderer/resources/guest_view/guest_view_deny.js
@@ -23,14 +23,15 @@ // Registers a GuestView custom element. function registerGuestViewElement(viewType) { - var proto = Object.create(HTMLElement.prototype); + var proto = $Object.create(HTMLElement.prototype); proto.createdCallback = function() { - window.console.error(ERROR_MESSAGE.replace(/%1/g, viewType.toLowerCase())); + window.console.error( + $String.replace(ERROR_MESSAGE, /%1/g, $String.toLowerCase(viewType))); }; - window[viewType] = DocumentNatives.RegisterElement(viewType.toLowerCase(), - {prototype: proto}); + window[viewType] = DocumentNatives.RegisterElement( + $String.toLowerCase(viewType), {prototype: proto}); // Delete the callbacks so developers cannot call them and produce unexpected // behavior.
diff --git a/extensions/renderer/resources/guest_view/guest_view_events.js b/extensions/renderer/resources/guest_view/guest_view_events.js index 1417c23..869aaf8 100644 --- a/extensions/renderer/resources/guest_view/guest_view_events.js +++ b/extensions/renderer/resources/guest_view/guest_view_events.js
@@ -160,7 +160,7 @@ // Adds an 'on<event>' property on the view, which can be used to set/unset // an event handler. GuestViewEvents.prototype.setupEventProperty = function(eventName) { - var propertyName = 'on' + eventName.toLowerCase(); + var propertyName = 'on' + $String.toLowerCase(eventName); $Object.defineProperty(this.view.element, propertyName, { get: $Function.bind(function() { return this.on[propertyName];
diff --git a/extensions/renderer/resources/guest_view/web_view/web_view.js b/extensions/renderer/resources/guest_view/web_view/web_view.js index 383c85c..718b82e 100644 --- a/extensions/renderer/resources/guest_view/web_view/web_view.js +++ b/extensions/renderer/resources/guest_view/web_view/web_view.js
@@ -79,23 +79,19 @@ // Sets the <webview>.request property. WebViewImpl.prototype.setRequestPropertyOnWebViewElement = function(request) { - Object.defineProperty( - this.element, - 'request', - { - value: request, - enumerable: true - } - ); + $Object.defineProperty( + this.element, 'request', {value: request, enumerable: true}); }; WebViewImpl.prototype.setupElementProperties = function() { // We cannot use {writable: true} property descriptor because we want a // dynamic getter value. - Object.defineProperty(this.element, 'contentWindow', { - get: $Function.bind(function() { - return this.guest.getContentWindow(); - }, this), + $Object.defineProperty(this.element, 'contentWindow', { + get: $Function.bind( + function() { + return this.guest.getContentWindow(); + }, + this), // No setter. enumerable: true });
diff --git a/extensions/renderer/resources/guest_view/web_view/web_view_action_requests.js b/extensions/renderer/resources/guest_view/web_view/web_view_action_requests.js index 0fa17f0..d763e6c 100644 --- a/extensions/renderer/resources/guest_view/web_view/web_view_action_requests.js +++ b/extensions/renderer/resources/guest_view/web_view/web_view_action_requests.js
@@ -141,9 +141,11 @@ Dialog.prototype.showWarningMessage = function() { var VOWELS = ['a', 'e', 'i', 'o', 'u']; var dialogType = this.event.messageType; - var article = (VOWELS.indexOf(dialogType.charAt(0)) >= 0) ? 'An' : 'A'; - this.WARNING_MSG_REQUEST_BLOCKED = this.WARNING_MSG_REQUEST_BLOCKED. - replace('%1', article).replace('%2', dialogType); + var article = + ($Array.indexOf(VOWELS, dialogType.charAt(0)) >= 0) ? 'An' : 'A'; + this.WARNING_MSG_REQUEST_BLOCKED = $String.replace( + $String.replace(this.WARNING_MSG_REQUEST_BLOCKED, '%1', article), '%2', + dialogType); window.console.warn(this.WARNING_MSG_REQUEST_BLOCKED); }; @@ -255,13 +257,13 @@ }; PermissionRequest.prototype.showWarningMessage = function() { - window.console.warn( - this.WARNING_MSG_REQUEST_BLOCKED.replace('%1', this.event.permission)); + window.console.warn($String.replace( + this.WARNING_MSG_REQUEST_BLOCKED, '%1', this.event.permission)); }; // Checks that the requested permission is valid. Returns true if valid. PermissionRequest.prototype.validPermissionCheck = function() { - if (PERMISSION_TYPES.indexOf(this.event.permission) < 0) { + if ($Array.indexOf(PERMISSION_TYPES, this.event.permission) < 0) { // The permission type is not allowed. Trigger the default response. this.defaultAction(); return false;
diff --git a/extensions/renderer/resources/guest_view/web_view/web_view_events.js b/extensions/renderer/resources/guest_view/web_view/web_view_events.js index fb184ec..a689122 100644 --- a/extensions/renderer/resources/guest_view/web_view/web_view_events.js +++ b/extensions/renderer/resources/guest_view/web_view/web_view_events.js
@@ -244,27 +244,16 @@ for (var i = 0; i < DeclarativeWebRequestSchema.events.length; ++i) { var eventSchema = DeclarativeWebRequestSchema.events[i]; var webRequestEvent = createDeclarativeWebRequestEvent(eventSchema); - Object.defineProperty( - request, - eventSchema.name, - { - get: webRequestEvent, - enumerable: true - } - ); + $Object.defineProperty( + request, eventSchema.name, {get: webRequestEvent, enumerable: true}); } // Populate the WebRequest events from the API definition. for (var i = 0; i < WebRequestSchema.events.length; ++i) { var webRequestEvent = createWebRequestEvent(WebRequestSchema.events[i]); - Object.defineProperty( - request, - WebRequestSchema.events[i].name, - { - get: webRequestEvent, - enumerable: true - } - ); + $Object.defineProperty( + request, WebRequestSchema.events[i].name, + {get: webRequestEvent, enumerable: true}); } this.view.setRequestPropertyOnWebViewElement(request); @@ -291,8 +280,8 @@ var showWarningMessage = function(code, reason) { var WARNING_MSG_LOAD_ABORTED = '<webview>: ' + 'The load has aborted with error %1: %2.'; - window.console.warn( - WARNING_MSG_LOAD_ABORTED.replace('%1', code).replace('%2', reason)); + window.console.warn($String.replace( + $String.replace(WARNING_MSG_LOAD_ABORTED, '%1', code), '%2', reason)); }; var webViewEvent = this.makeDomEvent(event, eventName); if (this.view.dispatchEvent(webViewEvent)) {
diff --git a/extensions/renderer/resources/guest_view/web_view/web_view_request_custom_bindings.js b/extensions/renderer/resources/guest_view/web_view/web_view_request_custom_bindings.js index db8b80f7..3fd27b58 100644 --- a/extensions/renderer/resources/guest_view/web_view/web_view_request_custom_bindings.js +++ b/extensions/renderer/resources/guest_view/web_view/web_view_request_custom_bindings.js
@@ -42,7 +42,7 @@ // Setup all data types for the declarative webRequest API from the schema. for (var i = 0; i < declarativeWebRequestSchema.types.length; ++i) { var typeSchema = declarativeWebRequestSchema.types[i]; - var typeId = typeSchema.id.replace('declarativeWebRequest.', ''); + var typeId = $String.replace(typeSchema.id, 'declarativeWebRequest.', ''); var action = function(typeId) { return function(parameters) { setupInstance(this, parameters, typeId);
diff --git a/extensions/renderer/resources/web_request_event.js b/extensions/renderer/resources/web_request_event.js index 8e55f5a..4a463fd7 100644 --- a/extensions/renderer/resources/web_request_event.js +++ b/extensions/renderer/resources/web_request_event.js
@@ -84,7 +84,7 @@ var subEvent = createSubEvent(subEventName, this.argSchemas); var subEventCallback = cb; - if (opt_extraInfo && opt_extraInfo.indexOf('blocking') >= 0) { + if (opt_extraInfo && $Array.indexOf(opt_extraInfo, 'blocking') >= 0) { var eventName = this.eventName; subEventCallback = function() { var requestId = arguments[0].requestId; @@ -98,7 +98,8 @@ throw e; } }; - } else if (opt_extraInfo && opt_extraInfo.indexOf('asyncBlocking') >= 0) { + } else if ( + opt_extraInfo && $Array.indexOf(opt_extraInfo, 'asyncBlocking') >= 0) { var eventName = this.eventName; subEventCallback = function() { var details = arguments[0];
diff --git a/extensions/renderer/safe_builtins.cc b/extensions/renderer/safe_builtins.cc index 32fe256..24514d4 100644 --- a/extensions/renderer/safe_builtins.cc +++ b/extensions/renderer/safe_builtins.cc
@@ -80,8 +80,8 @@ " 'reverse'],\n" " ['from', 'isArray']);\n" "saveBuiltin(String,\n" - " ['indexOf', 'slice', 'split', 'substr', 'toUpperCase',\n" - " 'replace']);\n" + " ['indexOf', 'slice', 'split', 'substr', 'toLowerCase',\n" + " 'toUpperCase', 'replace']);\n" "// Use exec rather than test to defend against clobbering in the\n" "// presence of ES2015 semantics, which read RegExp.prototype.exec.\n" "saveBuiltin(RegExp,\n"
diff --git a/ios/chrome/app/main_controller.mm b/ios/chrome/app/main_controller.mm index 3a21090..acc73ed5 100644 --- a/ios/chrome/app/main_controller.mm +++ b/ios/chrome/app/main_controller.mm
@@ -396,10 +396,6 @@ @property(nonatomic, strong) SigninInteractionCoordinator* signinInteractionCoordinator; -// Activates browsing and enables web views if |enabled| is YES. -// Disables browsing and purges web views if |enabled| is NO. -// Must be called only on the main thread. -- (void)setWebUsageEnabled:(BOOL)enabled; // Activates |mainBVC| and |otrBVC| and sets |currentBVC| as primary iff // |currentBVC| can be made active. - (void)activateBVCAndMakeCurrentBVCPrimary; @@ -868,16 +864,6 @@ return _browsingDataRemovalController; } -- (void)setWebUsageEnabled:(BOOL)enabled { - DCHECK([NSThread isMainThread]); - if (enabled) { - [self activateBVCAndMakeCurrentBVCPrimary]; - } else { - [self.mainBVC setActive:NO]; - [self.otrBVC setActive:NO]; - } -} - - (void)activateBVCAndMakeCurrentBVCPrimary { // If there are pending removal operations, the activation will be deferred // until the callback for |removeBrowsingDataFromBrowserState:| is received. @@ -1539,6 +1525,23 @@ completion:nil]; } +- (void)prepareForBrowsingDataRemoval { + // Disables browsing and purges web views. + // Must be called only on the main thread. + DCHECK([NSThread isMainThread]); + [self.mainBVC setActive:NO]; + [self.otrBVC setActive:NO]; +} + +- (void)browsingDataWasRemoved { + // Activates browsing and enables web views. + // Must be called only on the main thread. + DCHECK([NSThread isMainThread]); + [self.mainBVC setActive:YES]; + [self.otrBVC setActive:YES]; + [self.currentBVC setPrimary:YES]; +} + #pragma mark - ApplicationSettingsCommands // TODO(crbug.com/779791) : Remove show settings from MainController. @@ -2039,10 +2042,10 @@ // TODO(crbug.com/632772): Remove web usage disabling once // https://bugs.webkit.org/show_bug.cgi?id=149079 has been fixed. if (mask & IOSChromeBrowsingDataRemover::REMOVE_SITE_DATA) { - [self setWebUsageEnabled:NO]; + [self prepareForBrowsingDataRemoval]; } ProceduralBlock browsingDataRemoved = ^{ - [self setWebUsageEnabled:YES]; + [self browsingDataWasRemoved]; if (completionHandler) { completionHandler(); }
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd index 9ed8bdc..63a3d6b 100644 --- a/ios/chrome/app/strings/ios_strings.grd +++ b/ios/chrome/app/strings/ios_strings.grd
@@ -1075,6 +1075,9 @@ <message name="IDS_IOS_EXPORT_PASSWORDS_CANCEL_BUTTON" desc="Label of a confirmation dialog button which allows the user to cancel passwords export. [Length: 22em] [iOS only]"> Cancel </message> + <message name="IDS_IOS_SETTINGS_EXPORT_PASSWORDS_SET_UP_SCREENLOCK_CONTENT" desc="Message informing the user that in order to export the passwords, a screen lock needs to be set up on the device. This is shown as an alert message after the user tries to view or copy the password from a settings page. [Length: about two lines]"> + To export passwords, you must first set a passcode on your device. + </message> <message name="IDS_IOS_SAVE_PASSWORDS_MANAGE_ACCOUNT" desc="Header text with link for the view in Settings for managing saved passwords. [Length: unlimited] [iOS only]"> View and manage saved passwords at <ph name="BEGIN_LINK">BEGIN_LINK</ph>passwords.google.com<ph name="END_LINK">END_LINK</ph> </message>
diff --git a/ios/chrome/app/tests_fake_hook.mm b/ios/chrome/app/tests_fake_hook.mm index e58ad5da..da4a92e59 100644 --- a/ios/chrome/app/tests_fake_hook.mm +++ b/ios/chrome/app/tests_fake_hook.mm
@@ -28,7 +28,7 @@ bool DisableUpdateService() { return false; } -bool ForceAdaptiveToolbar() { +bool ForceUIRefreshPhase1() { return false; } void SetUpTestsIfPresent() {}
diff --git a/ios/chrome/app/tests_hook.h b/ios/chrome/app/tests_hook.h index 92d074e..afd241f 100644 --- a/ios/chrome/app/tests_hook.h +++ b/ios/chrome/app/tests_hook.h
@@ -32,9 +32,9 @@ bool DisableUpdateService(); // TODO(crbug.com/800266): Removes this hook. -// Returns true if the AdaptiveToolbar UI should be displayed, overriding the -// flag value. -bool ForceAdaptiveToolbar(); +// Returns true if the first phase of the UI refresh will be displayed, +// overriding the flag value. +bool ForceUIRefreshPhase1(); // Global integration tests setup. This is not used by EarlGrey-based // integration tests.
diff --git a/ios/chrome/browser/BUILD.gn b/ios/chrome/browser/BUILD.gn index 5cd66987..28d3d32 100644 --- a/ios/chrome/browser/BUILD.gn +++ b/ios/chrome/browser/BUILD.gn
@@ -112,13 +112,13 @@ "//components/webdata_services", "//google_apis", "//ios/chrome/app/strings", - "//ios/chrome/browser/bookmarks:features", "//ios/chrome/browser/browser_state", "//ios/chrome/browser/download", "//ios/chrome/browser/drag_and_drop", "//ios/chrome/browser/payments:constants", "//ios/chrome/browser/ssl:features", "//ios/chrome/browser/sync/glue", + "//ios/chrome/browser/ui:feature_flags", "//ios/chrome/browser/ui/activity_services:features", "//ios/chrome/browser/ui/coordinators:chrome_coordinators", "//ios/chrome/browser/ui/external_search:features",
diff --git a/ios/chrome/browser/about_flags.mm b/ios/chrome/browser/about_flags.mm index 7c922d25..2310565 100644 --- a/ios/chrome/browser/about_flags.mm +++ b/ios/chrome/browser/about_flags.mm
@@ -36,7 +36,6 @@ #include "components/security_state/core/features.h" #include "components/signin/core/browser/signin_switches.h" #include "components/strings/grit/components_strings.h" -#include "ios/chrome/browser/bookmarks/bookmark_new_generation_features.h" #include "ios/chrome/browser/chrome_switches.h" #include "ios/chrome/browser/drag_and_drop/drag_and_drop_flag.h" #include "ios/chrome/browser/ios_chrome_flag_descriptions.h" @@ -49,6 +48,7 @@ #import "ios/chrome/browser/ui/omnibox/omnibox_clipping_feature.h" #import "ios/chrome/browser/ui/toolbar/public/toolbar_controller_base_feature.h" #import "ios/chrome/browser/ui/toolbar/toolbar_private_base_feature.h" +#include "ios/chrome/browser/ui/ui_feature_flags.h" #include "ios/chrome/grit/ios_strings.h" #include "ios/public/provider/chrome/browser/chrome_browser_provider.h" #include "ios/web/public/features.h" @@ -217,9 +217,6 @@ {"clipping-textfield", flag_descriptions::kClippingTextfieldName, flag_descriptions::kClippingTextfieldDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE(kClippingTextfield)}, - {"bookmark-new-edit-page", flag_descriptions::kBookmarkNewEditPageName, - flag_descriptions::kBookmarkNewEditPageDescription, flags_ui::kOsIos, - FEATURE_VALUE_TYPE(kBookmarkNewEditPage)}, {"PasswordExport", flag_descriptions::kPasswordExportName, flag_descriptions::kPasswordExportDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE(password_manager::features::kPasswordExport)}, @@ -232,9 +229,10 @@ flag_descriptions::kShowAutofillTypePredictionsDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE(autofill::features::kAutofillShowTypePredictions)}, - {"adaptive-toolbar", flag_descriptions::kAdaptiveToolbarName, - flag_descriptions::kAdaptiveToolbarDescription, flags_ui::kOsIos, - FEATURE_VALUE_TYPE(kAdaptiveToolbar)}, + {"ui-refresh-phase-1", flag_descriptions::kUIRefreshPhase1Name, + flag_descriptions::kUIRefreshPhase1Description, flags_ui::kOsIos, + FEATURE_VALUE_TYPE(kUIRefreshPhase1)}, + }; // Add all switches from experimental flags to |command_line|.
diff --git a/ios/chrome/browser/bookmarks/BUILD.gn b/ios/chrome/browser/bookmarks/BUILD.gn index c8f8059..1581e81 100644 --- a/ios/chrome/browser/bookmarks/BUILD.gn +++ b/ios/chrome/browser/bookmarks/BUILD.gn
@@ -50,13 +50,3 @@ "//ios/chrome/browser/browser_state", ] } - -source_set("features") { - sources = [ - "bookmark_new_generation_features.cc", - "bookmark_new_generation_features.h", - ] - deps = [ - "//base", - ] -}
diff --git a/ios/chrome/browser/bookmarks/bookmark_new_generation_features.cc b/ios/chrome/browser/bookmarks/bookmark_new_generation_features.cc deleted file mode 100644 index 79f004a1e..0000000 --- a/ios/chrome/browser/bookmarks/bookmark_new_generation_features.cc +++ /dev/null
@@ -1,9 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ios/chrome/browser/bookmarks/bookmark_new_generation_features.h" - -// Feature flag for the new edit page and folder picker of the new bookmark UI. -const base::Feature kBookmarkNewEditPage{"BookmarkNewEditPage", - base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/ios/chrome/browser/bookmarks/bookmark_new_generation_features.h b/ios/chrome/browser/bookmarks/bookmark_new_generation_features.h deleted file mode 100644 index ffe8bac94..0000000 --- a/ios/chrome/browser/bookmarks/bookmark_new_generation_features.h +++ /dev/null
@@ -1,14 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_CHROME_BROWSER_BOOKMARKS_BOOKMARK_NEW_GENERATION_FEATURES_H -#define IOS_CHROME_BROWSER_BOOKMARKS_BOOKMARK_NEW_GENERATION_FEATURES_H - -#include "base/feature_list.h" -#include "build/build_config.h" - -// Feature flag for the new edit page and folder picker of the new bookmark UI. -extern const base::Feature kBookmarkNewEditPage; - -#endif // IOS_CHROME_BROWSER_BOOKMARKS_BOOKMARK_NEW_GENERATION_FEATURES_H
diff --git a/ios/chrome/browser/browsing_data/BUILD.gn b/ios/chrome/browser/browsing_data/BUILD.gn index 9cb5519a..0bc1a65 100644 --- a/ios/chrome/browser/browsing_data/BUILD.gn +++ b/ios/chrome/browser/browsing_data/BUILD.gn
@@ -99,7 +99,6 @@ "//ios/chrome/browser/sessions:serialisation", "//ios/chrome/browser/signin", "//ios/chrome/browser/snapshots", - "//ios/chrome/browser/ui:ui_internal", "//ios/web", "//net", ]
diff --git a/ios/chrome/browser/browsing_data/browsing_data_removal_controller.mm b/ios/chrome/browser/browsing_data/browsing_data_removal_controller.mm index a596b31..72bb13f 100644 --- a/ios/chrome/browser/browsing_data/browsing_data_removal_controller.mm +++ b/ios/chrome/browser/browsing_data/browsing_data_removal_controller.mm
@@ -25,7 +25,6 @@ #include "ios/chrome/browser/sessions/session_util.h" #include "ios/chrome/browser/signin/account_consistency_service_factory.h" #import "ios/chrome/browser/snapshots/snapshots_util.h" -#import "ios/chrome/browser/ui/browser_view_controller.h" #import "ios/chrome/browser/ui/external_file_remover.h" #import "ios/chrome/browser/ui/external_file_remover_factory.h" #include "ios/web/public/web_thread.h"
diff --git a/ios/chrome/browser/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/ios_chrome_flag_descriptions.cc index aa7293e5..6c797e0b 100644 --- a/ios/chrome/browser/ios_chrome_flag_descriptions.cc +++ b/ios/chrome/browser/ios_chrome_flag_descriptions.cc
@@ -11,15 +11,6 @@ namespace flag_descriptions { -const char kAdaptiveToolbarName[] = "Adaptive Toolbar"; -const char kAdaptiveToolbarDescription[] = - "When enabled, the adaptive toolbar will be used."; - -const char kBookmarkNewEditPageName[] = "Bookmark New Edit Page"; -const char kBookmarkNewEditPageDescription[] = - "When enabled, the new bookmark edit page and folder picker will be used " - "in the new bookmark UI."; - const char kBrowserTaskScheduler[] = "Task Scheduler"; const char kBrowserTaskSchedulerDescription[] = "Enables redirection of some task posting APIs to the task scheduler."; @@ -137,6 +128,10 @@ "BVC is visible, the tab switcher will remain in the VC hierarchy " "underneath it."; +const char kUIRefreshPhase1Name[] = "UI Refresh Phase 1"; +const char kUIRefreshPhase1Description[] = + "When enabled, the first phase of the iOS UI refresh will be displayed."; + const char kUseDdljsonApiName[] = "Use new ddljson API for Doodles"; const char kUseDdljsonApiDescription[] = "Enables the new ddljson API to fetch Doodles for the NTP.";
diff --git a/ios/chrome/browser/ios_chrome_flag_descriptions.h b/ios/chrome/browser/ios_chrome_flag_descriptions.h index 80e714c..5d39da99 100644 --- a/ios/chrome/browser/ios_chrome_flag_descriptions.h +++ b/ios/chrome/browser/ios_chrome_flag_descriptions.h
@@ -7,15 +7,6 @@ namespace flag_descriptions { -// Title and description for the flag to enable the adaptive toolbar. -extern const char kAdaptiveToolbarName[]; -extern const char kAdaptiveToolbarDescription[]; - -// Title and description for the flag to enable the new bookmark edit page in -// the new bookmark UI. -extern const char kBookmarkNewEditPageName[]; -extern const char kBookmarkNewEditPageDescription[]; - // Title and description for the flag to control redirection to the task // scheduler. extern const char kBrowserTaskScheduler[]; @@ -126,6 +117,10 @@ extern const char kTabSwitcherPresentsBVCName[]; extern const char kTabSwitcherPresentsBVCDescription[]; +// Title and description for the flag to enable the phase 1 UI Refresh. +extern const char kUIRefreshPhase1Name[]; +extern const char kUIRefreshPhase1Description[]; + // Title and description for the flag to enable the ddljson Doodle API. extern const char kUseDdljsonApiName[]; extern const char kUseDdljsonApiDescription[];
diff --git a/ios/chrome/browser/metrics/ukm_egtest.mm b/ios/chrome/browser/metrics/ukm_egtest.mm index da1734e..b789f596 100644 --- a/ios/chrome/browser/metrics/ukm_egtest.mm +++ b/ios/chrome/browser/metrics/ukm_egtest.mm
@@ -181,6 +181,13 @@ [ChromeEarlGrey waitForMainTabCount:(tab_count + 1)]; } +// Grant/revoke metrics consent and update MetricsServicesManager. +void UpdateMetricsConsent(bool new_state) { + g_metrics_enabled = new_state; + GetApplicationContext()->GetMetricsServicesManager()->UpdateUploadPermissions( + true); +} + // Signs in to sync. void SignIn() { ChromeIdentity* identity = [SigninEarlGreyUtils fakeIdentity1]; @@ -287,6 +294,9 @@ [super tearDown]; } +// The tests in this file should correspond with the ones in +// //chrome/browser/metrics/ukm_browsertest.cc + // Make sure that UKM is disabled while an incognito tab is open. - (void)testRegularPlusIncognito { uint64_t original_client_id = metrics::UkmEGTestHelper::client_id(); @@ -312,28 +322,41 @@ @"Client ID was reset."); } -// Make sure that UKM is disabled when sync is not enabled. -- (void)testNoSync { +// TODO(crbug.com/792933): Implement testIncognitoPlusRegular + +// testOpenNonSync not needed, since there can't be multiple profiles. + +// Make sure that UKM is disabled when metrics consent is revoked. +- (void)testMetricsConsent { uint64_t original_client_id = metrics::UkmEGTestHelper::client_id(); - SignOut(); + UpdateMetricsConsent(false); AssertUKMEnabled(false); - // Client ID should have been reset by signout. - GREYAssert(original_client_id != metrics::UkmEGTestHelper::client_id(), - @"Client ID was not reset."); - original_client_id = metrics::UkmEGTestHelper::client_id(); - SignInWithPromo(); + UpdateMetricsConsent(true); AssertUKMEnabled(true); - // Client ID should not have been reset. - GREYAssert(original_client_id == metrics::UkmEGTestHelper::client_id(), - @"Client ID was reset."); + // Client ID should have been reset. + GREYAssert(original_client_id != metrics::UkmEGTestHelper::client_id(), + @"Client ID was not reset."); +} + +// Make sure that providing metrics consent doesn't enable UKM w/o sync. +- (void)testConsentAddedButNoSync { + SignOut(); + UpdateMetricsConsent(false); + AssertUKMEnabled(false); + + UpdateMetricsConsent(true); + AssertUKMEnabled(false); + + SignInWithPromo(); + AssertUKMEnabled(true); } // Make sure that UKM is disabled when sync is disabled. -- (void)testDisableSync { +- (void)testSingleDisableSync { uint64_t original_client_id = metrics::UkmEGTestHelper::client_id(); [ChromeEarlGreyUI openSettingsMenu]; @@ -377,28 +400,34 @@ performAction:grey_tap()]; } -// Make sure that UKM is disabled when metrics consent is revoked. -- (void)testNoConsent { +// testMultiDisableSync not needed, since there can't be multiple profiles. + +// TODO(crbug.com/793082): Implement testSecondaryPassphrase. + +// Make sure that UKM is disabled when sync is not enabled. +- (void)testSingleSyncSignout { uint64_t original_client_id = metrics::UkmEGTestHelper::client_id(); - // Revoke metrics consent and update MetricsServicesManager. - g_metrics_enabled = false; - GetApplicationContext()->GetMetricsServicesManager()->UpdateUploadPermissions( - true); + SignOut(); AssertUKMEnabled(false); - - // Grant metrics consent and update MetricsServicesManager. - g_metrics_enabled = true; - GetApplicationContext()->GetMetricsServicesManager()->UpdateUploadPermissions( - true); - - AssertUKMEnabled(true); - // Client ID should have been reset. + // Client ID should have been reset by signout. GREYAssert(original_client_id != metrics::UkmEGTestHelper::client_id(), @"Client ID was not reset."); + + original_client_id = metrics::UkmEGTestHelper::client_id(); + SignInWithPromo(); + + AssertUKMEnabled(true); + // Client ID should not have been reset. + GREYAssert(original_client_id == metrics::UkmEGTestHelper::client_id(), + @"Client ID was reset."); } +// testMultiSyncSignout not needed, since there can't be multiple profiles. + +// testMetricsReporting not needed, since iOS doesn't use sampling. + - (void)testHistoryDelete { uint64_t original_client_id = metrics::UkmEGTestHelper::client_id();
diff --git a/ios/chrome/browser/signin/BUILD.gn b/ios/chrome/browser/signin/BUILD.gn index 6740511..fddf120 100644 --- a/ios/chrome/browser/signin/BUILD.gn +++ b/ios/chrome/browser/signin/BUILD.gn
@@ -57,6 +57,7 @@ "//base", "//components/browser_sync", "//components/content_settings/core/browser", + "//components/image_fetcher/ios", "//components/keyed_service/core", "//components/keyed_service/ios", "//components/metrics",
diff --git a/ios/chrome/browser/signin/account_fetcher_service_factory.cc b/ios/chrome/browser/signin/account_fetcher_service_factory.cc index 74b02d24..147bf7f 100644 --- a/ios/chrome/browser/signin/account_fetcher_service_factory.cc +++ b/ios/chrome/browser/signin/account_fetcher_service_factory.cc
@@ -7,6 +7,7 @@ #include <utility> #include "base/memory/singleton.h" +#include "components/image_fetcher/ios/ios_image_decoder_impl.h" #include "components/keyed_service/ios/browser_state_dependency_manager.h" #include "components/signin/core/browser/account_fetcher_service.h" #include "components/signin/core/browser/profile_oauth2_token_service.h" @@ -54,7 +55,8 @@ service->Initialize( SigninClientFactory::GetForBrowserState(browser_state), OAuth2TokenServiceFactory::GetForBrowserState(browser_state), - ios::AccountTrackerServiceFactory::GetForBrowserState(browser_state)); + ios::AccountTrackerServiceFactory::GetForBrowserState(browser_state), + image_fetcher::CreateIOSImageDecoder()); return service; }
diff --git a/ios/chrome/browser/tabs/tab.h b/ios/chrome/browser/tabs/tab.h index 696f42f..35492ef2 100644 --- a/ios/chrome/browser/tabs/tab.h +++ b/ios/chrome/browser/tabs/tab.h
@@ -103,9 +103,6 @@ @property(nonatomic, readonly) id<FindInPageControllerDelegate> findInPageControllerDelegate; -// Whether or not desktop user agent is used for the currently visible page. -@property(nonatomic, readonly) BOOL usesDesktopUserAgent; - // The delegate to use for the legacy fullscreen controller. It should not be // set if the new fullscreen is enabled. // TODO(crbug.com/778823): Remove this property. @@ -171,15 +168,6 @@ // Updates the timestamp of the last time the tab is visited. - (void)updateLastVisitedTimestamp; -// Loads the original url of the last non-redirect item (including non-history -// items). Used by request desktop/mobile site so that the updated user agent is -// used. -- (void)reloadWithUserAgentType:(web::UserAgentType)userAgentType; - -// Ensures the toolbar visibility matches |visible|. -// TODO(crbug.com/778823): Remove this code. -- (void)updateFullscreenWithToolbarVisible:(BOOL)visible; - // Called when this tab is shown. - (void)wasShown; @@ -189,6 +177,18 @@ // Called before capturing a snapshot for Tab. - (void)willUpdateSnapshot; +// Ensures the toolbar visibility matches |visible|. +// TODO(crbug.com/778823): Remove this code. +- (void)updateFullscreenWithToolbarVisible:(BOOL)visible; + +// Whether or not desktop user agent is used for the currently visible page. +@property(nonatomic, readonly) BOOL usesDesktopUserAgent; + +// Loads the original url of the last non-redirect item (including non-history +// items). Used by request desktop/mobile site so that the updated user agent is +// used. +- (void)reloadWithUserAgentType:(web::UserAgentType)userAgentType; + // Evaluates U2F result. - (void)evaluateU2FResultFromURL:(const GURL&)url;
diff --git a/ios/chrome/browser/tabs/tab.mm b/ios/chrome/browser/tabs/tab.mm index bc86765..72c5802 100644 --- a/ios/chrome/browser/tabs/tab.mm +++ b/ios/chrome/browser/tabs/tab.mm
@@ -34,7 +34,6 @@ #include "components/infobars/core/infobar_manager.h" #include "components/keyed_service/core/service_access_type.h" #include "components/metrics_services_manager/metrics_services_manager.h" -#include "components/navigation_metrics/navigation_metrics.h" #include "components/prefs/pref_service.h" #include "components/reading_list/core/reading_list_model.h" #include "components/search_engines/template_url_service.h" @@ -46,10 +45,8 @@ #import "ios/chrome/browser/autofill/form_suggestion_tab_helper.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/chrome_url_constants.h" -#import "ios/chrome/browser/crash_loop_detection_util.h" #include "ios/chrome/browser/experimental_flags.h" #import "ios/chrome/browser/find_in_page/find_in_page_controller.h" -#import "ios/chrome/browser/geolocation/omnibox_geolocation_controller.h" #include "ios/chrome/browser/history/history_service_factory.h" #include "ios/chrome/browser/history/history_tab_helper.h" #include "ios/chrome/browser/history/top_sites_factory.h" @@ -183,11 +180,6 @@ // Handles exportable files if possible. - (void)handleExportableFile:(net::HttpResponseHeaders*)headers; -// Returns YES if TabUsageRecorder::RecordPageLoadStart should be called for the -// given navigation. -- (BOOL)shouldRecordPageLoadStartForNavigation: - (web::NavigationContext*)navigation; - @end @implementation Tab @@ -203,6 +195,8 @@ @synthesize legacyFullscreenControllerDelegate = legacyFullscreenControllerDelegate_; +#pragma mark - Initializers + - (instancetype)initWithWebState:(web::WebState*)webState { DCHECK(webState); self = [super init]; @@ -222,51 +216,21 @@ return self; } +#pragma mark - NSObject protocol + - (void)dealloc { // The WebState owns the Tab, so -webStateDestroyed: should be called before // -dealloc and _webStateImpl set to nullptr. DCHECK(!_webStateImpl); } -- (id<FindInPageControllerDelegate>)findInPageControllerDelegate { - return self; -} - -- (void)setParentTabModel:(TabModel*)model { - DCHECK(!model || !_parentTabModel); - _parentTabModel = model; -} - - (NSString*)description { return [NSString stringWithFormat:@"%p ... %@ - %s", self, self.title, self.webState->GetVisibleURL().spec().c_str()]; } -- (id<TabDialogDelegate>)dialogDelegate { - return dialogDelegate_; -} - -- (BOOL)loadFinished { - return self.webState && !self.webState->IsLoading(); -} - -- (BOOL)isVoiceSearchResultsTab { - // TODO(crbug.com/778416): Move this logic entirely into helper. - // If nothing has been loaded in the Tab, it cannot be displaying a voice - // search results page. - web::NavigationItem* item = - self.webState->GetNavigationManager()->GetVisibleItem(); - if (!item) - return NO; - // Navigating through history to a NavigationItem that was created for a voice - // search query should just be treated like a normal page load. - if ((item->GetTransitionType() & ui::PAGE_TRANSITION_FORWARD_BACK) != 0) - return NO; - // Check whether |item| has been marked as a voice search result navigation. - return VoiceSearchNavigationTabHelper::FromWebState(self.webState) - ->IsNavigationFromVoiceSearch(item); -} +#pragma mark - Properties - (NSString*)title { base::string16 title = self.webState->GetTitle(); @@ -297,28 +261,16 @@ return _webStateImpl; } -- (UIView*)view { - if (!self.webState) - return nil; - - // Record reload of previously-evicted tab. - if (self.webState->IsEvicted() && [_parentTabModel tabUsageRecorder]) - [_parentTabModel tabUsageRecorder]->RecordPageLoadStart(self.webState); - - // Do not trigger the load if the tab has crashed. SadTabTabHelper is - // responsible for handing reload logic for crashed tabs. - if (!self.webState->IsCrashed()) { - self.webState->GetNavigationManager()->LoadIfNecessary(); - } - return self.webState->GetView(); +- (BOOL)canGoBack { + return self.navigationManager && self.navigationManager->CanGoBack(); } -- (UIView*)viewForPrinting { - return self.webController.viewForPrinting; +- (BOOL)canGoForward { + return self.navigationManager && self.navigationManager->CanGoForward(); } -- (web::NavigationManager*)navigationManager { - return self.webState ? self.webState->GetNavigationManager() : nullptr; +- (id<FindInPageControllerDelegate>)findInPageControllerDelegate { + return self; } - (void)setLegacyFullscreenControllerDelegate: @@ -368,11 +320,279 @@ overscrollActionsControllerDelegate_ = overscrollActionsControllerDelegate; } +- (BOOL)isVoiceSearchResultsTab { + // TODO(crbug.com/778416): Move this logic entirely into helper. + // If nothing has been loaded in the Tab, it cannot be displaying a voice + // search results page. + web::NavigationItem* item = + self.webState->GetNavigationManager()->GetVisibleItem(); + if (!item) + return NO; + // Navigating through history to a NavigationItem that was created for a voice + // search query should just be treated like a normal page load. + if ((item->GetTransitionType() & ui::PAGE_TRANSITION_FORWARD_BACK) != 0) + return NO; + // Check whether |item| has been marked as a voice search result navigation. + return VoiceSearchNavigationTabHelper::FromWebState(self.webState) + ->IsNavigationFromVoiceSearch(item); +} + +- (BOOL)loadFinished { + return self.webState && !self.webState->IsLoading(); +} + +#pragma mark - Public API + +- (void)setParentTabModel:(TabModel*)model { + DCHECK(!model || !_parentTabModel); + _parentTabModel = model; +} + +- (UIView*)view { + if (!self.webState) + return nil; + + // Record reload of previously-evicted tab. + if (self.webState->IsEvicted() && [_parentTabModel tabUsageRecorder]) + [_parentTabModel tabUsageRecorder]->RecordPageLoadStart(self.webState); + + // Do not trigger the load if the tab has crashed. SadTabTabHelper is + // responsible for handing reload logic for crashed tabs. + if (!self.webState->IsCrashed()) { + self.webState->GetNavigationManager()->LoadIfNecessary(); + } + return self.webState->GetView(); +} + +- (UIView*)viewForPrinting { + return self.webController.viewForPrinting; +} + // Halt the tab, which amounts to halting its webController. - (void)terminateNetworkActivity { [self.webController terminateNetworkActivity]; } +- (void)dismissModals { + [_openInController disable]; + [self.webController dismissModals]; +} + +- (web::NavigationManager*)navigationManager { + return self.webState ? self.webState->GetNavigationManager() : nullptr; +} + +- (void)goToItem:(const web::NavigationItem*)item { + DCHECK(item); + int index = self.navigationManager->GetIndexOfItem(item); + DCHECK_NE(index, -1); + self.navigationManager->GoToIndex(index); +} + +- (void)goBack { + if (self.navigationManager) { + DCHECK(self.navigationManager->CanGoBack()); + base::RecordAction(base::UserMetricsAction("Back")); + self.navigationManager->GoBack(); + } +} + +- (void)goForward { + if (self.navigationManager) { + DCHECK(self.navigationManager->CanGoForward()); + base::RecordAction(base::UserMetricsAction("Forward")); + self.navigationManager->GoForward(); + } +} + +- (double)lastVisitedTimestamp { + return _lastVisitedTimestamp; +} + +- (void)updateLastVisitedTimestamp { + _lastVisitedTimestamp = [[NSDate date] timeIntervalSince1970]; +} + +- (void)wasShown { + if (!base::FeatureList::IsEnabled(fullscreen::features::kNewFullscreen)) { + [self updateFullscreenWithToolbarVisible:YES]; + } + if (self.webState) + self.webState->WasShown(); +} + +- (void)wasHidden { + if (!base::FeatureList::IsEnabled(fullscreen::features::kNewFullscreen)) { + [self updateFullscreenWithToolbarVisible:YES]; + } + if (self.webState) + self.webState->WasHidden(); +} + +- (void)willUpdateSnapshot { + [_overscrollActionsController clear]; +} + +#pragma mark - Public API (relating to Fullscreen) + +- (void)updateFullscreenWithToolbarVisible:(BOOL)visible { + DCHECK(!base::FeatureList::IsEnabled(fullscreen::features::kNewFullscreen)); + [_legacyFullscreenController moveHeaderToRestingPosition:visible]; +} + +#pragma mark - Public API (relatinge to User agent) + +- (BOOL)usesDesktopUserAgent { + if (!self.navigationManager) + return NO; + + web::NavigationItem* visibleItem = self.navigationManager->GetVisibleItem(); + return visibleItem && + visibleItem->GetUserAgentType() == web::UserAgentType::DESKTOP; +} + +- (void)reloadWithUserAgentType:(web::UserAgentType)userAgentType { + // This removes the web view, which will be recreated at the end of this. + [self.webController requirePageReconstruction]; + + // TODO(crbug.com/228171): A hack in session_controller -addPendingItem + // discusses making tab responsible for distinguishing history stack + // navigation from new navigations. + web::NavigationManager* navigationManager = [self navigationManager]; + DCHECK(navigationManager); + + web::NavigationItem* lastNonRedirectItem = + navigationManager->GetTransientItem(); + if (!lastNonRedirectItem || IsItemRedirectItem(lastNonRedirectItem)) + lastNonRedirectItem = navigationManager->GetVisibleItem(); + if (!lastNonRedirectItem || IsItemRedirectItem(lastNonRedirectItem)) + lastNonRedirectItem = GetLastCommittedNonRedirectedItem(navigationManager); + + if (!lastNonRedirectItem) + return; + + // |reloadURL| will be empty if a page was open by DOM. + GURL reloadURL(lastNonRedirectItem->GetOriginalRequestURL()); + if (reloadURL.is_empty()) { + DCHECK(self.webState && self.webState->HasOpener()); + reloadURL = lastNonRedirectItem->GetVirtualURL(); + } + + web::NavigationManager::WebLoadParams params(reloadURL); + params.referrer = lastNonRedirectItem->GetReferrer(); + params.transition_type = ui::PAGE_TRANSITION_RELOAD; + + switch (userAgentType) { + case web::UserAgentType::DESKTOP: + params.user_agent_override_option = + web::NavigationManager::UserAgentOverrideOption::DESKTOP; + break; + case web::UserAgentType::MOBILE: + params.user_agent_override_option = + web::NavigationManager::UserAgentOverrideOption::MOBILE; + break; + case web::UserAgentType::NONE: + NOTREACHED(); + } + + navigationManager->LoadURLWithParams(params); +} + +#pragma mark - Public API (relating to U2F) + +- (void)evaluateU2FResultFromURL:(const GURL&)URL { + DCHECK(_secondFactorController); + [_secondFactorController evaluateU2FResultFromU2FURL:URL + webState:self.webState]; +} + +#pragma mark - FindInPageControllerDelegate protocol + +- (void)willAdjustScrollPosition { + if (!base::FeatureList::IsEnabled(fullscreen::features::kNewFullscreen)) { + // Skip the next attempt to correct the scroll offset for the toolbar + // height. Used when programatically scrolling down the y offset. + [_legacyFullscreenController shouldSkipNextScrollOffsetForHeader]; + } +} + +#pragma mark - CRWWebStateObserver protocol + +- (void)webState:(web::WebState*)webState + didCommitNavigationWithDetails:(const web::LoadCommittedDetails&)details { + DCHECK([self navigationManager]); + if (!base::FeatureList::IsEnabled(fullscreen::features::kNewFullscreen)) { + // TODO(crbug.com/381201): Move this call to DidFinishNavigation callback. + [_legacyFullscreenController disableFullScreen]; + } +} + +- (void)webState:(web::WebState*)webState + didStartNavigation:(web::NavigationContext*)navigation { + if (!navigation->IsSameDocument() && + !base::FeatureList::IsEnabled(fullscreen::features::kNewFullscreen)) { + // Move the toolbar to visible during page load. + [_legacyFullscreenController disableFullScreen]; + } + + [self.dialogDelegate cancelDialogForTab:self]; + [_openInController disable]; +} + +- (void)webState:(web::WebState*)webState + didLoadPageWithSuccess:(BOOL)loadSuccess { + DCHECK([self loadFinished]); + + // Cancel prerendering if response is "application/octet-stream". It can be a + // video file which should not be played from preload tab (crbug.com/436813). + if (self.isPrerenderTab && + self.webState->GetContentsMimeType() == "application/octet-stream") { + [self discardPrerender]; + } + + if (loadSuccess) { + scoped_refptr<net::HttpResponseHeaders> headers = + _webStateImpl->GetHttpResponseHeaders(); + [self handleExportableFile:headers.get()]; + } else { + if (!base::FeatureList::IsEnabled(fullscreen::features::kNewFullscreen)) { + [_legacyFullscreenController disableFullScreen]; + } + } +} + +- (void)webStateDidChangeVisibleSecurityState:(web::WebState*)webState { + if (!base::FeatureList::IsEnabled(fullscreen::features::kNewFullscreen)) { + // Disable fullscreen if SSL cert is invalid. + web::NavigationItem* item = [self navigationManager]->GetTransientItem(); + if (item) { + web::SecurityStyle securityStyle = item->GetSSL().security_style; + if (securityStyle == web::SECURITY_STYLE_AUTHENTICATION_BROKEN) { + [_legacyFullscreenController disableFullScreen]; + } + } + + [self updateFullscreenWithToolbarVisible:YES]; + } +} + +- (void)webStateDidSuppressDialog:(web::WebState*)webState { + DCHECK(self.isPrerenderTab); + [self discardPrerender]; +} + +- (void)renderProcessGoneForWebState:(web::WebState*)webState { + DCHECK(webState == _webStateImpl); + if (!base::FeatureList::IsEnabled(fullscreen::features::kNewFullscreen)) { + UIApplicationState state = + [UIApplication sharedApplication].applicationState; + if (webState->IsVisible() && state == UIApplicationStateActive) { + [_legacyFullscreenController disableFullScreen]; + } + } + [self.dialogDelegate cancelDialogForTab:self]; +} + - (void)webStateDestroyed:(web::WebState*)webState { DCHECK_EQ(_webStateImpl, webState); self.overscrollActionsControllerDelegate = nil; @@ -398,41 +618,15 @@ _webStateImpl = nullptr; } -- (void)dismissModals { - [_openInController disable]; - [self.webController dismissModals]; -} - -- (void)goBack { - if (self.navigationManager) { - DCHECK(self.navigationManager->CanGoBack()); - base::RecordAction(base::UserMetricsAction("Back")); - self.navigationManager->GoBack(); +- (void)webStateDidStopLoading:(web::WebState*)webState { + if (!base::FeatureList::IsEnabled(fullscreen::features::kNewFullscreen)) { + // This is the maximum that a page will ever load and it is safe to allow + // fullscreen mode. + [_legacyFullscreenController enableFullScreen]; } } -- (void)goForward { - if (self.navigationManager) { - DCHECK(self.navigationManager->CanGoForward()); - base::RecordAction(base::UserMetricsAction("Forward")); - self.navigationManager->GoForward(); - } -} - -- (BOOL)canGoBack { - return self.navigationManager && self.navigationManager->CanGoBack(); -} - -- (BOOL)canGoForward { - return self.navigationManager && self.navigationManager->CanGoForward(); -} - -- (void)goToItem:(const web::NavigationItem*)item { - DCHECK(item); - int index = self.navigationManager->GetIndexOfItem(item); - DCHECK_NE(index, -1); - self.navigationManager->GoToIndex(index); -} +#pragma mark - CRWWebDelegate protocol - (BOOL)openExternalURL:(const GURL&)url sourceURL:(const GURL&)sourceURL @@ -495,27 +689,65 @@ return NO; } -- (void)webState:(web::WebState*)webState - didFinishNavigation:(web::NavigationContext*)navigation { - [_parentTabModel notifyTabChanged:self]; +- (BOOL)webController:(CRWWebController*)webController + shouldOpenURL:(const GURL&)url + mainDocumentURL:(const GURL&)mainDocumentURL { + // chrome:// URLs are only allowed if the mainDocumentURL is also a chrome:// + // URL. + if (url.SchemeIs(kChromeUIScheme) && + !mainDocumentURL.SchemeIs(kChromeUIScheme)) { + return NO; + } + + // Always allow frame loads. + BOOL isFrameLoad = (url != mainDocumentURL); + if (isFrameLoad) + return YES; + + // TODO(crbug.com/546402): If this turns out to be useful, find a less hacky + // hook point to send this from. + NSString* urlString = base::SysUTF8ToNSString(url.spec()); + if ([urlString length]) { + [[NSNotificationCenter defaultCenter] + postNotificationName:kTabUrlMayStartLoadingNotificationForCrashReporting + object:self + userInfo:@{kTabUrlKey : urlString}]; + } + + return YES; } -// Records metric for the interface's orientation. -- (void)recordInterfaceOrientation { - switch ([[UIApplication sharedApplication] statusBarOrientation]) { - case UIInterfaceOrientationPortrait: - case UIInterfaceOrientationPortraitUpsideDown: - UMA_HISTOGRAM_BOOLEAN("Tab.PageLoadInPortrait", YES); - break; - case UIInterfaceOrientationLandscapeLeft: - case UIInterfaceOrientationLandscapeRight: - UMA_HISTOGRAM_BOOLEAN("Tab.PageLoadInPortrait", NO); - break; - case UIInterfaceOrientationUnknown: - // TODO(crbug.com/228832): Convert from a boolean histogram to an - // enumerated histogram and log this case as well. - break; +- (BOOL)webController:(CRWWebController*)webController + shouldOpenExternalURL:(const GURL&)URL { + if (self.isPrerenderTab) { + [self discardPrerender]; + return NO; } + return YES; +} + +- (CGFloat)headerHeightForWebController:(CRWWebController*)webController { + return [self.tabHeadersDelegate tabHeaderHeightForTab:self]; +} + +- (void)webController:(CRWWebController*)webController + didLoadPassKitObject:(NSData*)data { + [self.passKitDialogProvider presentPassKitDialog:data]; +} + +#pragma mark - Private methods + +- (void)discardPrerender { + DCHECK(self.isPrerenderTab); + [delegate_ discardPrerender]; +} + +- (BOOL)isPrerenderTab { + DCHECK(_browserState); + PrerenderService* prerenderService = + PrerenderServiceFactory::GetForBrowserState(_browserState); + return prerenderService && + prerenderService->IsWebStatePrerendered(self.webState); } - (OpenInController*)openInController { @@ -555,402 +787,6 @@ suggestedFilename:base::SysUTF16ToNSString(filename)]; } -- (BOOL)shouldRecordPageLoadStartForNavigation: - (web::NavigationContext*)navigation { - web::NavigationItem* lastCommittedItem = - [self navigationManager]->GetLastCommittedItem(); - if (!lastCommittedItem) { - // Opening a child window and loading URL there (crbug.com/773160). - return NO; - } - - web::NavigationItem* pendingItem = [self navigationManager]->GetPendingItem(); - if (pendingItem) { - using web::UserAgentType; - UserAgentType committedUserAgent = lastCommittedItem->GetUserAgentType(); - UserAgentType pendingUserAgent = pendingItem->GetUserAgentType(); - if (committedUserAgent != web::UserAgentType::NONE && - pendingUserAgent != web::UserAgentType::NONE && - committedUserAgent != pendingUserAgent) { - // Switching to Desktop or Mobile User Agent. - return YES; - } - } - - ui::PageTransition transition = navigation->GetPageTransition(); - if (!ui::PageTransitionIsNewNavigation(transition)) { - // Back forward navigation or reload. - return NO; - } - - if ((ui::PageTransition::PAGE_TRANSITION_CLIENT_REDIRECT & transition) != 0) { - // Client redirect. - return NO; - } - - using ui::PageTransitionCoreTypeIs; - return ( - PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_TYPED) || - PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_LINK) || - PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_GENERATED) || - PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_AUTO_BOOKMARK) || - PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_FORM_SUBMIT) || - PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_KEYWORD) || - PageTransitionCoreTypeIs(transition, - ui::PAGE_TRANSITION_KEYWORD_GENERATED)); -} - -#pragma mark - -#pragma mark FindInPageControllerDelegate - -- (void)willAdjustScrollPosition { - if (!base::FeatureList::IsEnabled(fullscreen::features::kNewFullscreen)) { - // Skip the next attempt to correct the scroll offset for the toolbar - // height. Used when programatically scrolling down the y offset. - [_legacyFullscreenController shouldSkipNextScrollOffsetForHeader]; - } -} - -#pragma mark - -#pragma mark FullScreen - -- (void)updateFullscreenWithToolbarVisible:(BOOL)visible { - DCHECK(!base::FeatureList::IsEnabled(fullscreen::features::kNewFullscreen)); - [_legacyFullscreenController moveHeaderToRestingPosition:visible]; -} - -#pragma mark - - -- (BOOL)usesDesktopUserAgent { - if (!self.navigationManager) - return NO; - - web::NavigationItem* visibleItem = self.navigationManager->GetVisibleItem(); - return visibleItem && - visibleItem->GetUserAgentType() == web::UserAgentType::DESKTOP; -} - -- (void)reloadWithUserAgentType:(web::UserAgentType)userAgentType { - // This removes the web view, which will be recreated at the end of this. - [self.webController requirePageReconstruction]; - - // TODO(crbug.com/228171): A hack in session_controller -addPendingItem - // discusses making tab responsible for distinguishing history stack - // navigation from new navigations. - web::NavigationManager* navigationManager = [self navigationManager]; - DCHECK(navigationManager); - - web::NavigationItem* lastNonRedirectItem = - navigationManager->GetTransientItem(); - if (!lastNonRedirectItem || IsItemRedirectItem(lastNonRedirectItem)) - lastNonRedirectItem = navigationManager->GetVisibleItem(); - if (!lastNonRedirectItem || IsItemRedirectItem(lastNonRedirectItem)) - lastNonRedirectItem = GetLastCommittedNonRedirectedItem(navigationManager); - - if (!lastNonRedirectItem) - return; - - // |reloadURL| will be empty if a page was open by DOM. - GURL reloadURL(lastNonRedirectItem->GetOriginalRequestURL()); - if (reloadURL.is_empty()) { - DCHECK(self.webState && self.webState->HasOpener()); - reloadURL = lastNonRedirectItem->GetVirtualURL(); - } - - web::NavigationManager::WebLoadParams params(reloadURL); - params.referrer = lastNonRedirectItem->GetReferrer(); - params.transition_type = ui::PAGE_TRANSITION_RELOAD; - - switch (userAgentType) { - case web::UserAgentType::DESKTOP: - params.user_agent_override_option = - web::NavigationManager::UserAgentOverrideOption::DESKTOP; - break; - case web::UserAgentType::MOBILE: - params.user_agent_override_option = - web::NavigationManager::UserAgentOverrideOption::MOBILE; - break; - case web::UserAgentType::NONE: - NOTREACHED(); - } - - navigationManager->LoadURLWithParams(params); -} - -- (void)evaluateU2FResultFromURL:(const GURL&)URL { - DCHECK(_secondFactorController); - [_secondFactorController evaluateU2FResultFromU2FURL:URL - webState:self.webState]; -} - -#pragma mark - CRWWebDelegate and CRWWebStateObserver protocol methods. - -- (void)webState:(web::WebState*)webState - didStartNavigation:(web::NavigationContext*)navigation { - // After a crash the NTP is loaded by default. - if (navigation->GetUrl().host() != kChromeUINewTabHost) { - static BOOL hasLoadedPage = NO; - if (!hasLoadedPage) { - // As soon as load is initialted, a crash shouldn't be counted as a - // startup crash. Since initiating a url load requires user action and is - // a significant source of crashes that could lead to false positives in - // crash loop detection. - crash_util::ResetFailedStartupAttemptCount(); - hasLoadedPage = YES; - } - } - - if (!navigation->IsSameDocument() && - !base::FeatureList::IsEnabled(fullscreen::features::kNewFullscreen)) { - // Move the toolbar to visible during page load. - [_legacyFullscreenController disableFullScreen]; - } - - if ([self shouldRecordPageLoadStartForNavigation:navigation] && - [_parentTabModel tabUsageRecorder] && !self.isPrerenderTab) { - [_parentTabModel tabUsageRecorder]->RecordPageLoadStart(webState); - } - - [self.dialogDelegate cancelDialogForTab:self]; - [_parentTabModel notifyTabChanged:self]; - [_openInController disable]; - [[NSNotificationCenter defaultCenter] - postNotificationName: - kTabClosingCurrentDocumentNotificationForCrashReporting - object:self]; - - web::NavigationItem* navigationItem = - [self navigationManager]->GetPendingItem(); - - // TODO(crbug.com/676129): the pending item is not correctly set when the - // page is reloading, use the last committed item if pending item is null. - // Remove this once tracking bug is fixed. - if (!navigationItem) - navigationItem = [self navigationManager]->GetLastCommittedItem(); - - [[OmniboxGeolocationController sharedInstance] - addLocationToNavigationItem:navigationItem - browserState:_browserState]; -} - -- (void)webState:(web::WebState*)webState - didCommitNavigationWithDetails:(const web::LoadCommittedDetails&)details { - DCHECK([self navigationManager]); - if (!base::FeatureList::IsEnabled(fullscreen::features::kNewFullscreen)) { - // TODO(crbug.com/381201): Move this call to DidFinishNavigation callback. - [_legacyFullscreenController disableFullScreen]; - } - GURL lastCommittedURL = webState->GetLastCommittedURL(); - - [_parentTabModel notifyTabLoading:self]; - - web::NavigationItem* previousItem = nullptr; - if (details.previous_item_index >= 0) { - previousItem = webState->GetNavigationManager()->GetItemAtIndex( - details.previous_item_index); - } - - [_parentTabModel navigationCommittedInTab:self previousItem:previousItem]; - - // Sending a notification about the url change for crash reporting. - // TODO(crbug.com/661675): Consider using the navigation entry committed - // notification now that it's in the right place. - NSString* URLSpec = base::SysUTF8ToNSString(lastCommittedURL.spec()); - if (URLSpec.length) { - [[NSNotificationCenter defaultCenter] - postNotificationName:kTabUrlStartedLoadingNotificationForCrashReporting - object:self - userInfo:@{kTabUrlKey : URLSpec}]; - } -} - -- (void)webState:(web::WebState*)webState - didLoadPageWithSuccess:(BOOL)loadSuccess { - DCHECK([self loadFinished]); - - // Cancel prerendering if response is "application/octet-stream". It can be a - // video file which should not be played from preload tab (crbug.com/436813). - if (self.isPrerenderTab && - self.webState->GetContentsMimeType() == "application/octet-stream") { - [self discardPrerender]; - } - - bool wasPost = false; - GURL lastCommittedURL; - web::NavigationItem* lastCommittedItem = - [self navigationManager]->GetLastCommittedItem(); - if (lastCommittedItem) { - wasPost = lastCommittedItem->HasPostData(); - lastCommittedURL = lastCommittedItem->GetVirtualURL(); - } - if (!base::FeatureList::IsEnabled(fullscreen::features::kNewFullscreen) && - !loadSuccess) { - [_legacyFullscreenController disableFullScreen]; - } - [self recordInterfaceOrientation]; - navigation_metrics::RecordMainFrameNavigation( - lastCommittedURL, true, self.browserState->IsOffTheRecord()); - - if (loadSuccess) { - scoped_refptr<net::HttpResponseHeaders> headers = - _webStateImpl->GetHttpResponseHeaders(); - [self handleExportableFile:headers.get()]; - } - - [_parentTabModel notifyTabFinishedLoading:self success:loadSuccess]; - - if (!self.isPrerenderTab) { - [[OmniboxGeolocationController sharedInstance] - finishPageLoadForTab:self - loadSuccess:loadSuccess]; - } -} - -- (void)webState:(web::WebState*)webState - didChangeLoadingProgress:(double)progress { - // TODO(crbug.com/546406): It is probably possible to do something smarter, - // but the fact that this is not always sent will have to be taken into - // account. - [_parentTabModel notifyTabChanged:self]; -} - -- (void)webStateDidChangeTitle:(web::WebState*)webState { - [_parentTabModel notifyTabChanged:self]; -} - -- (void)webStateDidStopLoading:(web::WebState*)webState { - if (!base::FeatureList::IsEnabled(fullscreen::features::kNewFullscreen)) { - // This is the maximum that a page will ever load and it is safe to allow - // fullscreen mode. - [_legacyFullscreenController enableFullScreen]; - } - [_parentTabModel notifyTabChanged:self]; -} - -- (BOOL)webController:(CRWWebController*)webController - shouldOpenExternalURL:(const GURL&)URL { - if (self.isPrerenderTab) { - [self discardPrerender]; - return NO; - } - return YES; -} - -- (double)lastVisitedTimestamp { - return _lastVisitedTimestamp; -} - -- (void)updateLastVisitedTimestamp { - _lastVisitedTimestamp = [[NSDate date] timeIntervalSince1970]; -} - -- (BOOL)webController:(CRWWebController*)webController - shouldOpenURL:(const GURL&)url - mainDocumentURL:(const GURL&)mainDocumentURL { - // chrome:// URLs are only allowed if the mainDocumentURL is also a chrome:// - // URL. - if (url.SchemeIs(kChromeUIScheme) && - !mainDocumentURL.SchemeIs(kChromeUIScheme)) { - return NO; - } - - // Always allow frame loads. - BOOL isFrameLoad = (url != mainDocumentURL); - if (isFrameLoad) - return YES; - - // TODO(crbug.com/546402): If this turns out to be useful, find a less hacky - // hook point to send this from. - NSString* urlString = base::SysUTF8ToNSString(url.spec()); - if ([urlString length]) { - [[NSNotificationCenter defaultCenter] - postNotificationName:kTabUrlMayStartLoadingNotificationForCrashReporting - object:self - userInfo:@{kTabUrlKey : urlString}]; - } - - return YES; -} - -#pragma mark - CRWWebDelegate and CRWWebStateObserver protocol methods - -- (void)webStateDidSuppressDialog:(web::WebState*)webState { - DCHECK(self.isPrerenderTab); - [self discardPrerender]; -} - -- (CGFloat)headerHeightForWebController:(CRWWebController*)webController { - return [self.tabHeadersDelegate tabHeaderHeightForTab:self]; -} - -- (void)webStateDidChangeVisibleSecurityState:(web::WebState*)webState { - if (!base::FeatureList::IsEnabled(fullscreen::features::kNewFullscreen)) { - // Disable fullscreen if SSL cert is invalid. - web::NavigationItem* item = [self navigationManager]->GetTransientItem(); - if (item) { - web::SecurityStyle securityStyle = item->GetSSL().security_style; - if (securityStyle == web::SECURITY_STYLE_AUTHENTICATION_BROKEN) { - [_legacyFullscreenController disableFullScreen]; - } - } - } - - [_parentTabModel notifyTabChanged:self]; - if (!base::FeatureList::IsEnabled(fullscreen::features::kNewFullscreen)) { - [self updateFullscreenWithToolbarVisible:YES]; - } -} - -- (void)renderProcessGoneForWebState:(web::WebState*)webState { - DCHECK(webState == _webStateImpl); - if (!base::FeatureList::IsEnabled(fullscreen::features::kNewFullscreen)) { - UIApplicationState state = - [UIApplication sharedApplication].applicationState; - if (webState->IsVisible() && state == UIApplicationStateActive) { - [_legacyFullscreenController disableFullScreen]; - } - } - [self.dialogDelegate cancelDialogForTab:self]; -} - -- (void)webController:(CRWWebController*)webController - didLoadPassKitObject:(NSData*)data { - [self.passKitDialogProvider presentPassKitDialog:data]; -} - -- (void)discardPrerender { - DCHECK(self.isPrerenderTab); - [delegate_ discardPrerender]; -} - -- (BOOL)isPrerenderTab { - DCHECK(_browserState); - PrerenderService* prerenderService = - PrerenderServiceFactory::GetForBrowserState(_browserState); - return prerenderService && - prerenderService->IsWebStatePrerendered(self.webState); -} - -- (void)wasShown { - if (!base::FeatureList::IsEnabled(fullscreen::features::kNewFullscreen)) { - [self updateFullscreenWithToolbarVisible:YES]; - } - if (self.webState) - self.webState->WasShown(); -} - -- (void)wasHidden { - if (!base::FeatureList::IsEnabled(fullscreen::features::kNewFullscreen)) { - [self updateFullscreenWithToolbarVisible:YES]; - } - if (self.webState) - self.webState->WasHidden(); -} - -- (void)willUpdateSnapshot { - [_overscrollActionsController clear]; -} - @end #pragma mark - TestingSupport
diff --git a/ios/chrome/browser/tabs/tab_model.mm b/ios/chrome/browser/tabs/tab_model.mm index 1d4d59b..8ffe501 100644 --- a/ios/chrome/browser/tabs/tab_model.mm +++ b/ios/chrome/browser/tabs/tab_model.mm
@@ -17,6 +17,7 @@ #include "base/strings/sys_string_conversions.h" #include "base/task/cancelable_task_tracker.h" #include "components/favicon/ios/web_favicon_driver.h" +#include "components/navigation_metrics/navigation_metrics.h" #include "components/sessions/core/serialized_navigation_entry.h" #include "components/sessions/core/session_id.h" #include "components/sessions/core/tab_restore_service.h" @@ -24,6 +25,8 @@ #include "ios/chrome/browser/browser_state/chrome_browser_state.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" +#import "ios/chrome/browser/geolocation/omnibox_geolocation_controller.h" #import "ios/chrome/browser/metrics/tab_usage_recorder.h" #import "ios/chrome/browser/prerender/prerender_service_factory.h" #include "ios/chrome/browser/sessions/ios_chrome_tab_restore_service_factory.h" @@ -55,10 +58,13 @@ #import "ios/chrome/browser/web_state_list/web_state_opener.h" #include "ios/web/public/browser_state.h" #include "ios/web/public/certificate_policy_cache.h" +#import "ios/web/public/load_committed_details.h" #include "ios/web/public/navigation_item.h" #import "ios/web/public/navigation_manager.h" #import "ios/web/public/serializable_user_data_manager.h" +#import "ios/web/public/web_state/navigation_context.h" #include "ios/web/public/web_state/session_certificate_policy_cache.h" +#import "ios/web/public/web_state/web_state_observer_bridge.h" #include "ios/web/public/web_thread.h" #include "url/gurl.h" @@ -108,9 +114,108 @@ base::Unretained(web_state_list))); } +// Returns whether |rhs| and |lhs| are different user agent types. If either +// of them is web::UserAgentType::NONE, then return NO. +BOOL IsTransitionBetweenDesktopAndMobileUserAgent(web::UserAgentType lhs, + web::UserAgentType rhs) { + if (lhs == web::UserAgentType::NONE) + return NO; + + if (rhs == web::UserAgentType::NONE) + return NO; + + return lhs != rhs; +} + +// Returns whether TabUsageRecorder::RecordPageLoadStart should be called for +// the given navigation. +BOOL ShouldRecordPageLoadStartForNavigation( + web::NavigationContext* navigation) { + web::NavigationManager* navigation_manager = + navigation->GetWebState()->GetNavigationManager(); + + web::NavigationItem* last_committed_item = + navigation_manager->GetLastCommittedItem(); + if (!last_committed_item) { + // Opening a child window and loading URL there. + // http://crbug.com/773160 + return NO; + } + + web::NavigationItem* pending_item = navigation_manager->GetPendingItem(); + if (pending_item) { + if (IsTransitionBetweenDesktopAndMobileUserAgent( + pending_item->GetUserAgentType(), + last_committed_item->GetUserAgentType())) { + // Switching between Desktop and Mobile user agent. + return NO; + } + } + + ui::PageTransition transition = navigation->GetPageTransition(); + if (!ui::PageTransitionIsNewNavigation(transition)) { + // Back/forward navigation or reload. + return NO; + } + + if ((transition & ui::PAGE_TRANSITION_CLIENT_REDIRECT) != 0) { + // Client redirect. + return NO; + } + + static const ui::PageTransition kRecordedPageTransitionTypes[] = { + ui::PAGE_TRANSITION_TYPED, + ui::PAGE_TRANSITION_LINK, + ui::PAGE_TRANSITION_GENERATED, + ui::PAGE_TRANSITION_AUTO_BOOKMARK, + ui::PAGE_TRANSITION_FORM_SUBMIT, + ui::PAGE_TRANSITION_KEYWORD, + ui::PAGE_TRANSITION_KEYWORD_GENERATED, + }; + + for (size_t i = 0; i < arraysize(kRecordedPageTransitionTypes); ++i) { + const ui::PageTransition recorded_type = kRecordedPageTransitionTypes[i]; + if (ui::PageTransitionCoreTypeIs(transition, recorded_type)) { + return YES; + } + } + + return NO; +} + +// Records metrics for the interface's orientation. +void RecordInterfaceOrientationMetric() { + switch ([[UIApplication sharedApplication] statusBarOrientation]) { + case UIInterfaceOrientationPortrait: + case UIInterfaceOrientationPortraitUpsideDown: + UMA_HISTOGRAM_BOOLEAN("Tab.PageLoadInPortrait", YES); + break; + case UIInterfaceOrientationLandscapeLeft: + case UIInterfaceOrientationLandscapeRight: + UMA_HISTOGRAM_BOOLEAN("Tab.PageLoadInPortrait", NO); + break; + case UIInterfaceOrientationUnknown: + // TODO(crbug.com/228832): Convert from a boolean histogram to an + // enumerated histogram and log this case as well. + break; + } +} + +// Records metrics for main frame navigation. +void RecordMainFrameNavigationMetric(web::WebState* web_state) { + DCHECK(web_state); + DCHECK(web_state->GetBrowserState()); + DCHECK(web_state->GetNavigationManager()); + web::NavigationItem* item = + web_state->GetNavigationManager()->GetLastCommittedItem(); + navigation_metrics::RecordMainFrameNavigation( + item ? item->GetVirtualURL() : GURL::EmptyGURL(), true, + web_state->GetBrowserState()->IsOffTheRecord()); +} + } // anonymous namespace -@interface TabModel () { +@interface TabModel ()<CRWWebStateObserver, WebStateListObserving> { // Delegate for the WebStateList. std::unique_ptr<WebStateListDelegate> _webStateListDelegate; @@ -143,6 +248,9 @@ // Used to ensure thread-safety of the certificate policy management code. base::CancelableTaskTracker _clearPoliciesTaskTracker; + + // Used to observe owned Tabs' WebStates. + std::unique_ptr<web::WebStateObserver> _webStateObserver; } // Session window for the contents of the tab model. @@ -222,6 +330,8 @@ _browserState = browserState; DCHECK(_browserState); + _webStateObserver = std::make_unique<web::WebStateObserverBridge>(self); + // Normal browser states are the only ones to get tab restore. Tab sync // handles incognito browser states by filtering on profile, so it's // important to the backend code to always have a sync window delegate. @@ -249,6 +359,9 @@ [retainedWebStateListObservers addObject:tabModelClosingWebStateObserver]; _webStateListObservers.push_back( + std::make_unique<WebStateListObserverBridge>(self)); + + _webStateListObservers.push_back( std::make_unique<WebStateListObserverBridge>( tabModelClosingWebStateObserver)); @@ -588,6 +701,7 @@ _clearPoliciesTaskTracker.TryCancelAll(); _tabUsageRecorder.reset(); + _webStateObserver.reset(); } - (void)navigationCommittedInTab:(Tab*)tab @@ -742,4 +856,153 @@ } } +#pragma mark - CRWWebStateObserver + +- (void)webState:(web::WebState*)webState + didCommitNavigationWithDetails: + (const web::LoadCommittedDetails&)load_details { + Tab* tab = LegacyTabHelper::GetTabForWebState(webState); + [self notifyTabChanged:tab]; + + web::NavigationItem* previousItem = nullptr; + if (load_details.previous_item_index >= 0) { + DCHECK(webState->GetNavigationManager()); + previousItem = webState->GetNavigationManager()->GetItemAtIndex( + load_details.previous_item_index); + } + + [self navigationCommittedInTab:tab previousItem:previousItem]; + + // Sending a notification about the url change for crash reporting. + // TODO(crbug.com/661675): Consider using the navigation entry committed + // notification now that it's in the right place. + const std::string& lastCommittedURL = webState->GetLastCommittedURL().spec(); + if (!lastCommittedURL.empty()) { + [[NSNotificationCenter defaultCenter] + postNotificationName:kTabUrlStartedLoadingNotificationForCrashReporting + object:tab + userInfo:@{ + kTabUrlKey : base::SysUTF8ToNSString(lastCommittedURL) + }]; + } +} + +- (void)webState:(web::WebState*)webState + didStartNavigation:(web::NavigationContext*)navigation { + Tab* tab = LegacyTabHelper::GetTabForWebState(webState); + + // In order to avoid false positive in the crash loop detection, disable the + // counter as soon as an URL is loaded. This requires an user action and is a + // significant source of crashes. Ignore NTP as it is loaded by default after + // a crash. + if (navigation->GetUrl().host_piece() != kChromeUINewTabHost) { + static dispatch_once_t dispatch_once_token; + dispatch_once(&dispatch_once_token, ^{ + crash_util::ResetFailedStartupAttemptCount(); + }); + } + + if (_tabUsageRecorder && ShouldRecordPageLoadStartForNavigation(navigation)) { + _tabUsageRecorder->RecordPageLoadStart(webState); + } + + [self notifyTabChanged:tab]; + [[NSNotificationCenter defaultCenter] + postNotificationName: + kTabClosingCurrentDocumentNotificationForCrashReporting + object:tab]; + + DCHECK(webState->GetNavigationManager()); + web::NavigationItem* navigationItem = + webState->GetNavigationManager()->GetPendingItem(); + + // TODO(crbug.com/676129): the pending item is not correctly set when the + // page is reloading, use the last committed item if pending item is null. + // Remove this once tracking bug is fixed. + if (!navigationItem) { + navigationItem = webState->GetNavigationManager()->GetLastCommittedItem(); + } + + [[OmniboxGeolocationController sharedInstance] + addLocationToNavigationItem:navigationItem + browserState:ios::ChromeBrowserState::FromBrowserState( + webState->GetBrowserState())]; +} + +- (void)webState:(web::WebState*)webState + didFinishNavigation:(web::NavigationContext*)navigation { + Tab* tab = LegacyTabHelper::GetTabForWebState(webState); + [self notifyTabChanged:tab]; +} + +- (void)webState:(web::WebState*)webState didLoadPageWithSuccess:(BOOL)success { + DCHECK(!webState->IsLoading()); + Tab* tab = LegacyTabHelper::GetTabForWebState(webState); + [self notifyTabFinishedLoading:tab success:success]; + + RecordInterfaceOrientationMetric(); + RecordMainFrameNavigationMetric(webState); + + [[OmniboxGeolocationController sharedInstance] finishPageLoadForTab:tab + loadSuccess:success]; +} + +- (void)webState:(web::WebState*)webState + didChangeLoadingProgress:(double)progress { + // TODO(crbug.com/546406): It is probably possible to do something smarter, + // but the fact that this is not always sent will have to be taken into + // account. + Tab* tab = LegacyTabHelper::GetTabForWebState(webState); + [self notifyTabChanged:tab]; +} + +- (void)webStateDidChangeTitle:(web::WebState*)webState { + Tab* tab = LegacyTabHelper::GetTabForWebState(webState); + [self notifyTabChanged:tab]; +} + +- (void)webStateDidChangeVisibleSecurityState:(web::WebState*)webState { + Tab* tab = LegacyTabHelper::GetTabForWebState(webState); + [self notifyTabChanged:tab]; +} + +- (void)webStateDestroyed:(web::WebState*)webState { + // The TabModel is removed from WebState's observer when the WebState is + // detached from WebStateList which happens before WebState destructor, + // so this method should never be called. + NOTREACHED(); +} + +- (void)webStateDidStopLoading:(web::WebState*)webState { + Tab* tab = LegacyTabHelper::GetTabForWebState(webState); + [self notifyTabChanged:tab]; +} + +#pragma mark - WebStateListObserving + +- (void)webStateList:(WebStateList*)webStateList + didInsertWebState:(web::WebState*)webState + atIndex:(int)index + activating:(BOOL)activating { + DCHECK(webState); + webState->AddObserver(_webStateObserver.get()); +} + +- (void)webStateList:(WebStateList*)webStateList + didReplaceWebState:(web::WebState*)oldWebState + withWebState:(web::WebState*)newWebState + atIndex:(int)atIndex { + DCHECK(oldWebState); + DCHECK(newWebState); + newWebState->AddObserver(_webStateObserver.get()); + oldWebState->RemoveObserver(_webStateObserver.get()); +} + +- (void)webStateList:(WebStateList*)webStateList + didDetachWebState:(web::WebState*)webState + atIndex:(int)atIndex { + DCHECK(webState); + webState->RemoveObserver(_webStateObserver.get()); +} + @end
diff --git a/ios/chrome/browser/ui/BUILD.gn b/ios/chrome/browser/ui/BUILD.gn index 98e985a..67b5473f6 100644 --- a/ios/chrome/browser/ui/BUILD.gn +++ b/ios/chrome/browser/ui/BUILD.gn
@@ -64,6 +64,7 @@ "uikit_ui_util.mm", ] deps = [ + ":feature_flags", "//base", "//base:i18n", "//ios/chrome/app:tests_hook", @@ -82,6 +83,17 @@ configs += [ "//build/config/compiler:enable_arc" ] } +source_set("feature_flags") { + configs += [ "//build/config/compiler:enable_arc" ] + sources = [ + "ui_feature_flags.cc", + "ui_feature_flags.h", + ] + deps = [ + "//base", + ] +} + source_set("unit_tests") { configs += [ "//build/config/compiler:enable_arc" ] testonly = true @@ -393,14 +405,20 @@ "//ui/base", "//ui/gfx", "//url", + + # Fake dependencies to break cycles + "//ios/chrome/browser/browsing_data:browsing_data_internal", + "//ios/chrome/browser/ui/settings", ] public_deps = [ "//ios/chrome/browser/ui/side_swipe", "//ios/chrome/browser/ui/toolbar", ] allow_circular_includes_from = [ + "//ios/chrome/browser/browsing_data:browsing_data_internal", "//ios/chrome/browser/ui/ntp:ntp_internal", "//ios/chrome/browser/ui/overscroll_actions", + "//ios/chrome/browser/ui/settings", "//ios/chrome/browser/ui/stack_view", "//ios/chrome/browser/ui/tab_switcher", "//ios/chrome/browser/ui/tabs:coordinator",
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm index 82900c6e..1e79baa5 100644 --- a/ios/chrome/browser/ui/browser_view_controller.mm +++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -1682,7 +1682,7 @@ - (BOOL)prefersStatusBarHidden { BOOL defaultValue = NO; - if (IsAdaptiveToolbarEnabled()) { + if (IsUIRefreshPhase1Enabled()) { defaultValue = [super prefersStatusBarHidden]; } return self.hideStatusBar || defaultValue; @@ -1934,7 +1934,7 @@ _toolbarModelIOS.reset([_dependencyFactory newToolbarModelIOSWithDelegate:_toolbarModelDelegate.get()]); - if (IsAdaptiveToolbarEnabled()) { + if (IsUIRefreshPhase1Enabled()) { PrimaryToolbarCoordinator* topToolbarCoordinator = [[PrimaryToolbarCoordinator alloc] initWithBrowserState:_browserState]; self.primaryToolbarCoordinator = topToolbarCoordinator;
diff --git a/ios/chrome/browser/ui/commands/application_commands.h b/ios/chrome/browser/ui/commands/application_commands.h index 0803b25..236c587 100644 --- a/ios/chrome/browser/ui/commands/application_commands.h +++ b/ios/chrome/browser/ui/commands/application_commands.h
@@ -98,6 +98,12 @@ // Shows the Add Account UI, presenting from |baseViewController|. - (void)showAddAccountFromViewController:(UIViewController*)baseViewController; +// Prepares the UI for ClearBrowsingData. +- (void)prepareForBrowsingDataRemoval; + +// Updates the UI once ClearBrowsingData has occured. +- (void)browsingDataWasRemoved; + @end #endif // IOS_CHROME_BROWSER_UI_COMMANDS_APPLICATION_COMMANDS_H_
diff --git a/ios/chrome/browser/ui/download/legacy_download_manager_controller_unittest.mm b/ios/chrome/browser/ui/download/legacy_download_manager_controller_unittest.mm index a7b63a5a..1aba2212 100644 --- a/ios/chrome/browser/ui/download/legacy_download_manager_controller_unittest.mm +++ b/ios/chrome/browser/ui/download/legacy_download_manager_controller_unittest.mm
@@ -87,7 +87,8 @@ EXPECT_TRUE([_controller googleDriveButton]); } -TEST_F(LegacyDownloadManagerControllerTest, TestStart) { +// TODO(crbug.com/804250): this test is flaky. +TEST_F(LegacyDownloadManagerControllerTest, FLAKY_TestStart) { [_controller start]; EXPECT_TRUE( [[UIApplication sharedApplication] isNetworkActivityIndicatorVisible]);
diff --git a/ios/chrome/browser/ui/download/pass_kit_coordinator_unittest.mm b/ios/chrome/browser/ui/download/pass_kit_coordinator_unittest.mm index 73195c0..ee8cc6c 100644 --- a/ios/chrome/browser/ui/download/pass_kit_coordinator_unittest.mm +++ b/ios/chrome/browser/ui/download/pass_kit_coordinator_unittest.mm
@@ -63,7 +63,8 @@ // Tests that PassKitCoordinator presents PKAddPassesViewController for the // valid PKPass object. -TEST_F(PassKitCoordinatorTest, ValidPassKitObject) { +// TODO(crbug.com/804250): this test is flaky. +TEST_F(PassKitCoordinatorTest, FLAKY_ValidPassKitObject) { std::string data = testing::GetTestPass(); NSData* nsdata = [NSData dataWithBytes:data.c_str() length:data.size()]; PKPass* pass = [[PKPass alloc] initWithData:nsdata error:nil]; @@ -99,7 +100,8 @@ } // Tests presenting multiple valid PKPass objects. -TEST_F(PassKitCoordinatorTest, MultiplePassKitObjects) { +// TODO(crbug.com/804250): this test is flaky. +TEST_F(PassKitCoordinatorTest, FLAKY_MultiplePassKitObjects) { if (IsIPadIdiom()) { // Wallet app is not supported on iPads. return;
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.mm b/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.mm index f3b0a05..d31f786 100644 --- a/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.mm +++ b/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.mm
@@ -301,27 +301,29 @@ completionAnimator:(UIViewPropertyAnimator*)completionAnimator { // Hide the rightView button so its not visibile on its initial layout // while the expan animation is happening. - self.rightView.hidden = YES; - self.rightView.alpha = 0; - self.rightView.frame = CGRectLayoutOffset( - [self rightViewRectForBounds:self.bounds], kToolbarButtonAnimationOffset); + self.clearButton.hidden = YES; + self.clearButton.alpha = 0; + self.clearButton.frame = + CGRectLayoutOffset([self rightViewRectForBounds:self.bounds], + [self clearButtonAnimationOffset]); [completionAnimator addAnimations:^{ - self.rightView.hidden = NO; - self.rightView.alpha = 1.0; - self.rightView.frame = CGRectLayoutOffset(self.rightView.frame, - -kToolbarButtonAnimationOffset); + self.clearButton.hidden = NO; + self.clearButton.alpha = 1.0; + + self.clearButton.frame = CGRectLayoutOffset( + self.clearButton.frame, -[self clearButtonAnimationOffset]); }]; } - (void)addContractOmniboxAnimations:(UIViewPropertyAnimator*)animator { [animator addAnimations:^{ - self.rightView.alpha = 0; - self.rightView.frame = - CGRectLayoutOffset(self.rightView.frame, kToolbarButtonAnimationOffset); + self.clearButton.alpha = 0; + self.clearButton.frame = CGRectLayoutOffset(self.clearButton.frame, + kToolbarButtonAnimationOffset); }]; [animator addCompletion:^(UIViewAnimatingPosition finalPosition) { - self.rightView = nil; + [self resetClearButton]; }]; } @@ -941,4 +943,29 @@ return CGRectZero; } +// Accesses the clear button view when it's available; correctly resolves RTL. +- (UIView*)clearButton { + if ([self isTextFieldLTR]) { + return self.rightView; + } else { + return self.leftView; + } +} + +- (void)resetClearButton { + if ([self isTextFieldLTR]) { + self.rightView = nil; + } else { + self.rightView = nil; + } +} + +- (CGFloat)clearButtonAnimationOffset { + if ([self isTextFieldLTR]) { + return kToolbarButtonAnimationOffset; + } else { + return -kToolbarButtonAnimationOffset; + } +} + @end
diff --git a/ios/chrome/browser/ui/settings/BUILD.gn b/ios/chrome/browser/ui/settings/BUILD.gn index 0e468be..4b8f90c 100644 --- a/ios/chrome/browser/ui/settings/BUILD.gn +++ b/ios/chrome/browser/ui/settings/BUILD.gn
@@ -43,6 +43,8 @@ "password_details_collection_view_controller.h", "password_details_collection_view_controller.mm", "password_details_collection_view_controller_delegate.h", + "password_exporter.h", + "password_exporter.mm", "privacy_collection_view_controller.h", "privacy_collection_view_controller.mm", "reauthentication_module.h", @@ -116,6 +118,7 @@ "//ios/chrome/browser/browser_state", "//ios/chrome/browser/browser_state:browser_state_impl", "//ios/chrome/browser/browsing_data", + "//ios/chrome/browser/browsing_data:browsing_data_internal", "//ios/chrome/browser/content_settings", "//ios/chrome/browser/feature_engagement", "//ios/chrome/browser/history", @@ -181,6 +184,7 @@ "password_details_collection_view_controller_for_testing.h", "personal_data_manager_data_changed_observer.cc", "personal_data_manager_data_changed_observer.h", + "reauthentication_module_for_testing.h", ] deps = [ ":settings", @@ -226,6 +230,7 @@ "import_data_collection_view_controller_unittest.mm", "password_details_collection_view_controller_unittest.mm", "privacy_collection_view_controller_unittest.mm", + "reauthentication_module_unittest.mm", "save_passwords_collection_view_controller_unittest.mm", "search_engine_settings_collection_view_controller_unittest.mm", "settings_navigation_controller_unittest.mm",
diff --git a/ios/chrome/browser/ui/settings/clear_browsing_data_collection_view_controller.mm b/ios/chrome/browser/ui/settings/clear_browsing_data_collection_view_controller.mm index 93b9be4..0bb887d 100644 --- a/ios/chrome/browser/ui/settings/clear_browsing_data_collection_view_controller.mm +++ b/ios/chrome/browser/ui/settings/clear_browsing_data_collection_view_controller.mm
@@ -30,6 +30,7 @@ #include "ios/chrome/browser/application_context.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/browsing_data/browsing_data_counter_wrapper.h" +#import "ios/chrome/browser/browsing_data/browsing_data_removal_controller.h" #include "ios/chrome/browser/browsing_data/ios_browsing_data_counter_factory.h" #include "ios/chrome/browser/browsing_data/ios_chrome_browsing_data_remover.h" #include "ios/chrome/browser/chrome_url_constants.h" @@ -38,6 +39,7 @@ #include "ios/chrome/browser/history/web_history_service_factory.h" #include "ios/chrome/browser/signin/signin_manager_factory.h" #include "ios/chrome/browser/sync/ios_chrome_profile_sync_service_factory.h" +#import "ios/chrome/browser/ui/chrome_web_view_factory.h" #import "ios/chrome/browser/ui/collection_view/cells/MDCCollectionViewCell+Chrome.h" #import "ios/chrome/browser/ui/collection_view/cells/collection_view_detail_item.h" #import "ios/chrome/browser/ui/collection_view/cells/collection_view_footer_item.h" @@ -635,11 +637,29 @@ - (void)clearDataForDataTypes:(int)dataTypeMask { DCHECK(dataTypeMask); - ClearBrowsingDataCommand* command = - [[ClearBrowsingDataCommand alloc] initWithBrowserState:_browserState - mask:dataTypeMask - timePeriod:_timePeriod]; - [self chromeExecuteCommand:command]; + + BrowsingDataRemovalController* browsingDataRemovalController = + [[BrowsingDataRemovalController alloc] init]; + + if (dataTypeMask & IOSChromeBrowsingDataRemover::REMOVE_SITE_DATA) { + [self.dispatcher prepareForBrowsingDataRemoval]; + } + + [browsingDataRemovalController + removeBrowsingDataFromBrowserState:_browserState + mask:dataTypeMask + timePeriod:_timePeriod + completionHandler:^{ + [self.dispatcher browsingDataWasRemoved]; + }]; + + if (dataTypeMask & IOSChromeBrowsingDataRemover::REMOVE_COOKIES) { + base::Time beginDeleteTime = + browsing_data::CalculateBeginDeleteTime(_timePeriod); + [ChromeWebViewFactory clearExternalCookies:_browserState + fromTime:beginDeleteTime + toTime:base::Time::Max()]; + } // Send the "Cleared Browsing Data" event to the feature_engagement::Tracker // when the user initiates a clear browsing data action. No event is sent if
diff --git a/ios/chrome/browser/ui/settings/password_details_collection_view_controller.mm b/ios/chrome/browser/ui/settings/password_details_collection_view_controller.mm index 393ba663..17a8052 100644 --- a/ios/chrome/browser/ui/settings/password_details_collection_view_controller.mm +++ b/ios/chrome/browser/ui/settings/password_details_collection_view_controller.mm
@@ -37,9 +37,6 @@ namespace { -// A help article on how to set up a passcode. -constexpr char kPasscodeArticleURL[] = "https://support.apple.com/HT204060"; - typedef NS_ENUM(NSInteger, SectionIdentifier) { SectionIdentifierSite = kSectionIdentifierEnumZero, SectionIdentifierUsername, @@ -383,6 +380,7 @@ [_weakReauthenticationModule attemptReauthWithLocalizedReason: l10n_util::GetNSString(IDS_IOS_SETTINGS_PASSWORD_REAUTH_REASON_SHOW) + canReusePreviousAuth:YES handler:showPasswordHandler]; } else { [self showPasscodeDialog]; @@ -444,6 +442,7 @@ [_weakReauthenticationModule attemptReauthWithLocalizedReason: l10n_util::GetNSString(IDS_IOS_SETTINGS_PASSWORD_REAUTH_REASON_COPY) + canReusePreviousAuth:YES handler:copyPasswordHandler]; } else { [self showPasscodeDialog];
diff --git a/ios/chrome/browser/ui/settings/password_details_collection_view_controller_unittest.mm b/ios/chrome/browser/ui/settings/password_details_collection_view_controller_unittest.mm index c2be56a..e1330a0 100644 --- a/ios/chrome/browser/ui/settings/password_details_collection_view_controller_unittest.mm +++ b/ios/chrome/browser/ui/settings/password_details_collection_view_controller_unittest.mm
@@ -38,6 +38,7 @@ } - (void)attemptReauthWithLocalizedReason:(NSString*)localizedReason + canReusePreviousAuth:(BOOL)canReusePreviousAuth handler:(void (^)(BOOL success)) showCopyPasswordsHandler { self.localizedReasonForAuthentication = localizedReason;
diff --git a/ios/chrome/browser/ui/settings/password_exporter.h b/ios/chrome/browser/ui/settings/password_exporter.h new file mode 100644 index 0000000..54c0e2e0 --- /dev/null +++ b/ios/chrome/browser/ui/settings/password_exporter.h
@@ -0,0 +1,39 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_EXPORTER_H_ +#define IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_EXPORTER_H_ + +#import <Foundation/Foundation.h> + +@protocol ReauthenticationProtocol; + +@protocol PasswordExporterDelegate<NSObject> + +// Displays a dialog informing the user that they must set up a passcode +// in order to export passwords. +- (void)showSetPasscodeDialog; + +@end + +/** Class handling all the operations necessary to export passwords.*/ +@interface PasswordExporter : NSObject + +// The designated initializer. |reauthenticationModule| and |delegate| must +// not be nil. +- (instancetype)initWithReauthenticationModule: + (id<ReauthenticationProtocol>)reuthenticationModule + delegate: + (id<PasswordExporterDelegate>)delegate + NS_DESIGNATED_INITIALIZER; + +- (instancetype)init NS_UNAVAILABLE; + +// Method to be called in order to start the export flow. This initiates +// the re-authentication procedure and asks for password serialization. +- (void)startExportFlow; + +@end + +#endif // IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_EXPORTER_H_
diff --git a/ios/chrome/browser/ui/settings/password_exporter.mm b/ios/chrome/browser/ui/settings/password_exporter.mm new file mode 100644 index 0000000..3cb73bb --- /dev/null +++ b/ios/chrome/browser/ui/settings/password_exporter.mm
@@ -0,0 +1,64 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/settings/password_exporter.h" + +#include "base/logging.h" +#import "ios/chrome/browser/ui/settings/reauthentication_module.h" +#include "ios/chrome/grit/ios_strings.h" +#include "ui/base/l10n/l10n_util_mac.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +@interface PasswordExporter () { + // Module containing the reauthentication mechanism used for exporting + // passwords. + __weak id<ReauthenticationProtocol> _weakReauthenticationModule; + // Instance of the view controller initiating the export. Used + // for displaying alerts. + __weak id<PasswordExporterDelegate> _weakDelegate; +} + +@end + +@implementation PasswordExporter + +- (instancetype)initWithReauthenticationModule: + (id<ReauthenticationProtocol>)reauthenticationModule + delegate:(id<PasswordExporterDelegate>) + delegate { + DCHECK(delegate); + DCHECK(reauthenticationModule); + self = [super init]; + if (self) { + _weakReauthenticationModule = reauthenticationModule; + _weakDelegate = delegate; + } + return self; +} + +- (void)startExportFlow { + if ([_weakReauthenticationModule canAttemptReauth]) { + // TODO(crbug.com/789122): Ask for password serialization. + [self startReauthentication]; + } else { + [_weakDelegate showSetPasscodeDialog]; + } +} + +#pragma mark - Private methods + +- (void)startReauthentication { + [_weakReauthenticationModule + attemptReauthWithLocalizedReason:l10n_util::GetNSString( + IDS_IOS_EXPORT_PASSWORDS) + canReusePreviousAuth:NO + handler:^(BOOL success){ + // TODO(crbug.com/789122): Store reauth + // result and continue the export flow. + }]; +} +@end
diff --git a/ios/chrome/browser/ui/settings/reauthentication_module.h b/ios/chrome/browser/ui/settings/reauthentication_module.h index fa3c742..a72a23c9 100644 --- a/ios/chrome/browser/ui/settings/reauthentication_module.h +++ b/ios/chrome/browser/ui/settings/reauthentication_module.h
@@ -9,6 +9,9 @@ #import "ios/chrome/browser/ui/settings/reauthentication_protocol.h" +// A help article on how to set up a passcode. +extern const char kPasscodeArticleURL[]; + @protocol SuccessfulReauthTimeAccessor<NSObject> // Method meant to be called by the |ReauthenticationModule| to update @@ -21,9 +24,9 @@ @end /** - * This is used by |PasswordsDetailsCollectionViewController| to re-authenticate - * the user before displaying the password in plain text, or allowing it to be - * copied. + * This is used by |PasswordsDetailsCollectionViewController| and + * |PasswordExporter|to re-authenticate the user before displaying the password + * in plain text, allowing it to be copied, or exporting passwords. */ @interface ReauthenticationModule : NSObject<ReauthenticationProtocol>
diff --git a/ios/chrome/browser/ui/settings/reauthentication_module.mm b/ios/chrome/browser/ui/settings/reauthentication_module.mm index 336331b..f13aa6d 100644 --- a/ios/chrome/browser/ui/settings/reauthentication_module.mm +++ b/ios/chrome/browser/ui/settings/reauthentication_module.mm
@@ -13,9 +13,12 @@ #error "This file requires ARC support." #endif +constexpr char kPasscodeArticleURL[] = "https://support.apple.com/HT204060"; + @implementation ReauthenticationModule { - // Authentication context on which the authentication policy is evaluated. - LAContext* _context; + // Block that creates a new |LAContext| object everytime one is required, + // meant to make testing with a mock object possible. + LAContext* (^_createLAContext)(void); // Accessor allowing the module to request the update of the time when the // successful re-authentication was performed and to get the time of the last @@ -28,21 +31,25 @@ DCHECK(successfulReauthTimeAccessor); self = [super init]; if (self) { - _context = [[LAContext alloc] init]; + _createLAContext = ^{ + return [[LAContext alloc] init]; + }; _successfulReauthTimeAccessor = successfulReauthTimeAccessor; } return self; } - (BOOL)canAttemptReauth { + LAContext* context = _createLAContext(); // The authentication method is Touch ID or passcode. return - [_context canEvaluatePolicy:LAPolicyDeviceOwnerAuthentication error:nil]; + [context canEvaluatePolicy:LAPolicyDeviceOwnerAuthentication error:nil]; } - (void)attemptReauthWithLocalizedReason:(NSString*)localizedReason + canReusePreviousAuth:(BOOL)canReusePreviousAuth handler:(void (^)(BOOL success))handler { - if ([self isPreviousAuthValid]) { + if (canReusePreviousAuth && [self isPreviousAuthValid]) { handler(YES); UMA_HISTOGRAM_ENUMERATION( "PasswordManager.ReauthToAccessPasswordInSettings", @@ -51,10 +58,10 @@ return; } - _context = [[LAContext alloc] init]; + LAContext* context = _createLAContext(); // No fallback option is provided. - _context.localizedFallbackTitle = @""; + context.localizedFallbackTitle = @""; __weak ReauthenticationModule* weakSelf = self; void (^replyBlock)(BOOL, NSError*) = ^(BOOL success, NSError* error) { @@ -74,9 +81,9 @@ }); }; - [_context evaluatePolicy:LAPolicyDeviceOwnerAuthentication - localizedReason:localizedReason - reply:replyBlock]; + [context evaluatePolicy:LAPolicyDeviceOwnerAuthentication + localizedReason:localizedReason + reply:replyBlock]; } - (BOOL)isPreviousAuthValid { @@ -95,4 +102,10 @@ return previousAuthValid; } +#pragma mark - ForTesting + +- (void)setCreateLAContext:(LAContext* (^)(void))createLAContext { + _createLAContext = createLAContext; +} + @end
diff --git a/ios/chrome/browser/ui/settings/reauthentication_module_for_testing.h b/ios/chrome/browser/ui/settings/reauthentication_module_for_testing.h new file mode 100644 index 0000000..4939204 --- /dev/null +++ b/ios/chrome/browser/ui/settings/reauthentication_module_for_testing.h
@@ -0,0 +1,20 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_SETTINGS_REAUTHENTICATION_MODULE_FOR_TESTING_H_ +#define IOS_CHROME_BROWSER_UI_SETTINGS_REAUTHENTICATION_MODULE_FOR_TESTING_H_ + +#import "ios/chrome/browser/ui/settings/reauthentication_module.h" + +#import <LocalAuthentication/LocalAuthentication.h> + +@interface ReauthenticationModule (ForTesting) + +// Allows the replacement of the |LAContext| objects used by +// |ReauthenticationModule| with a mock to facilitate testing. +- (void)setCreateLAContext:(LAContext* (^)(void))createLAContext; + +@end + +#endif // IOS_CHROME_BROWSER_UI_SETTINGS_REAUTHENTICATION_MODULE_FOR_TESTING_H
diff --git a/ios/chrome/browser/ui/settings/reauthentication_module_unittest.mm b/ios/chrome/browser/ui/settings/reauthentication_module_unittest.mm new file mode 100644 index 0000000..3132ba2 --- /dev/null +++ b/ios/chrome/browser/ui/settings/reauthentication_module_unittest.mm
@@ -0,0 +1,117 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/settings/reauthentication_module_for_testing.h" + +#import <LocalAuthentication/LocalAuthentication.h> + +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#import "third_party/ocmock/OCMock/OCMock.h" +#import "third_party/ocmock/gtest_support.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +@interface TestingSuccessfulReauthTimeAccessor + : NSObject<SuccessfulReauthTimeAccessor> { + // Object storing the time of a fake previous successful re-authentication + // to be used by the |ReauthenticationModule|. + NSDate* successfulReauthTime_; +} + +@end + +@implementation TestingSuccessfulReauthTimeAccessor + +- (void)updateSuccessfulReauthTime { + successfulReauthTime_ = [[NSDate alloc] init]; +} + +- (void)updateSuccessfulReauthTime:(NSDate*)time { + successfulReauthTime_ = time; +} + +- (NSDate*)lastSuccessfulReauthTime { + return successfulReauthTime_; +} + +@end + +namespace { + +class ReauthenticationModuleTest : public ::testing::Test { + protected: + ReauthenticationModuleTest() {} + + void SetUp() override { + auth_context_ = [OCMockObject niceMockForClass:[LAContext class]]; + time_accessor_ = [[TestingSuccessfulReauthTimeAccessor alloc] init]; + reauthentication_module_ = [[ReauthenticationModule alloc] + initWithSuccessfulReauthTimeAccessor:time_accessor_]; + [reauthentication_module_ setCreateLAContext:^LAContext*() { + return auth_context_; + }]; + } + + id auth_context_; + TestingSuccessfulReauthTimeAccessor* time_accessor_; + ReauthenticationModule* reauthentication_module_; +}; + +TEST_F(ReauthenticationModuleTest, ReauthReuseNotPermitted) { + [time_accessor_ updateSuccessfulReauthTime]; + + OCMExpect([auth_context_ evaluatePolicy:LAPolicyDeviceOwnerAuthentication + localizedReason:[OCMArg any] + reply:[OCMArg any]]); + [reauthentication_module_ attemptReauthWithLocalizedReason:@"Test" + canReusePreviousAuth:NO + handler:^(BOOL success){ + }]; + + EXPECT_OCMOCK_VERIFY(auth_context_); +} + +TEST_F(ReauthenticationModuleTest, ReauthReusePermittedLessThanSixtySeconds) { + [time_accessor_ updateSuccessfulReauthTime]; + + [[auth_context_ reject] evaluatePolicy:LAPolicyDeviceOwnerAuthentication + localizedReason:[OCMArg any] + reply:[OCMArg any]]; + + // Use @try/@catch as -reject raises an exception. + @try { + [reauthentication_module_ attemptReauthWithLocalizedReason:@"Test" + canReusePreviousAuth:YES + handler:^(BOOL success){ + }]; + EXPECT_OCMOCK_VERIFY(auth_context_); + } @catch (NSException* exception) { + // The exception is raised when + // - attemptReauthWithLocalizedReason:canReusePreviousAuth:handler: + // is invoked. As this should not happen, mark the test as failed. + GTEST_FAIL(); + } +} + +TEST_F(ReauthenticationModuleTest, ReauthReusePermittedMoreThanSixtySeconds) { + const int kIntervalForFakePreviousAuthInSeconds = -70; + [time_accessor_ updateSuccessfulReauthTime: + [NSDate dateWithTimeIntervalSinceNow: + kIntervalForFakePreviousAuthInSeconds]]; + + OCMExpect([auth_context_ evaluatePolicy:LAPolicyDeviceOwnerAuthentication + localizedReason:[OCMArg any] + reply:[OCMArg any]]); + [reauthentication_module_ attemptReauthWithLocalizedReason:@"Test" + canReusePreviousAuth:YES + handler:^(BOOL success){ + }]; + + EXPECT_OCMOCK_VERIFY(auth_context_); +} + +} // namespace
diff --git a/ios/chrome/browser/ui/settings/reauthentication_protocol.h b/ios/chrome/browser/ui/settings/reauthentication_protocol.h index ba63a9e2..57b051ef 100644 --- a/ios/chrome/browser/ui/settings/reauthentication_protocol.h +++ b/ios/chrome/browser/ui/settings/reauthentication_protocol.h
@@ -13,9 +13,12 @@ - (BOOL)canAttemptReauth; // Attempts to reauthenticate the user with Touch ID or passcode if Touch ID is -// not available and the device is running iOS 9. |handler| -// will take action depending on the result of the reauth attempt. +// not available. If |canReusePreviousAuth| is YES, a previous successful +// reauthentication can be taken into consideration, otherwise a new +// reauth attempt must be made. |handler| will take action depending on the +// result of the reauth attempt. - (void)attemptReauthWithLocalizedReason:(NSString*)localizedReason + canReusePreviousAuth:(BOOL)canReusePreviousAuth handler:(void (^)(BOOL success))handler; @end
diff --git a/ios/chrome/browser/ui/settings/save_passwords_collection_view_controller.h b/ios/chrome/browser/ui/settings/save_passwords_collection_view_controller.h index d907dbcd..29c719f 100644 --- a/ios/chrome/browser/ui/settings/save_passwords_collection_view_controller.h +++ b/ios/chrome/browser/ui/settings/save_passwords_collection_view_controller.h
@@ -38,6 +38,7 @@ // |getLoginsFromPasswordStore| finishes. - (void)onGetPasswordStoreResults: (const std::vector<std::unique_ptr<autofill::PasswordForm>>&)result; + @end #endif // IOS_CHROME_BROWSER_UI_SETTINGS_SAVE_PASSWORDS_COLLECTION_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/settings/save_passwords_collection_view_controller.mm b/ios/chrome/browser/ui/settings/save_passwords_collection_view_controller.mm index ab53f18..f58fadc 100644 --- a/ios/chrome/browser/ui/settings/save_passwords_collection_view_controller.mm +++ b/ios/chrome/browser/ui/settings/save_passwords_collection_view_controller.mm
@@ -25,6 +25,7 @@ #include "components/password_manager/core/common/password_manager_pref_names.h" #include "components/prefs/pref_member.h" #include "components/prefs/pref_service.h" +#include "components/strings/grit/components_strings.h" #include "components/url_formatter/url_formatter.h" #include "ios/chrome/browser/application_context.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" @@ -38,6 +39,7 @@ #import "ios/chrome/browser/ui/collection_view/collection_view_model.h" #import "ios/chrome/browser/ui/settings/password_details_collection_view_controller.h" #import "ios/chrome/browser/ui/settings/password_details_collection_view_controller_delegate.h" +#import "ios/chrome/browser/ui/settings/password_exporter.h" #import "ios/chrome/browser/ui/settings/reauthentication_module.h" #import "ios/chrome/browser/ui/settings/settings_utils.h" #import "ios/chrome/browser/ui/settings/utils/pref_backed_boolean.h" @@ -98,6 +100,7 @@ if (!results.empty()) [delegate_ onGetPasswordStoreResults:results]; } + } // namespace password_manager // Use the type of the items to convey the Saved/Blacklisted status. @@ -113,7 +116,8 @@ @interface SavePasswordsCollectionViewController ()< BooleanObserver, PasswordDetailsCollectionViewControllerDelegate, - SuccessfulReauthTimeAccessor> { + SuccessfulReauthTimeAccessor, + PasswordExporterDelegate> { // The observable boolean that binds to the password manager setting state. // Saved passwords are only on if the password manager is enabled. PrefBackedBoolean* passwordManagerEnabled_; @@ -157,10 +161,15 @@ // Kick off async request to get logins from password store. - (void)getLoginsFromPasswordStore; +// Object handling passwords export operations. +@property(nonatomic, strong) PasswordExporter* passwordExporter; + @end @implementation SavePasswordsCollectionViewController +@synthesize passwordExporter = passwordExporter_; + #pragma mark - Initialization - (instancetype)initWithBrowserState:(ios::ChromeBrowserState*)browserState { @@ -172,6 +181,10 @@ browserState_ = browserState; reauthenticationModule_ = [[ReauthenticationModule alloc] initWithSuccessfulReauthTimeAccessor:self]; + passwordExporter_ = [[PasswordExporter alloc] + initWithReauthenticationModule:reauthenticationModule_ + delegate:self]; + self.title = l10n_util::GetNSString(IDS_IOS_SAVE_PASSWORDS); self.collectionViewAccessibilityIdentifier = @"SavePasswordsCollectionViewController"; @@ -487,12 +500,17 @@ handler:nil]; [exportConfirmation addAction:cancelAction]; - // TODO(crbug.com/789122): Ask for password serialization - // and wire re-authentication. + __weak SavePasswordsCollectionViewController* weakSelf = self; UIAlertAction* exportAction = [UIAlertAction actionWithTitle:l10n_util::GetNSString(IDS_IOS_EXPORT_PASSWORDS) style:UIAlertActionStyleDefault - handler:nil]; + handler:^(UIAlertAction* action) { + SavePasswordsCollectionViewController* strongSelf = weakSelf; + if (!strongSelf) { + return; + } + [strongSelf.passwordExporter startExportFlow]; + }]; [exportConfirmation addAction:exportAction]; [self presentViewController:exportConfirmation animated:YES completion:nil]; @@ -706,4 +724,33 @@ return successfulReauthTime_; } +#pragma mark PasswordExporterDelegate + +- (void)showSetPasscodeDialog { + UIAlertController* alertController = [UIAlertController + alertControllerWithTitle:l10n_util::GetNSString( + IDS_IOS_SETTINGS_SET_UP_SCREENLOCK_TITLE) + message: + l10n_util::GetNSString( + IDS_IOS_SETTINGS_EXPORT_PASSWORDS_SET_UP_SCREENLOCK_CONTENT) + preferredStyle:UIAlertControllerStyleAlert]; + + ProceduralBlockWithURL blockOpenURL = BlockToOpenURL(self, self.dispatcher); + UIAlertAction* learnAction = [UIAlertAction + actionWithTitle:l10n_util::GetNSString( + IDS_IOS_SETTINGS_SET_UP_SCREENLOCK_LEARN_HOW) + style:UIAlertActionStyleDefault + handler:^(UIAlertAction*) { + blockOpenURL(GURL(kPasscodeArticleURL)); + }]; + [alertController addAction:learnAction]; + UIAlertAction* okAction = + [UIAlertAction actionWithTitle:l10n_util::GetNSString(IDS_OK) + style:UIAlertActionStyleDefault + handler:nil]; + [alertController addAction:okAction]; + alertController.preferredAction = okAction; + [self presentViewController:alertController animated:YES completion:nil]; +} + @end
diff --git a/ios/chrome/browser/ui/settings/settings_navigation_controller.mm b/ios/chrome/browser/ui/settings/settings_navigation_controller.mm index f91ba7c..c12fd53 100644 --- a/ios/chrome/browser/ui/settings/settings_navigation_controller.mm +++ b/ios/chrome/browser/ui/settings/settings_navigation_controller.mm
@@ -10,9 +10,6 @@ #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/sync/sync_setup_service.h" #include "ios/chrome/browser/sync/sync_setup_service_factory.h" -#import "ios/chrome/browser/ui/commands/UIKit+ChromeExecuteCommand.h" -#import "ios/chrome/browser/ui/commands/clear_browsing_data_command.h" -#include "ios/chrome/browser/ui/commands/ios_command_ids.h" #import "ios/chrome/browser/ui/icons/chrome_icon.h" #import "ios/chrome/browser/ui/keyboard/UIKeyCommand+Chrome.h" #import "ios/chrome/browser/ui/material_components/app_bar_presenting.h" @@ -111,9 +108,6 @@ // Creates an autoreleased "CANCEL" button that closes the settings when tapped. - (UIBarButtonItem*)cancelButton; -// Intercepts some commands and forwards all others up the responder chain. -- (void)chromeExecuteCommand:(id)sender; - @end @implementation SettingsNavigationController { @@ -488,30 +482,6 @@ return NO; } -#pragma mark - UIResponder (ChromeExecuteCommand) - -- (void)chromeExecuteCommand:(id)sender { - switch ([sender tag]) { - case IDC_CLEAR_BROWSING_DATA_IOS: { - // Check that the data for the right browser state is being cleared before - // forwarding it up the responder chain. - ios::ChromeBrowserState* commandBrowserState = - [base::mac::ObjCCast<ClearBrowsingDataCommand>(sender) browserState]; - - // Clearing browsing data for the wrong profile is a destructive action. - // Executing it on the wrong profile is a privacy issue. Kill the - // app if this ever happens. - CHECK_EQ(commandBrowserState, [self mainBrowserState]); - break; - } - default: - NOTREACHED() - << "Unexpected command " << [sender tag] - << " Settings commands must execute on the main browser state."; - } - [[self nextResponder] chromeExecuteCommand:sender]; -} - #pragma mark - UIResponder - (NSArray*)keyCommands {
diff --git a/ios/chrome/browser/ui/toolbar/adaptive/BUILD.gn b/ios/chrome/browser/ui/toolbar/adaptive/BUILD.gn index 202f2d3..0a578fcf 100644 --- a/ios/chrome/browser/ui/toolbar/adaptive/BUILD.gn +++ b/ios/chrome/browser/ui/toolbar/adaptive/BUILD.gn
@@ -4,7 +4,7 @@ source_set("adaptive") { sources = [ - "adaptive_toolbar_coordinator+protected.h", + "adaptive_toolbar_coordinator+subclassing.h", "adaptive_toolbar_coordinator.h", "adaptive_toolbar_coordinator.mm", "primary_toolbar_coordinator.h", @@ -43,6 +43,7 @@ source_set("adaptive_ui") { sources = [ "adaptive_toolbar_view.h", + "adaptive_toolbar_view_controller+subclassing.h", "adaptive_toolbar_view_controller.h", "adaptive_toolbar_view_controller.mm", "primary_toolbar_view.h",
diff --git a/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_coordinator+protected.h b/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_coordinator+subclassing.h similarity index 89% rename from ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_coordinator+protected.h rename to ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_coordinator+subclassing.h index 2f5fee19..2804f544 100644 --- a/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_coordinator+protected.h +++ b/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_coordinator+subclassing.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_UI_TOOLBAR_ADAPTIVE_ADAPTIVE_TOOLBAR_COORDINATOR_PROTECTED_H_ -#define IOS_CHROME_BROWSER_UI_TOOLBAR_ADAPTIVE_ADAPTIVE_TOOLBAR_COORDINATOR_PROTECTED_H_ +#ifndef IOS_CHROME_BROWSER_UI_TOOLBAR_ADAPTIVE_ADAPTIVE_TOOLBAR_COORDINATOR_SUBCLASSING_H_ +#define IOS_CHROME_BROWSER_UI_TOOLBAR_ADAPTIVE_ADAPTIVE_TOOLBAR_COORDINATOR_SUBCLASSING_H_ #import "ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_coordinator.h" @@ -19,4 +19,4 @@ @end -#endif // IOS_CHROME_BROWSER_UI_TOOLBAR_ADAPTIVE_ADAPTIVE_TOOLBAR_COORDINATOR_PROTECTED_H_ +#endif // IOS_CHROME_BROWSER_UI_TOOLBAR_ADAPTIVE_ADAPTIVE_TOOLBAR_COORDINATOR_SUBCLASSING_H_
diff --git a/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_coordinator.mm b/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_coordinator.mm index faf5817..54e5dceb 100644 --- a/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_coordinator.mm +++ b/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_coordinator.mm
@@ -6,7 +6,7 @@ #include "ios/chrome/browser/bookmarks/bookmark_model_factory.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" -#import "ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_coordinator+protected.h" +#import "ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_coordinator+subclassing.h" #import "ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_view_controller.h" #import "ios/chrome/browser/ui/toolbar/clean/toolbar_button_factory.h" #import "ios/chrome/browser/ui/toolbar/clean/toolbar_button_visibility_configuration.h"
diff --git a/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_eg_tests_hook.mm b/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_eg_tests_hook.mm index ccf4600..7fa1b5b 100644 --- a/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_eg_tests_hook.mm +++ b/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_eg_tests_hook.mm
@@ -34,7 +34,7 @@ return true; } -bool ForceAdaptiveToolbar() { +bool ForceUIRefreshPhase1() { return true; }
diff --git a/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_view_controller+subclassing.h b/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_view_controller+subclassing.h new file mode 100644 index 0000000..bda27da --- /dev/null +++ b/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_view_controller+subclassing.h
@@ -0,0 +1,18 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_TOOLBAR_ADAPTIVE_ADAPTIVE_TOOLBAR_VIEW_CONTROLLER_SUBCLASSING_H_ +#define IOS_CHROME_BROWSER_UI_TOOLBAR_ADAPTIVE_ADAPTIVE_TOOLBAR_VIEW_CONTROLLER_SUBCLASSING_H_ + +#import "ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_view_controller.h" + +// Protected interface of the AdaptiveToolbarViewController. +@interface AdaptiveToolbarViewController (Subclassing) + +// Sets the progress of the progressBar to 1 then hides it. +- (void)stopProgressBar; + +@end + +#endif // IOS_CHROME_BROWSER_UI_TOOLBAR_ADAPTIVE_ADAPTIVE_TOOLBAR_VIEW_CONTROLLER_SUBCLASSING_H_
diff --git a/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_view_controller.mm b/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_view_controller.mm index d9b02c8..2d07f1b5 100644 --- a/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_view_controller.mm +++ b/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_view_controller.mm
@@ -95,17 +95,8 @@ self.view.shareButton.enabled = enabled; } -#pragma mark - Private +#pragma mark - Protected -// Updates all buttons visibility to match any recent WebState or SizeClass -// change. -- (void)updateAllButtonsVisibility { - for (ToolbarButton* button in self.view.allButtons) { - [button updateHiddenInCurrentSizeClass]; - } -} - -// Sets the progress of the progressBar to 1 then hides it. - (void)stopProgressBar { __weak MDCProgressView* weakProgressBar = self.view.progressBar; __weak AdaptiveToolbarViewController* weakSelf = self; @@ -119,4 +110,14 @@ }]; } +#pragma mark - Private + +// Updates all buttons visibility to match any recent WebState or SizeClass +// change. +- (void)updateAllButtonsVisibility { + for (ToolbarButton* button in self.view.allButtons) { + [button updateHiddenInCurrentSizeClass]; + } +} + @end
diff --git a/ios/chrome/browser/ui/toolbar/adaptive/primary_toolbar_coordinator.mm b/ios/chrome/browser/ui/toolbar/adaptive/primary_toolbar_coordinator.mm index 0e92376..2849d8b3 100644 --- a/ios/chrome/browser/ui/toolbar/adaptive/primary_toolbar_coordinator.mm +++ b/ios/chrome/browser/ui/toolbar/adaptive/primary_toolbar_coordinator.mm
@@ -14,7 +14,7 @@ #include "ios/chrome/browser/ui/omnibox/location_bar_delegate.h" #import "ios/chrome/browser/ui/omnibox/omnibox_popup_positioner.h" #import "ios/chrome/browser/ui/omnibox/popup/omnibox_popup_coordinator.h" -#import "ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_coordinator+protected.h" +#import "ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_coordinator+subclassing.h" #import "ios/chrome/browser/ui/toolbar/adaptive/primary_toolbar_view_controller.h" #import "ios/chrome/browser/ui/toolbar/clean/toolbar_coordinator_delegate.h" #import "ios/chrome/browser/ui/toolbar/public/web_toolbar_controller_constants.h" @@ -84,7 +84,7 @@ } - (void)showPrerenderingAnimation { - // TODO(crbug.com/803377): Implement that. + [self.viewController showPrerenderingAnimation]; } - (BOOL)isOmniboxFirstResponder {
diff --git a/ios/chrome/browser/ui/toolbar/adaptive/primary_toolbar_view_controller.h b/ios/chrome/browser/ui/toolbar/adaptive/primary_toolbar_view_controller.h index 27e02b8..37b5565 100644 --- a/ios/chrome/browser/ui/toolbar/adaptive/primary_toolbar_view_controller.h +++ b/ios/chrome/browser/ui/toolbar/adaptive/primary_toolbar_view_controller.h
@@ -14,6 +14,9 @@ // Sets the location bar view, containing the omnibox. - (void)setLocationBarView:(UIView*)locationBarView; +// Shows the animation when transitioning to a prerendered page. +- (void)showPrerenderingAnimation; + @end #endif // IOS_CHROME_BROWSER_UI_TOOLBAR_ADAPTIVE_PRIMARY_TOOLBAR_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/toolbar/adaptive/primary_toolbar_view_controller.mm b/ios/chrome/browser/ui/toolbar/adaptive/primary_toolbar_view_controller.mm index d30bcf9a..ce2495a 100644 --- a/ios/chrome/browser/ui/toolbar/adaptive/primary_toolbar_view_controller.mm +++ b/ios/chrome/browser/ui/toolbar/adaptive/primary_toolbar_view_controller.mm
@@ -5,10 +5,12 @@ #import "ios/chrome/browser/ui/toolbar/adaptive/primary_toolbar_view_controller.h" #import "base/logging.h" +#import "ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_view_controller+subclassing.h" #import "ios/chrome/browser/ui/toolbar/adaptive/primary_toolbar_view.h" #import "ios/chrome/browser/ui/toolbar/clean/toolbar_constants.h" #import "ios/chrome/browser/ui/toolbar/clean/toolbar_tools_menu_button.h" #import "ios/chrome/browser/ui/util/named_guide.h" +#import "ios/third_party/material_components_ios/src/components/ProgressView/src/MaterialProgressView.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." @@ -23,6 +25,18 @@ @dynamic view; +#pragma mark - Public + +- (void)showPrerenderingAnimation { + __weak PrimaryToolbarViewController* weakSelf = self; + [self.view.progressBar setProgress:0]; + [self.view.progressBar setHidden:NO + animated:YES + completion:^(BOOL finished) { + [weakSelf stopProgressBar]; + }]; +} + #pragma mark - UIViewController - (void)loadView {
diff --git a/ios/chrome/browser/ui/toolbar/adaptive/secondary_toolbar_coordinator.mm b/ios/chrome/browser/ui/toolbar/adaptive/secondary_toolbar_coordinator.mm index f0a22de6..a0d0918 100644 --- a/ios/chrome/browser/ui/toolbar/adaptive/secondary_toolbar_coordinator.mm +++ b/ios/chrome/browser/ui/toolbar/adaptive/secondary_toolbar_coordinator.mm
@@ -4,7 +4,7 @@ #import "ios/chrome/browser/ui/toolbar/adaptive/secondary_toolbar_coordinator.h" -#import "ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_coordinator+protected.h" +#import "ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_coordinator+subclassing.h" #import "ios/chrome/browser/ui/toolbar/adaptive/secondary_toolbar_view_controller.h" #if !defined(__has_feature) || !__has_feature(objc_arc)
diff --git a/ios/chrome/browser/ui/toolbar/clean/toolbar_configuration.mm b/ios/chrome/browser/ui/toolbar/clean/toolbar_configuration.mm index 00e73d0..971e1ee6 100644 --- a/ios/chrome/browser/ui/toolbar/clean/toolbar_configuration.mm +++ b/ios/chrome/browser/ui/toolbar/clean/toolbar_configuration.mm
@@ -36,7 +36,7 @@ } - (UIColor*)backgroundColor { - if (IsAdaptiveToolbarEnabled()) { + if (IsUIRefreshPhase1Enabled()) { switch (self.style) { case NORMAL: return UIColorFromRGB(kAdaptiveToolbarBackgroundColor); @@ -54,7 +54,7 @@ } - (UIColor*)omniboxBackgroundColor { - if (IsAdaptiveToolbarEnabled()) { + if (IsUIRefreshPhase1Enabled()) { switch (self.style) { case NORMAL: return UIColorFromRGB(kAdaptiveLocationBackgroundColor);
diff --git a/ios/chrome/browser/ui/toolbar/clean/toolbar_coordinator.mm b/ios/chrome/browser/ui/toolbar/clean/toolbar_coordinator.mm index 2ea62cc..73f9d92 100644 --- a/ios/chrome/browser/ui/toolbar/clean/toolbar_coordinator.mm +++ b/ios/chrome/browser/ui/toolbar/clean/toolbar_coordinator.mm
@@ -218,11 +218,6 @@ // TODO(crbug.com/803383): This should be done inside the location bar. // Updates the omnibox. [self.locationBarCoordinator updateOmniboxState]; - // Updates the toolbar buttons. - // TODO(crbug.com/803386): This call is needed for interstitials. Check if it - // is possible to remove it. - if ([self getWebState]) - [self.mediator updateConsumerForWebState:[self getWebState]]; } - (void)updateToolbarForSideSwipeSnapshot:(web::WebState*)webState {
diff --git a/ios/chrome/browser/ui/toolbar/clean/toolbar_mediator.mm b/ios/chrome/browser/ui/toolbar/clean/toolbar_mediator.mm index 9045ffbf..f79370e 100644 --- a/ios/chrome/browser/ui/toolbar/clean/toolbar_mediator.mm +++ b/ios/chrome/browser/ui/toolbar/clean/toolbar_mediator.mm
@@ -119,6 +119,11 @@ [self.consumer setLoadingProgressFraction:progress]; } +- (void)webStateDidChangeVisibleSecurityState:(web::WebState*)webState { + DCHECK_EQ(_webState, webState); + [self updateConsumer]; +} + - (void)webStateDestroyed:(web::WebState*)webState { DCHECK_EQ(_webState, webState); _webState->RemoveObserver(_webStateObserver.get());
diff --git a/ios/chrome/browser/ui/toolbar/clean/toolbar_mediator_unittest.mm b/ios/chrome/browser/ui/toolbar/clean/toolbar_mediator_unittest.mm index 243f223..377e7378 100644 --- a/ios/chrome/browser/ui/toolbar/clean/toolbar_mediator_unittest.mm +++ b/ios/chrome/browser/ui/toolbar/clean/toolbar_mediator_unittest.mm
@@ -382,6 +382,27 @@ } // Test the Toolbar is updated when the Webstate observer method +// didFinishNavigation is called. +TEST_F(ToolbarMediatorTest, TestDidChangeVisibleSecurityState) { + SetUpBookmarks(); + mediator_.webStateList = web_state_list_.get(); + SetUpActiveWebState(); + mediator_.consumer = consumer_; + mediator_.bookmarkModel = bookmark_model_; + + navigation_manager_->set_can_go_forward(true); + navigation_manager_->set_can_go_back(true); + + web_state_->SetCurrentURL(GURL(kTestUrl)); + web_state_->OnVisibleSecurityStateChanged(); + + [[consumer_ verify] setCanGoForward:YES]; + [[consumer_ verify] setCanGoBack:YES]; + [[consumer_ verify] setPageBookmarked:YES]; + [[consumer_ verify] setShareMenuEnabled:YES]; +} + +// Test the Toolbar is updated when the Webstate observer method // didChangeLoadingProgress is called. TEST_F(ToolbarMediatorTest, TestLoadingProgress) { mediator_.webStateList = web_state_list_.get();
diff --git a/ios/chrome/browser/ui/toolbar/clean/toolbar_view_controller.mm b/ios/chrome/browser/ui/toolbar/clean/toolbar_view_controller.mm index 40848be70..4b2be1d 100644 --- a/ios/chrome/browser/ui/toolbar/clean/toolbar_view_controller.mm +++ b/ios/chrome/browser/ui/toolbar/clean/toolbar_view_controller.mm
@@ -241,6 +241,7 @@ - (void)setBackgroundToIncognitoNTPColorWithAlpha:(CGFloat)alpha { self.view.backgroundView.alpha = alpha; self.view.shadowView.alpha = 1 - alpha; + self.view.progressBar.alpha = 1 - alpha; } - (void)showPrerenderingAnimation {
diff --git a/ios/chrome/browser/ui/toolbar/public/primary_toolbar_coordinator.h b/ios/chrome/browser/ui/toolbar/public/primary_toolbar_coordinator.h index cd6a688e..1571f2d 100644 --- a/ios/chrome/browser/ui/toolbar/public/primary_toolbar_coordinator.h +++ b/ios/chrome/browser/ui/toolbar/public/primary_toolbar_coordinator.h
@@ -33,7 +33,7 @@ // Stops the coordinator. - (void)stop; -// Show the animation when transitioning to a prerendered page. +// Shows the animation when transitioning to a prerendered page. - (void)showPrerenderingAnimation; // Whether the omnibox is currently the first responder. - (BOOL)isOmniboxFirstResponder;
diff --git a/ios/chrome/browser/ui/toolbar/toolbar_private_base_feature.h b/ios/chrome/browser/ui/toolbar/toolbar_private_base_feature.h index b418b5c7..fb16e7c 100644 --- a/ios/chrome/browser/ui/toolbar/toolbar_private_base_feature.h +++ b/ios/chrome/browser/ui/toolbar/toolbar_private_base_feature.h
@@ -12,8 +12,4 @@ // function instead. extern const base::Feature kSafeAreaCompatibleToolbar; -// Feature to choose whether to use the Adaptive Toolbar or the standard -// toolbar. -extern const base::Feature kAdaptiveToolbar; - #endif // IOS_CHROME_BROWSER_UI_TOOLBAR_TOOLBAR_PRIVATE_BASE_FEATURE_H_
diff --git a/ios/chrome/browser/ui/toolbar/toolbar_private_base_feature.mm b/ios/chrome/browser/ui/toolbar/toolbar_private_base_feature.mm index ec6570c..889e5ee 100644 --- a/ios/chrome/browser/ui/toolbar/toolbar_private_base_feature.mm +++ b/ios/chrome/browser/ui/toolbar/toolbar_private_base_feature.mm
@@ -10,6 +10,3 @@ const base::Feature kSafeAreaCompatibleToolbar{ "SafeAreaCompatibleToolbar", base::FEATURE_ENABLED_BY_DEFAULT}; - -const base::Feature kAdaptiveToolbar{"AdaptiveToolbar", - base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/ios/chrome/browser/ui/ui_feature_flags.cc b/ios/chrome/browser/ui/ui_feature_flags.cc new file mode 100644 index 0000000..0887a973 --- /dev/null +++ b/ios/chrome/browser/ui/ui_feature_flags.cc
@@ -0,0 +1,8 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ios/chrome/browser/ui/ui_feature_flags.h" + +const base::Feature kUIRefreshPhase1{"UIRefreshPhase1", + base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/ios/chrome/browser/ui/ui_feature_flags.h b/ios/chrome/browser/ui/ui_feature_flags.h new file mode 100644 index 0000000..e57373c5 --- /dev/null +++ b/ios/chrome/browser/ui/ui_feature_flags.h
@@ -0,0 +1,14 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_UI_FEATURE_FLAGS_H_ +#define IOS_CHROME_BROWSER_UI_UI_FEATURE_FLAGS_H_ + +#include "base/feature_list.h" + +// Used to enable the first phase of the UI refresh. This flag should not be +// used directly. Instead use ui_util::IsUIRefreshPhase1Enabled(). +extern const base::Feature kUIRefreshPhase1; + +#endif // IOS_CHROME_BROWSER_UI_UI_FEATURE_FLAGS_H_
diff --git a/ios/chrome/browser/ui/ui_util.h b/ios/chrome/browser/ui/ui_util.h index f3ad79c..1216c42 100644 --- a/ios/chrome/browser/ui/ui_util.h +++ b/ios/chrome/browser/ui/ui_util.h
@@ -39,8 +39,8 @@ // Returns true if the device is an iPhone X. bool IsIPhoneX(); -// Returns whether the feature to display the adaptive toolbar is enabled. -bool IsAdaptiveToolbarEnabled(); +// Returns whether the first phase of the UI refresh will be displayed.. +bool IsUIRefreshPhase1Enabled(); // Returns whether the feature to force the toolbar to respect the safe area is // enabled.
diff --git a/ios/chrome/browser/ui/ui_util.mm b/ios/chrome/browser/ui/ui_util.mm index 5c5ce1c..49813d7 100644 --- a/ios/chrome/browser/ui/ui_util.mm +++ b/ios/chrome/browser/ui/ui_util.mm
@@ -12,6 +12,7 @@ #include "ios/chrome/app/tests_hook.h" #import "ios/chrome/browser/ui/toolbar/public/toolbar_controller_base_feature.h" #import "ios/chrome/browser/ui/toolbar/toolbar_private_base_feature.h" +#import "ios/chrome/browser/ui/ui_feature_flags.h" #import "ios/chrome/browser/ui/uikit_ui_util.h" #include "ui/base/device_form_factor.h" #include "ui/gfx/ios/uikit_util.h" @@ -57,10 +58,10 @@ CGRectGetHeight([[UIScreen mainScreen] nativeBounds]) == 2436); } -bool IsAdaptiveToolbarEnabled() { - if (tests_hook::ForceAdaptiveToolbar()) +bool IsUIRefreshPhase1Enabled() { + if (tests_hook::ForceUIRefreshPhase1()) return true; - return base::FeatureList::IsEnabled(kAdaptiveToolbar); + return base::FeatureList::IsEnabled(kUIRefreshPhase1); } bool IsSafeAreaCompatibleToolbarEnabled() {
diff --git a/ios/chrome/test/app/password_test_util.mm b/ios/chrome/test/app/password_test_util.mm index caf44b2..c84dcb8 100644 --- a/ios/chrome/test/app/password_test_util.mm +++ b/ios/chrome/test/app/password_test_util.mm
@@ -28,6 +28,7 @@ } - (void)attemptReauthWithLocalizedReason:(NSString*)localizedReason + canReusePreviousAuth:(BOOL)canReusePreviousAuth handler:(void (^)(BOOL success)) showCopyPasswordsHandler { showCopyPasswordsHandler(_shouldSucceed);
diff --git a/ios/chrome/test/earl_grey/eg_tests_hook.mm b/ios/chrome/test/earl_grey/eg_tests_hook.mm index c74977e..f1f1ada 100644 --- a/ios/chrome/test/earl_grey/eg_tests_hook.mm +++ b/ios/chrome/test/earl_grey/eg_tests_hook.mm
@@ -34,7 +34,7 @@ return true; } -bool ForceAdaptiveToolbar() { +bool ForceUIRefreshPhase1() { return false; }
diff --git a/ios/web_view/BUILD.gn b/ios/web_view/BUILD.gn index 2d43cd7..5da225b 100644 --- a/ios/web_view/BUILD.gn +++ b/ios/web_view/BUILD.gn
@@ -173,6 +173,7 @@ "//components/autofill/ios/browser", "//components/content_settings/core/browser", "//components/flags_ui", + "//components/image_fetcher/ios", "//components/infobars/core", "//components/keyed_service/core", "//components/keyed_service/ios",
diff --git a/ios/web_view/internal/DEPS b/ios/web_view/internal/DEPS index aaaec8c..b5a9d94 100644 --- a/ios/web_view/internal/DEPS +++ b/ios/web_view/internal/DEPS
@@ -3,6 +3,7 @@ "+components/autofill", "+components/content_settings/core", "+components/flags_ui", + "+components/image_fetcher/ios", "+components/infobars/core", "+components/keyed_service/core", "+components/keyed_service/ios",
diff --git a/ios/web_view/internal/signin/web_view_account_fetcher_service_factory.mm b/ios/web_view/internal/signin/web_view_account_fetcher_service_factory.mm index 277a9a2..1e07672 100644 --- a/ios/web_view/internal/signin/web_view_account_fetcher_service_factory.mm +++ b/ios/web_view/internal/signin/web_view_account_fetcher_service_factory.mm
@@ -7,6 +7,7 @@ #include <utility> #include "base/memory/singleton.h" +#include "components/image_fetcher/ios/ios_image_decoder_impl.h" #include "components/keyed_service/ios/browser_state_dependency_manager.h" #include "components/signin/core/browser/account_fetcher_service.h" #include "components/signin/core/browser/profile_oauth2_token_service.h" @@ -59,7 +60,8 @@ service->Initialize( WebViewSigninClientFactory::GetForBrowserState(browser_state), WebViewOAuth2TokenServiceFactory::GetForBrowserState(browser_state), - WebViewAccountTrackerServiceFactory::GetForBrowserState(browser_state)); + WebViewAccountTrackerServiceFactory::GetForBrowserState(browser_state), + image_fetcher::CreateIOSImageDecoder()); return service; }
diff --git a/net/BUILD.gn b/net/BUILD.gn index 8557659..e73a87eb 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -1817,6 +1817,8 @@ "reporting/reporting_delivery_agent.h", "reporting/reporting_endpoint_manager.cc", "reporting/reporting_endpoint_manager.h", + "reporting/reporting_feature.cc", + "reporting/reporting_feature.h", "reporting/reporting_garbage_collector.cc", "reporting/reporting_garbage_collector.h", "reporting/reporting_header_parser.cc", @@ -2583,10 +2585,10 @@ "log/test_net_log_util.h", "nqe/network_quality_estimator_test_util.cc", "nqe/network_quality_estimator_test_util.h", - "proxy/mock_proxy_resolver.cc", - "proxy/mock_proxy_resolver.h", "proxy/mock_pac_file_fetcher.cc", "proxy/mock_pac_file_fetcher.h", + "proxy/mock_proxy_resolver.cc", + "proxy/mock_proxy_resolver.h", "proxy/proxy_config_service_common_unittest.cc", "proxy/proxy_config_service_common_unittest.h", "socket/socket_test_util.cc", @@ -4975,6 +4977,8 @@ "proxy/mojo_proxy_resolver_v8_tracing_bindings_unittest.cc", "proxy/multi_threaded_proxy_resolver_unittest.cc", "proxy/network_delegate_error_observer_unittest.cc", + "proxy/pac_file_decider_unittest.cc", + "proxy/pac_file_fetcher_impl_unittest.cc", "proxy/proxy_bypass_rules_unittest.cc", "proxy/proxy_config_service_android_unittest.cc", "proxy/proxy_config_service_linux_unittest.cc", @@ -4985,8 +4989,6 @@ "proxy/proxy_resolver_v8_tracing_unittest.cc", "proxy/proxy_resolver_v8_tracing_wrapper_unittest.cc", "proxy/proxy_resolver_v8_unittest.cc", - "proxy/pac_file_decider_unittest.cc", - "proxy/pac_file_fetcher_impl_unittest.cc", "proxy/proxy_server_unittest.cc", "proxy/proxy_service_unittest.cc", "quic/chromium/bidirectional_stream_quic_impl_unittest.cc",
diff --git a/net/network_error_logging/network_error_logging_end_to_end_test.cc b/net/network_error_logging/network_error_logging_end_to_end_test.cc index ffcbc4c..3da56ed6a 100644 --- a/net/network_error_logging/network_error_logging_end_to_end_test.cc +++ b/net/network_error_logging/network_error_logging_end_to_end_test.cc
@@ -5,12 +5,14 @@ #include "base/macros.h" #include "base/run_loop.h" #include "base/strings/stringprintf.h" +#include "base/test/scoped_feature_list.h" #include "base/test/values_test_util.h" #include "base/time/time.h" #include "base/values.h" #include "build/build_config.h" #include "net/base/net_errors.h" #include "net/network_error_logging/network_error_logging_service.h" +#include "net/reporting/reporting_feature.h" #include "net/reporting/reporting_policy.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/embedded_test_server/http_request.h" @@ -55,6 +57,9 @@ : test_server_(test_server::EmbeddedTestServer::TYPE_HTTPS), upload_should_hang_(false), upload_received_(false) { + scoped_feature_list_.InitWithFeatures( + {features::kReporting, features::kNetworkErrorLogging}, {}); + // Make report delivery happen instantly. auto policy = std::make_unique<ReportingPolicy>(); policy->delivery_interval = base::TimeDelta::FromSeconds(0); @@ -140,6 +145,7 @@ return std::move(response); } + base::test::ScopedFeatureList scoped_feature_list_; std::unique_ptr<URLRequestContext> url_request_context_; test_server::EmbeddedTestServer test_server_;
diff --git a/net/network_error_logging/network_error_logging_service.cc b/net/network_error_logging/network_error_logging_service.cc index ebded2f..e9d6f7b 100644 --- a/net/network_error_logging/network_error_logging_service.cc +++ b/net/network_error_logging/network_error_logging_service.cc
@@ -8,6 +8,7 @@ #include <string> #include <utility> +#include "base/feature_list.h" #include "base/json/json_reader.h" #include "base/logging.h" #include "base/memory/ptr_util.h" @@ -23,6 +24,13 @@ #include "url/gurl.h" #include "url/origin.h" +namespace features { + +const base::Feature kNetworkErrorLogging{"NetworkErrorLogging", + base::FEATURE_DISABLED_BY_DEFAULT}; + +} // namespace features + namespace net { namespace { @@ -119,6 +127,9 @@ // static std::unique_ptr<NetworkErrorLoggingService> NetworkErrorLoggingService::Create() { + if (!base::FeatureList::IsEnabled(features::kNetworkErrorLogging)) + return std::unique_ptr<NetworkErrorLoggingService>(); + // Would be MakeUnique, but the constructor is private so MakeUnique can't see // it. return base::WrapUnique(new NetworkErrorLoggingService());
diff --git a/net/network_error_logging/network_error_logging_service_unittest.cc b/net/network_error_logging/network_error_logging_service_unittest.cc index 56fe21fe..e04a2f2 100644 --- a/net/network_error_logging/network_error_logging_service_unittest.cc +++ b/net/network_error_logging/network_error_logging_service_unittest.cc
@@ -10,13 +10,13 @@ #include "base/callback.h" #include "base/macros.h" #include "base/memory/ptr_util.h" +#include "base/test/scoped_feature_list.h" #include "base/test/values_test_util.h" #include "base/time/time.h" #include "base/values.h" #include "net/base/ip_address.h" #include "net/base/net_errors.h" #include "net/network_error_logging/network_error_logging_service.h" -#include "net/reporting/reporting_policy.h" #include "net/reporting/reporting_service.h" #include "net/socket/next_proto.h" #include "testing/gtest/include/gtest/gtest.h" @@ -85,14 +85,8 @@ return true; } - const ReportingPolicy& GetPolicy() const override { - NOTREACHED(); - return dummy_policy_; - } - private: std::vector<Report> reports_; - ReportingPolicy dummy_policy_; DISALLOW_COPY_AND_ASSIGN(TestReportingService); }; @@ -100,6 +94,7 @@ class NetworkErrorLoggingServiceTest : public ::testing::Test { protected: NetworkErrorLoggingServiceTest() { + scoped_feature_list_.InitAndEnableFeature(features::kNetworkErrorLogging); service_ = NetworkErrorLoggingService::Create(); CreateReportingService(); } @@ -163,12 +158,22 @@ const GURL kReferrer_ = GURL("https://referrer.com/"); private: + base::test::ScopedFeatureList scoped_feature_list_; std::unique_ptr<NetworkErrorLoggingService> service_; std::unique_ptr<TestReportingService> reporting_service_; }; -TEST_F(NetworkErrorLoggingServiceTest, CreateService) { - // Service is created by default in the test fixture.. +TEST_F(NetworkErrorLoggingServiceTest, FeatureDisabled) { + // N.B. This test does not actually use the test fixture. + + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndDisableFeature(features::kNetworkErrorLogging); + + auto service = NetworkErrorLoggingService::Create(); + EXPECT_FALSE(service); +} + +TEST_F(NetworkErrorLoggingServiceTest, FeatureEnabled) { EXPECT_TRUE(service()); }
diff --git a/net/quic/chromium/quic_stream_factory.cc b/net/quic/chromium/quic_stream_factory.cc index 97a5306..d5ed39e 100644 --- a/net/quic/chromium/quic_stream_factory.cc +++ b/net/quic/chromium/quic_stream_factory.cc
@@ -326,8 +326,10 @@ int DoResolveHostComplete(int rv); int DoConnect(); int DoConnectComplete(int rv); + int DoConfirmConnection(int rv); - void OnIOComplete(int rv); + void OnResolveHostComplete(int rv); + void OnConnectComplete(int rv); const QuicSessionKey& key() const { return key_; } @@ -369,6 +371,7 @@ STATE_RESOLVE_HOST_COMPLETE, STATE_CONNECT, STATE_CONNECT_COMPLETE, + STATE_CONFIRM_CONNECTION, }; IoState io_state_; @@ -468,6 +471,9 @@ case STATE_CONNECT_COMPLETE: rv = DoConnectComplete(rv); break; + case STATE_CONFIRM_CONNECTION: + rv = DoConfirmConnection(rv); + break; default: NOTREACHED() << "io_state_: " << io_state_; break; @@ -476,16 +482,21 @@ return rv; } -void QuicStreamFactory::Job::OnIOComplete(int rv) { - IoState start_state = io_state_; +void QuicStreamFactory::Job::OnResolveHostComplete(int rv) { + DCHECK_EQ(STATE_RESOLVE_HOST_COMPLETE, io_state_); + rv = DoLoop(rv); - if (start_state == STATE_RESOLVE_HOST_COMPLETE && - !host_resolution_callback_.is_null()) { + if (!host_resolution_callback_.is_null()) base::ResetAndReturn(&host_resolution_callback_).Run(rv); - } - if (rv != ERR_IO_PENDING && !callback_.is_null()) { + + if (rv != ERR_IO_PENDING && !callback_.is_null()) base::ResetAndReturn(&callback_).Run(rv); - } +} + +void QuicStreamFactory::Job::OnConnectComplete(int rv) { + rv = DoLoop(rv); + if (rv != ERR_IO_PENDING && !callback_.is_null()) + base::ResetAndReturn(&callback_).Run(rv); } void QuicStreamFactory::Job::PopulateNetErrorDetails( @@ -507,7 +518,7 @@ io_state_ = STATE_RESOLVE_HOST_COMPLETE; return host_resolver_->Resolve( HostResolver::RequestInfo(key_.destination()), priority_, &address_list_, - base::Bind(&QuicStreamFactory::Job::OnIOComplete, GetWeakPtr()), + base::Bind(&QuicStreamFactory::Job::OnResolveHostComplete, GetWeakPtr()), &request_, net_log_); } @@ -554,7 +565,7 @@ return ERR_QUIC_PROTOCOL_ERROR; rv = session_->CryptoConnect( - base::Bind(&QuicStreamFactory::Job::OnIOComplete, GetWeakPtr())); + base::Bind(&QuicStreamFactory::Job::OnConnectComplete, GetWeakPtr())); if (!session_->connection()->connected() && session_->error() == QUIC_PROOF_INVALID) { @@ -565,6 +576,11 @@ } int QuicStreamFactory::Job::DoConnectComplete(int rv) { + io_state_ = STATE_CONFIRM_CONNECTION; + return rv; +} + +int QuicStreamFactory::Job::DoConfirmConnection(int rv) { net_log_.EndEvent(NetLogEventType::QUIC_STREAM_FACTORY_JOB_CONNECT); if (session_ && session_->error() == QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT) { num_sent_client_hellos_ += session_->GetNumSentClientHellos();
diff --git a/net/reporting/reporting_feature.cc b/net/reporting/reporting_feature.cc new file mode 100644 index 0000000..9f4e28e --- /dev/null +++ b/net/reporting/reporting_feature.cc
@@ -0,0 +1,11 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/reporting/reporting_feature.h" + +namespace features { + +const base::Feature kReporting{"Reporting", base::FEATURE_DISABLED_BY_DEFAULT}; + +} // namespace features
diff --git a/net/reporting/reporting_feature.h b/net/reporting/reporting_feature.h new file mode 100644 index 0000000..4bd3d39 --- /dev/null +++ b/net/reporting/reporting_feature.h
@@ -0,0 +1,17 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NET_REPORTING_REPORTING_FEATURE_H_ +#define NET_REPORTING_REPORTING_FEATURE_H_ + +#include "base/feature_list.h" +#include "net/base/net_export.h" + +namespace features { + +extern const base::Feature NET_EXPORT kReporting; + +} // namespace features + +#endif // NET_REPORTING_REPORTING_FEATURE_H_
diff --git a/net/reporting/reporting_header_parser_fuzzer.cc b/net/reporting/reporting_header_parser_fuzzer.cc index 470d496a..302cc8fb 100644 --- a/net/reporting/reporting_header_parser_fuzzer.cc +++ b/net/reporting/reporting_header_parser_fuzzer.cc
@@ -55,10 +55,10 @@ policy.max_report_age = base::TimeDelta::FromMicroseconds(policy_data.max_report_age_us()); policy.max_report_attempts = policy_data.max_report_attempts(); - policy.clear_reports_on_network_changes = - policy_data.clear_reports_on_network_changes(); - policy.clear_clients_on_network_changes = - policy_data.clear_clients_on_network_changes(); + policy.persist_reports_across_network_changes = + policy_data.persist_reports_across_network_changes(); + policy.persist_clients_across_network_changes = + policy_data.persist_clients_across_network_changes(); } DEFINE_BINARY_PROTO_FUZZER(
diff --git a/net/reporting/reporting_network_change_observer.cc b/net/reporting/reporting_network_change_observer.cc index 20e33a3..c7acb88 100644 --- a/net/reporting/reporting_network_change_observer.cc +++ b/net/reporting/reporting_network_change_observer.cc
@@ -38,11 +38,11 @@ if (type != NetworkChangeNotifier::ConnectionType::CONNECTION_NONE) return; - if (context_->policy().clear_reports_on_network_changes) + if (!context_->policy().persist_reports_across_network_changes) context_->cache()->RemoveAllReports( ReportingReport::Outcome::ERASED_NETWORK_CHANGED); - if (context_->policy().clear_clients_on_network_changes) + if (!context_->policy().persist_clients_across_network_changes) context_->cache()->RemoveAllClients(); }
diff --git a/net/reporting/reporting_network_change_observer_unittest.cc b/net/reporting/reporting_network_change_observer_unittest.cc index ce114d1..ae35fbda8 100644 --- a/net/reporting/reporting_network_change_observer_unittest.cc +++ b/net/reporting/reporting_network_change_observer_unittest.cc
@@ -60,8 +60,8 @@ TEST_F(ReportingNetworkChangeObserverTest, ClearNothing) { ReportingPolicy new_policy = policy(); - new_policy.clear_reports_on_network_changes = false; - new_policy.clear_clients_on_network_changes = false; + new_policy.persist_reports_across_network_changes = true; + new_policy.persist_clients_across_network_changes = true; UsePolicy(new_policy); cache()->AddReport(kUrl_, kGroup_, kType_, @@ -79,8 +79,8 @@ TEST_F(ReportingNetworkChangeObserverTest, ClearReports) { ReportingPolicy new_policy = policy(); - new_policy.clear_reports_on_network_changes = true; - new_policy.clear_clients_on_network_changes = false; + new_policy.persist_reports_across_network_changes = false; + new_policy.persist_clients_across_network_changes = true; UsePolicy(new_policy); cache()->AddReport(kUrl_, kGroup_, kType_, @@ -98,8 +98,8 @@ TEST_F(ReportingNetworkChangeObserverTest, ClearClients) { ReportingPolicy new_policy = policy(); - new_policy.clear_reports_on_network_changes = false; - new_policy.clear_clients_on_network_changes = true; + new_policy.persist_reports_across_network_changes = true; + new_policy.persist_clients_across_network_changes = false; UsePolicy(new_policy); cache()->AddReport(kUrl_, kGroup_, kType_, @@ -117,8 +117,8 @@ TEST_F(ReportingNetworkChangeObserverTest, ClearReportsAndClients) { ReportingPolicy new_policy = policy(); - new_policy.clear_reports_on_network_changes = true; - new_policy.clear_clients_on_network_changes = true; + new_policy.persist_reports_across_network_changes = false; + new_policy.persist_clients_across_network_changes = false; UsePolicy(new_policy); cache()->AddReport(kUrl_, kGroup_, kType_,
diff --git a/net/reporting/reporting_policy.cc b/net/reporting/reporting_policy.cc index 007eb89..1c4d163 100644 --- a/net/reporting/reporting_policy.cc +++ b/net/reporting/reporting_policy.cc
@@ -18,8 +18,8 @@ garbage_collection_interval(base::TimeDelta::FromMinutes(5)), max_report_age(base::TimeDelta::FromMinutes(15)), max_report_attempts(5), - clear_reports_on_network_changes(true), - clear_clients_on_network_changes(false) { + persist_reports_across_network_changes(false), + persist_clients_across_network_changes(true) { endpoint_backoff_policy.num_errors_to_ignore = 0; endpoint_backoff_policy.initial_delay_ms = 60 * 1000; // 1 minute endpoint_backoff_policy.multiply_factor = 2.0;
diff --git a/net/reporting/reporting_policy.h b/net/reporting/reporting_policy.h index 772bff5..86d8858 100644 --- a/net/reporting/reporting_policy.h +++ b/net/reporting/reporting_policy.h
@@ -51,13 +51,13 @@ // discarded as failed. int max_report_attempts; - // Whether to clear reports when the network changes to avoid leaking browsing - // data between networks. - bool clear_reports_on_network_changes; + // Whether to persist (versus clear) reports when the network changes to avoid + // leaking browsing data between networks. + bool persist_reports_across_network_changes; - // Whether to clear clients when the network changes to avoid leaking browsing - // data between networks. - bool clear_clients_on_network_changes; + // Whether to persist (versus clear) clients when the network changes to avoid + // leaking browsing data between networks. + bool persist_clients_across_network_changes; }; } // namespace net
diff --git a/net/reporting/reporting_policy.proto b/net/reporting/reporting_policy.proto index c908b86..c7b9cb0 100644 --- a/net/reporting/reporting_policy.proto +++ b/net/reporting/reporting_policy.proto
@@ -21,8 +21,8 @@ required uint64 garbage_collection_interval_us = 7; required uint64 max_report_age_us = 8; required int32 max_report_attempts = 9; - required bool clear_reports_on_network_changes = 10; - required bool clear_clients_on_network_changes = 11; + required bool persist_reports_across_network_changes = 10; + required bool persist_clients_across_network_changes = 11; } message ReportingHeaderParserFuzzInput {
diff --git a/net/reporting/reporting_service.cc b/net/reporting/reporting_service.cc index 46fbba8e..59976e23 100644 --- a/net/reporting/reporting_service.cc +++ b/net/reporting/reporting_service.cc
@@ -62,10 +62,6 @@ return context_->uploader()->RequestIsUpload(request); } - const ReportingPolicy& GetPolicy() const override { - return context_->policy(); - } - private: std::unique_ptr<ReportingContext> context_;
diff --git a/net/reporting/reporting_service.h b/net/reporting/reporting_service.h index 37958702..aa7dc40e 100644 --- a/net/reporting/reporting_service.h +++ b/net/reporting/reporting_service.h
@@ -70,8 +70,6 @@ // about report uploads. virtual bool RequestIsUpload(const URLRequest& request) = 0; - virtual const ReportingPolicy& GetPolicy() const = 0; - protected: ReportingService() {}
diff --git a/net/ssl/ssl_config.cc b/net/ssl/ssl_config.cc index 72d63d83..75ea0f1d 100644 --- a/net/ssl/ssl_config.cc +++ b/net/ssl/ssl_config.cc
@@ -12,7 +12,7 @@ const uint16_t kDefaultSSLVersionMax = SSL_PROTOCOL_VERSION_TLS1_2; -const TLS13Variant kDefaultTLS13Variant = kTLS13VariantDraft22; +const TLS13Variant kDefaultTLS13Variant = kTLS13VariantDraft23; SSLConfig::CertAndStatus::CertAndStatus() = default; SSLConfig::CertAndStatus::CertAndStatus(scoped_refptr<X509Certificate> cert_arg,
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc index 6cfc3a38..ebb098dd 100644 --- a/net/url_request/url_request_unittest.cc +++ b/net/url_request/url_request_unittest.cc
@@ -144,7 +144,6 @@ #endif #if BUILDFLAG(ENABLE_REPORTING) -#include "net/reporting/reporting_policy.h" #include "net/reporting/reporting_service.h" #include "net/url_request/network_error_logging_delegate.h" #endif // BUILDFLAG(ENABLE_REPORTING) @@ -7050,12 +7049,6 @@ return true; } - const ReportingPolicy& GetPolicy() const override { - static ReportingPolicy dummy_policy_; - NOTIMPLEMENTED(); - return dummy_policy_; - } - private: std::vector<Header> headers_; };
diff --git a/services/network/public/cpp/BUILD.gn b/services/network/public/cpp/BUILD.gn index 7ccd21c..3399f7f6 100644 --- a/services/network/public/cpp/BUILD.gn +++ b/services/network/public/cpp/BUILD.gn
@@ -14,8 +14,6 @@ "mutable_partial_network_traffic_annotation_tag_struct_traits.h", "net_adapters.cc", "net_adapters.h", - "network_features.cc", - "network_features.h", "network_switches.cc", "network_switches.h", "proxy_resolving_client_socket.cc",
diff --git a/services/network/public/cpp/network_features.cc b/services/network/public/cpp/network_features.cc deleted file mode 100644 index ad31b70..0000000 --- a/services/network/public/cpp/network_features.cc +++ /dev/null
@@ -1,13 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "services/network/public/cpp/network_features.h" - -namespace features { - -const base::Feature kReporting{"Reporting", base::FEATURE_DISABLED_BY_DEFAULT}; -const base::Feature kNetworkErrorLogging{"NetworkErrorLogging", - base::FEATURE_DISABLED_BY_DEFAULT}; - -} // namespace features
diff --git a/services/network/public/cpp/network_features.h b/services/network/public/cpp/network_features.h deleted file mode 100644 index 9c818f1..0000000 --- a/services/network/public/cpp/network_features.h +++ /dev/null
@@ -1,17 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef SERVICES_NETWORK_PUBLIC_CPP_NETWORK_FEATURES_ -#define SERVICES_NETWORK_PUBLIC_CPP_NETWORK_FEATURES_ - -#include "base/feature_list.h" - -namespace features { - -extern const base::Feature kReporting; -extern const base::Feature kNetworkErrorLogging; - -} // namespace features - -#endif // SERVICES_NETWORK_PUBLIC_CPP_NETWORK_FEATURES_
diff --git a/services/viz/public/cpp/compositing/struct_traits_unittest.cc b/services/viz/public/cpp/compositing/struct_traits_unittest.cc index 243031d9..6cf37de 100644 --- a/services/viz/public/cpp/compositing/struct_traits_unittest.cc +++ b/services/viz/public/cpp/compositing/struct_traits_unittest.cc
@@ -41,7 +41,6 @@ #include "services/viz/public/cpp/compositing/shared_quad_state_struct_traits.h" #include "services/viz/public/cpp/compositing/surface_id_struct_traits.h" #include "services/viz/public/cpp/compositing/surface_info_struct_traits.h" -#include "services/viz/public/cpp/compositing/surface_sequence_struct_traits.h" #include "services/viz/public/cpp/compositing/transferable_resource_struct_traits.h" #include "services/viz/public/interfaces/compositing/begin_frame_args.mojom.h" #include "services/viz/public/interfaces/compositing/compositor_frame.mojom.h" @@ -49,7 +48,6 @@ #include "services/viz/public/interfaces/compositing/filter_operations.mojom.h" #include "services/viz/public/interfaces/compositing/returned_resource.mojom.h" #include "services/viz/public/interfaces/compositing/surface_info.mojom.h" -#include "services/viz/public/interfaces/compositing/surface_sequence.mojom.h" #include "services/viz/public/interfaces/compositing/transferable_resource.mojom.h" #include "skia/public/interfaces/bitmap_skbitmap_struct_traits.h" #include "skia/public/interfaces/blur_image_filter_tile_mode_struct_traits.h" @@ -448,19 +446,6 @@ EXPECT_EQ(sorting_context_id, output_sqs.sorting_context_id); } -TEST_F(StructTraitsTest, SurfaceSequence) { - const FrameSinkId frame_sink_id(2016, 1234); - const uint32_t sequence = 0xfbadbeef; - - SurfaceSequence input(frame_sink_id, sequence); - SurfaceSequence output; - mojom::SurfaceSequence::Deserialize(mojom::SurfaceSequence::Serialize(&input), - &output); - - EXPECT_EQ(frame_sink_id, output.frame_sink_id); - EXPECT_EQ(sequence, output.sequence); -} - // Note that this is a fairly trivial test of CompositorFrame serialization as // most of the heavy lifting has already been done by CompositorFrameMetadata, // RenderPass, and QuadListBasic unit tests.
diff --git a/services/viz/public/cpp/compositing/surface_sequence.typemap b/services/viz/public/cpp/compositing/surface_sequence.typemap deleted file mode 100644 index b2377ba..0000000 --- a/services/viz/public/cpp/compositing/surface_sequence.typemap +++ /dev/null
@@ -1,12 +0,0 @@ -# Copyright 2016 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -mojom = "//services/viz/public/interfaces/compositing/surface_sequence.mojom" -public_headers = [ "//components/viz/common/surfaces/surface_sequence.h" ] -traits_headers = - [ "//services/viz/public/cpp/compositing/surface_sequence_struct_traits.h" ] -deps = [ - "//components/viz/common", -] -type_mappings = [ "viz.mojom.SurfaceSequence=viz::SurfaceSequence" ]
diff --git a/services/viz/public/cpp/compositing/surface_sequence_struct_traits.h b/services/viz/public/cpp/compositing/surface_sequence_struct_traits.h deleted file mode 100644 index 24563cb02..0000000 --- a/services/viz/public/cpp/compositing/surface_sequence_struct_traits.h +++ /dev/null
@@ -1,35 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef SERVICES_VIZ_PUBLIC_CPP_COMPOSITING_SURFACE_SEQUENCE_STRUCT_TRAITS_H_ -#define SERVICES_VIZ_PUBLIC_CPP_COMPOSITING_SURFACE_SEQUENCE_STRUCT_TRAITS_H_ - -#include "components/viz/common/surfaces/surface_sequence.h" -#include "services/viz/public/interfaces/compositing/surface_sequence.mojom-shared.h" - -namespace mojo { - -template <> -struct StructTraits<viz::mojom::SurfaceSequenceDataView, viz::SurfaceSequence> { - static const viz::FrameSinkId& frame_sink_id(const viz::SurfaceSequence& id) { - return id.frame_sink_id; - } - - static uint32_t sequence(const viz::SurfaceSequence& id) { - return id.sequence; - } - - static bool Read(viz::mojom::SurfaceSequenceDataView data, - viz::SurfaceSequence* out) { - viz::FrameSinkId frame_sink_id; - if (!data.ReadFrameSinkId(&frame_sink_id)) - return false; - *out = viz::SurfaceSequence(frame_sink_id, data.sequence()); - return true; - } -}; - -} // namespace mojo - -#endif // SERVICES_VIZ_PUBLIC_CPP_COMPOSITING_SURFACE_SEQUENCE_STRUCT_TRAITS_H_
diff --git a/services/viz/public/cpp/compositing/typemaps.gni b/services/viz/public/cpp/compositing/typemaps.gni index 689f6f4..5e57cf6 100644 --- a/services/viz/public/cpp/compositing/typemaps.gni +++ b/services/viz/public/cpp/compositing/typemaps.gni
@@ -19,7 +19,6 @@ "//services/viz/public/cpp/compositing/returned_resource.typemap", "//services/viz/public/cpp/compositing/selection.typemap", "//services/viz/public/cpp/compositing/shared_quad_state.typemap", - "//services/viz/public/cpp/compositing/surface_sequence.typemap", "//services/viz/public/cpp/compositing/surface_id.typemap", "//services/viz/public/cpp/compositing/surface_info.typemap", "//services/viz/public/cpp/compositing/transferable_resource.typemap",
diff --git a/services/viz/public/interfaces/BUILD.gn b/services/viz/public/interfaces/BUILD.gn index 7f2c09c..1cad4c4 100644 --- a/services/viz/public/interfaces/BUILD.gn +++ b/services/viz/public/interfaces/BUILD.gn
@@ -28,7 +28,6 @@ "compositing/shared_quad_state.mojom", "compositing/surface_id.mojom", "compositing/surface_info.mojom", - "compositing/surface_sequence.mojom", "compositing/texture_releaser.mojom", "compositing/transferable_resource.mojom", "compositing/video_detector_observer.mojom",
diff --git a/services/viz/public/interfaces/compositing/surface_sequence.mojom b/services/viz/public/interfaces/compositing/surface_sequence.mojom deleted file mode 100644 index 7d59501..0000000 --- a/services/viz/public/interfaces/compositing/surface_sequence.mojom +++ /dev/null
@@ -1,15 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -module viz.mojom; - -import "services/viz/public/interfaces/compositing/frame_sink_id.mojom"; - -// A per-surface-namespace sequence number that's used to coordinate -// dependencies between frames. A sequence number may be satisfied once, and -// may be depended on once. -struct SurfaceSequence { - FrameSinkId frame_sink_id; - uint32 sequence; -};
diff --git a/testing/buildbot/chromium.perf.json b/testing/buildbot/chromium.perf.json index 80ec356f..69307f7 100644 --- a/testing/buildbot/chromium.perf.json +++ b/testing/buildbot/chromium.perf.json
@@ -41832,6 +41832,27 @@ } }, { + "args": [], + "isolate_name": "performance_browser_tests", + "name": "performance_browser_tests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:1626", + "id": "build126-b1", + "os": "Mac-10.11", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 600, + "upload_test_results": true + } + }, + { "args": [ "power.idle_platform", "-v", @@ -49837,6 +49858,27 @@ } }, { + "args": [], + "isolate_name": "performance_browser_tests", + "name": "performance_browser_tests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "1002:6821", + "id": "build132-b1", + "os": "Mac-10.11", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 600, + "upload_test_results": true + } + }, + { "args": [ "power.idle_platform", "-v", @@ -53837,6 +53879,27 @@ } }, { + "args": [], + "isolate_name": "performance_browser_tests", + "name": "performance_browser_tests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:0d26", + "id": "build30-b4", + "os": "Mac-10.11", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 600, + "upload_test_results": true + } + }, + { "args": [ "power.idle_platform", "-v", @@ -65528,6 +65591,27 @@ } }, { + "args": [], + "isolate_name": "performance_browser_tests", + "name": "performance_browser_tests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "1002:6613", + "id": "build103-m1", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 600, + "upload_test_results": true + } + }, + { "args": [ "power.idle_platform", "-v", @@ -69446,6 +69530,27 @@ } }, { + "args": [], + "isolate_name": "performance_browser_tests", + "name": "performance_browser_tests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "8086:041a", + "id": "build166-m1", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 600, + "upload_test_results": true + } + }, + { "args": [ "power.idle_platform", "-v", @@ -81248,6 +81353,27 @@ } }, { + "args": [], + "isolate_name": "performance_browser_tests", + "name": "performance_browser_tests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "102b:0532", + "id": "build140-m1", + "os": "Windows-2008ServerR2-SP1", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 600, + "upload_test_results": true + } + }, + { "args": [ "power.idle_platform", "-v", @@ -85166,6 +85292,27 @@ } }, { + "args": [], + "isolate_name": "performance_browser_tests", + "name": "performance_browser_tests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "102b:0532", + "id": "build145-m1", + "os": "Windows-2012ServerR2-SP0", + "pool": "Chrome-perf" + } + ], + "expiration": 36000, + "hard_timeout": 10800, + "ignore_task_failure": false, + "io_timeout": 600, + "upload_test_results": true + } + }, + { "args": [ "power.idle_platform", "-v",
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG index 282e3db..0dc7dae 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -267,7 +267,6 @@ crbug.com/591099 compositing/overflow/siblings-composited-with-border-radius-ancestor.html [ Failure ] crbug.com/591099 compositing/overflow/siblings-with-border-radius-ancestor.html [ Failure ] crbug.com/591099 compositing/overflow/textarea-scroll-touch.html [ Failure ] -crbug.com/591099 compositing/overflow/theme-affects-visual-overflow.html [ Failure Pass ] crbug.com/591099 compositing/overflow/universal-accelerated-overflow-scroll.html [ Pass Timeout ] crbug.com/591099 compositing/overflow/update-widget-positions-on-nested-frames-and-scrollers.html [ Crash Failure ] crbug.com/591099 compositing/reflections/compositing-change-inside-reflection.html [ Failure ] @@ -720,16 +719,17 @@ crbug.com/591099 css3/filters/effect-invert.html [ Failure ] crbug.com/591099 css3/filters/effect-opacity-hw.html [ Failure ] crbug.com/591099 css3/filters/effect-opacity.html [ Failure ] -crbug.com/714962 css3/filters/effect-reference-image-lazy-attach.html [ Failure ] -crbug.com/714962 css3/filters/effect-reference-image.html [ Failure ] -crbug.com/714962 css3/filters/effect-reference-on-transparent-element.html [ Failure ] +crbug.com/714962 css3/filters/effect-reference-image-lazy-attach.html [ Failure Pass ] +crbug.com/714962 css3/filters/effect-reference-image.html [ Failure Pass ] +crbug.com/714962 css3/filters/effect-reference-on-transparent-element.html [ Failure Pass ] crbug.com/714962 css3/filters/effect-reference-tile.html [ Crash ] +crbug.com/714962 css3/filters/effect-reference-zoom-hw.html [ Failure ] crbug.com/591099 css3/filters/effect-saturate-hw.html [ Failure ] crbug.com/591099 css3/filters/effect-saturate.html [ Failure ] crbug.com/591099 css3/filters/effect-sepia-hw.html [ Failure ] crbug.com/591099 css3/filters/effect-sepia.html [ Failure ] -crbug.com/714962 css3/filters/empty-element-with-filter.html [ Failure ] -crbug.com/714962 css3/filters/filterRegions.html [ Failure ] +crbug.com/714962 css3/filters/empty-element-with-filter.html [ Failure Pass ] +crbug.com/714962 css3/filters/filterRegions.html [ Failure Pass ] crbug.com/591099 css3/filters/filtered-inline.html [ Failure ] crbug.com/714962 css3/filters/nested-filter.html [ Failure ] crbug.com/591099 css3/filters/regions-expanding.html [ Failure ] @@ -1021,7 +1021,7 @@ crbug.com/591099 editing/deleting/merge-no-br.html [ Failure ] crbug.com/591099 editing/deleting/merge-whitespace-pre.html [ Failure ] crbug.com/591099 editing/deleting/table-cells.html [ Failure ] -crbug.com/591099 editing/deleting/transpose-empty.html [ Failure ] +crbug.com/591099 editing/deleting/transpose-empty.html [ Failure Pass ] crbug.com/591099 editing/deleting/type-delete-after-quote.html [ Failure ] crbug.com/591099 editing/execCommand/12244.html [ Failure ] crbug.com/591099 editing/execCommand/4580583-1.html [ Failure ] @@ -1180,7 +1180,6 @@ crbug.com/714962 editing/selection/drag-drop-events.html [ Failure ] crbug.com/714962 editing/selection/drag-drop-restore.html [ Failure ] crbug.com/591099 editing/selection/drag-in-iframe.html [ Failure ] -crbug.com/591099 editing/selection/drag-select-1.html [ Failure Pass ] crbug.com/714962 editing/selection/drag-select-rapidly.html [ Failure ] crbug.com/714962 editing/selection/drag-text-delay.html [ Failure ] crbug.com/591099 editing/selection/drag-to-contenteditable-iframe.html [ Failure ] @@ -1233,6 +1232,7 @@ crbug.com/591099 editing/selection/mouse/extend_by_word_with_base_is_end.html [ Failure ] crbug.com/714962 editing/selection/mouse/mouse_up_focus.html [ Timeout ] crbug.com/714962 editing/selection/mouse/overidden_user_select_in_dom_tree.html [ Failure ] +crbug.com/591099 editing/selection/mouse/overriden_user_select_in_shadow_tree.html [ Failure ] crbug.com/714962 editing/selection/mouse/user-drag-element-and-user-select-none.html [ Failure ] crbug.com/591099 editing/selection/move-3875618-fix.html [ Failure ] crbug.com/591099 editing/selection/move-3875641-fix.html [ Failure ] @@ -1280,7 +1280,6 @@ crbug.com/591099 editing/selection/selection-background.html [ Failure ] crbug.com/591099 editing/selection/selection-button-text.html [ Failure ] crbug.com/591099 editing/selection/selection-invalid-offset.html [ Failure ] -crbug.com/591099 editing/selection/selection-linebreaks-rtl-writing-modes.html [ Failure Pass ] crbug.com/591099 editing/selection/shift-click.html [ Failure ] crbug.com/714962 editing/selection/skip-over-contenteditable.html [ Failure ] crbug.com/591099 editing/selection/subpixel-positioned-selection.html [ Failure ] @@ -1330,7 +1329,7 @@ crbug.com/591099 external/wpt/WebCryptoAPI/generateKey/failures_ECDH.worker.html [ Timeout ] crbug.com/591099 external/wpt/WebCryptoAPI/generateKey/failures_ECDSA.worker.html [ Timeout ] crbug.com/591099 external/wpt/WebCryptoAPI/generateKey/failures_HMAC.worker.html [ Timeout ] -crbug.com/714962 external/wpt/WebCryptoAPI/generateKey/failures_RSA-OAEP.https.worker.html [ Timeout ] +crbug.com/714962 external/wpt/WebCryptoAPI/generateKey/failures_RSA-OAEP.https.worker.html [ Pass Timeout ] crbug.com/591099 external/wpt/WebCryptoAPI/generateKey/failures_RSA-OAEP.worker.html [ Timeout ] crbug.com/591099 external/wpt/WebCryptoAPI/generateKey/failures_RSA-PSS.worker.html [ Timeout ] crbug.com/591099 external/wpt/WebCryptoAPI/generateKey/failures_RSASSA-PKCS1-v1_5.worker.html [ Timeout ] @@ -1339,7 +1338,7 @@ crbug.com/709227 external/wpt/WebCryptoAPI/import_export/symmetric_importKey.worker.html [ Failure ] crbug.com/714962 external/wpt/WebCryptoAPI/import_export/test_rsa_importKey.https.html [ Pass Timeout ] crbug.com/591099 external/wpt/acid/acid3/test.html [ Crash ] -crbug.com/591099 external/wpt/compat/webkit-text-fill-color-property-005.html [ Failure Pass ] +crbug.com/591099 external/wpt/compat/webkit-text-fill-color-property-005.html [ Pass ] crbug.com/591099 external/wpt/credential-management/federatedcredential-framed-get.sub.https.html [ Pass ] crbug.com/591099 external/wpt/credential-management/passwordcredential-framed-get.sub.https.html [ Pass ] crbug.com/591099 external/wpt/css/CSS2/floats/floats-wrap-bfc-003-left-table.xht [ Failure ] @@ -1364,7 +1363,6 @@ crbug.com/714962 external/wpt/css/css-backgrounds/background-image-004.html [ Failure Pass ] crbug.com/714962 external/wpt/css/css-backgrounds/background-image-005.html [ Failure ] crbug.com/714962 external/wpt/css/css-backgrounds/background-image-006.html [ Failure Pass ] -crbug.com/714962 external/wpt/css/css-backgrounds/css3-background-clip.html [ Failure ] crbug.com/714962 external/wpt/css/css-display/display-contents-dynamic-before-after-001.html [ Failure ] crbug.com/714962 external/wpt/css/css-display/display-contents-dynamic-before-after-first-letter-001.html [ Failure ] crbug.com/591099 external/wpt/css/css-display/display-contents-dynamic-table-001-inline.html [ Failure ] @@ -1720,15 +1718,15 @@ crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-icb-vrl-018.xht [ Pass ] crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-icb-vrl-020.xht [ Pass ] crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-icb-vrl-030.xht [ Pass ] -crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-003.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-005.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-003.xht [ Failure Pass ] +crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-005.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-007.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-009.xht [ Failure Pass ] -crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-011.xht [ Failure ] -crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-013.xht [ Failure ] +crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-011.xht [ Failure Pass ] +crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-013.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-015.xht [ Failure Pass ] -crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-017.xht [ Failure ] -crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-019.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-017.xht [ Failure Pass ] +crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-019.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-021.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-023.xht [ Failure ] crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-025.xht [ Failure Pass ] @@ -1737,23 +1735,23 @@ crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-031.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-033.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-035.xht [ Failure ] -crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-037.xht [ Failure ] +crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-037.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-039.xht [ Failure ] crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-041.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-043.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-045.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-047.xht [ Failure ] -crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-049.xht [ Failure ] -crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-051.xht [ Failure ] +crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-049.xht [ Failure Pass ] +crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-051.xht [ Failure Pass ] crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-053.xht [ Failure Pass ] -crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-055.xht [ Failure ] +crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-055.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-057.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-059.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-061.xht [ Failure Pass ] -crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-063.xht [ Failure ] +crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-063.xht [ Failure Pass ] crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-065.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-067.xht [ Failure Pass ] -crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-069.xht [ Failure ] +crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-069.xht [ Failure Pass ] crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-071.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-073.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-075.xht [ Failure ] @@ -1762,19 +1760,19 @@ crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-081.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-083.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-085.xht [ Failure ] -crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-087.xht [ Failure ] +crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-087.xht [ Failure Pass ] crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-089.xht [ Failure Pass ] -crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-091.xht [ Failure ] -crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-093.xht [ Failure ] +crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-091.xht [ Failure Pass ] +crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-093.xht [ Failure Pass ] crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-095.xht [ Failure Pass ] -crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-097.xht [ Failure ] +crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-097.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-103.xht [ Failure ] crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-105.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-107.xht [ Failure Pass ] crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-109.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-111.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-113.xht [ Failure Pass ] -crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-115.xht [ Failure ] +crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-115.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-117.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-119.xht [ Failure ] crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-121.xht [ Failure Pass ] @@ -1786,7 +1784,7 @@ crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-133.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-135.xht [ Failure Pass ] crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-137.xht [ Failure ] -crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-139.xht [ Failure ] +crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-139.xht [ Failure Pass ] crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-141.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-143.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-145.xht [ Failure Pass ] @@ -1803,12 +1801,12 @@ crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-167.xht [ Failure Pass ] crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-169.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-171.xht [ Failure Pass ] -crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-173.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-173.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-175.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-177.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-179.xht [ Failure Pass ] crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-181.xht [ Failure Pass ] -crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-183.xht [ Failure ] +crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-183.xht [ Failure Pass ] crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-185.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-187.xht [ Failure Pass ] crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-189.xht [ Failure Pass ] @@ -1831,15 +1829,15 @@ crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-223.xht [ Failure ] crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-225.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-227.xht [ Failure Pass ] -crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-229.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-229.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-002.xht [ Failure ] crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-004.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-006.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-008.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-010.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-010.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-012.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-014.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-016.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-016.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-018.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-020.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-022.xht [ Failure ] @@ -1896,14 +1894,14 @@ crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-128.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-130.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-132.xht [ Failure ] -crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-134.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-136.xht [ Failure ] +crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-134.xht [ Failure Pass ] +crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-136.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-138.xht [ Failure ] crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-140.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-142.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-144.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-144.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-146.xht [ Failure ] -crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-148.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-148.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-150.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-152.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-154.xht [ Failure ] @@ -1919,7 +1917,7 @@ crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-174.xht [ Failure Pass ] crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-176.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-178.xht [ Failure ] -crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-180.xht [ Failure ] +crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-180.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-182.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-184.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-186.xht [ Failure ] @@ -1958,21 +1956,21 @@ crbug.com/591099 external/wpt/css/css-writing-modes/clearance-calculations-vrl-004.xht [ Failure ] crbug.com/591099 external/wpt/css/css-writing-modes/clearance-calculations-vrl-006.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/clearance-calculations-vrl-008.xht [ Failure ] -crbug.com/714962 external/wpt/css/css-writing-modes/direction-vlr-003.xht [ Failure ] +crbug.com/714962 external/wpt/css/css-writing-modes/direction-vlr-003.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/direction-vlr-005.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/direction-vrl-002.xht [ Failure Pass ] -crbug.com/714962 external/wpt/css/css-writing-modes/direction-vrl-004.xht [ Failure ] +crbug.com/714962 external/wpt/css/css-writing-modes/direction-vrl-004.xht [ Failure Pass ] crbug.com/591099 external/wpt/css/css-writing-modes/float-contiguous-vrl-002.xht [ Failure ] crbug.com/591099 external/wpt/css/css-writing-modes/float-contiguous-vrl-004.xht [ Failure ] crbug.com/591099 external/wpt/css/css-writing-modes/float-contiguous-vrl-006.xht [ Failure ] crbug.com/591099 external/wpt/css/css-writing-modes/float-contiguous-vrl-008.xht [ Failure ] crbug.com/591099 external/wpt/css/css-writing-modes/float-lft-orthog-htb-in-vrl-002.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/float-shrink-to-fit-vrl-008.xht [ Failure ] -crbug.com/714962 external/wpt/css/css-writing-modes/float-vlr-005.xht [ Failure ] +crbug.com/714962 external/wpt/css/css-writing-modes/float-vlr-005.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/float-vlr-007.xht [ Failure Pass ] crbug.com/591099 external/wpt/css/css-writing-modes/float-vlr-013.xht [ Failure ] crbug.com/591099 external/wpt/css/css-writing-modes/float-vrl-004.xht [ Failure Pass ] -crbug.com/591099 external/wpt/css/css-writing-modes/float-vrl-006.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-writing-modes/float-vrl-006.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/float-vrl-008.xht [ Failure ] crbug.com/591099 external/wpt/css/css-writing-modes/float-vrl-012.xht [ Failure ] crbug.com/591099 external/wpt/css/css-writing-modes/horizontal-rule-vrl-002.xht [ Failure ] @@ -2046,18 +2044,18 @@ crbug.com/591099 external/wpt/css/css-writing-modes/table-column-order-005.xht [ Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-003.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-005.xht [ Failure Pass ] -crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-007.xht [ Failure ] -crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-009.xht [ Failure ] +crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-007.xht [ Failure Pass ] +crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-009.xht [ Failure Pass ] crbug.com/591099 external/wpt/css/css-writing-modes/text-align-vlr-011.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-013.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-015.xht [ Failure Pass ] -crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-017.xht [ Failure ] -crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-019.xht [ Failure ] +crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-017.xht [ Failure Pass ] +crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-019.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-002.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-004.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-006.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-008.xht [ Failure Pass ] -crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-010.xht [ Failure ] +crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-010.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-012.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-014.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-016.xht [ Failure ] @@ -2066,7 +2064,7 @@ crbug.com/591099 external/wpt/css/css-writing-modes/text-baseline-vrl-006.xht [ Failure ] crbug.com/591099 external/wpt/css/css-writing-modes/text-combine-upright-decorations-001.html [ Failure ] crbug.com/591099 external/wpt/css/css-writing-modes/text-combine-upright-layout-rules-001.html [ Failure ] -crbug.com/714962 external/wpt/css/css-writing-modes/text-indent-vlr-003.xht [ Failure ] +crbug.com/714962 external/wpt/css/css-writing-modes/text-indent-vlr-003.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/text-indent-vlr-005.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/text-indent-vlr-011.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/text-indent-vlr-013.xht [ Failure Pass ] @@ -2114,8 +2112,8 @@ crbug.com/591099 external/wpt/css/cssom-view/elementsFromPoint-svg.html [ Failure ] crbug.com/714962 external/wpt/css/cssom/medialist-dynamic-001.html [ Failure ] crbug.com/626703 external/wpt/css/cssom/stylesheet-replacedata-dynamic.html [ Failure ] -crbug.com/591099 external/wpt/css/geometry/interfaces.html [ Timeout ] -crbug.com/591099 external/wpt/css/geometry/interfaces.worker.html [ Timeout ] +crbug.com/591099 external/wpt/css/geometry/interfaces.html [ Pass Timeout ] +crbug.com/591099 external/wpt/css/geometry/interfaces.worker.html [ Pass Timeout ] crbug.com/714962 external/wpt/css/selectors/focus-within-001.html [ Failure ] crbug.com/591099 external/wpt/css/selectors/focus-within-004.html [ Failure ] crbug.com/714962 external/wpt/css/selectors/focus-within-007.html [ Failure ] @@ -2282,7 +2280,7 @@ crbug.com/591099 external/wpt/feature-policy/autoplay-allowed-by-feature-policy.https.sub.html [ Failure ] crbug.com/591099 external/wpt/feature-policy/payment-allowed-by-feature-policy.https.sub.html [ Pass ] crbug.com/591099 external/wpt/feature-policy/payment-disabled-by-feature-policy.https.sub.html [ Pass ] -crbug.com/591099 external/wpt/geolocation-API/PositionOptions.https.html [ Failure ] +crbug.com/591099 external/wpt/geolocation-API/PositionOptions.https.html [ Failure Pass ] crbug.com/591099 external/wpt/html-media-capture/capture_audio_cancel-manual.html [ Failure ] crbug.com/591099 external/wpt/html-media-capture/capture_image_cancel-manual.html [ Failure ] crbug.com/591099 external/wpt/html-media-capture/capture_video_cancel-manual.html [ Failure ] @@ -2359,7 +2357,6 @@ crbug.com/591099 external/wpt/intersection-observer/remove-element.html [ Failure ] crbug.com/714962 external/wpt/intersection-observer/root-margin.html [ Failure ] crbug.com/591099 external/wpt/intersection-observer/same-document-root.html [ Failure ] -crbug.com/591099 external/wpt/keyboard-lock/navigator-keyboardLock-two-parallel-requests.https.html [ Failure Pass ] crbug.com/591099 external/wpt/longtask-timing/longtask-in-sibling-iframe.html [ Pass Timeout ] crbug.com/591099 external/wpt/media-source/mediasource-getvideoplaybackquality.html [ Timeout ] crbug.com/591099 external/wpt/mediacapture-streams/MediaStreamTrack-getSettings.https.html [ Pass ] @@ -3013,6 +3010,7 @@ crbug.com/591099 fast/css/hover-affects-ancestor.html [ Failure ] crbug.com/714962 fast/css/hover-pseudo-element-quirks.html [ Failure ] crbug.com/591099 fast/css/hover-subselector.html [ Failure ] +crbug.com/591099 fast/css/hover-update.html [ Timeout ] crbug.com/591099 fast/css/hsl-color.html [ Failure ] crbug.com/591099 fast/css/hsla-color.html [ Failure ] crbug.com/591099 fast/css/ignore-empty-focus-ring-rects.html [ Failure ] @@ -3453,6 +3451,7 @@ crbug.com/591099 fast/events/mousemove-to-resizer-changes-cursor.html [ Failure ] crbug.com/591099 fast/events/mouseover-mouseout.html [ Failure ] crbug.com/591099 fast/events/no-blur-on-enter-button.html [ Failure ] +crbug.com/591099 fast/events/node-event-anchor-lock.html [ Failure ] crbug.com/714962 fast/events/offsetX-offsetY.html [ Failure ] crbug.com/591099 fast/events/onblur-remove.html [ Failure ] crbug.com/714962 fast/events/onchange-click-hang.html [ Failure ] @@ -3460,6 +3459,7 @@ crbug.com/591099 fast/events/onclick-list-marker.html [ Failure ] crbug.com/591099 fast/events/onload-re-entry.html [ Failure ] crbug.com/591099 fast/events/onload-webkit-before-webcore.html [ Failure ] +crbug.com/591099 fast/events/open-window-from-another-frame.html [ Timeout ] crbug.com/591099 fast/events/pointer-events-2.html [ Failure ] crbug.com/714962 fast/events/pointerevents/mouse-node-remove.html [ Failure ] crbug.com/714962 fast/events/pointerevents/mouse-pointer-boundary-events-for-shadowdom.html [ Failure ] @@ -3567,7 +3567,7 @@ crbug.com/714962 fast/forms/calendar-picker/month-picker-mouse-operations.html [ Failure ] crbug.com/714962 fast/forms/calendar-picker/week-picker-appearance-step.html [ Failure ] crbug.com/714962 fast/forms/calendar-picker/week-picker-appearance.html [ Failure ] -crbug.com/591099 fast/forms/calendar-picker/week-picker-key-operations.html [ Timeout ] +crbug.com/591099 fast/forms/calendar-picker/week-picker-key-operations.html [ Pass Timeout ] crbug.com/714962 fast/forms/calendar-picker/week-picker-mouse-operations.html [ Failure ] crbug.com/591099 fast/forms/caret-rtl.html [ Failure ] crbug.com/714962 fast/forms/checkbox/checkbox-focus-by-mouse.html [ Failure ] @@ -3673,7 +3673,7 @@ crbug.com/591099 fast/forms/label/labels-remove-htmlFor-label.html [ Crash ] crbug.com/591099 fast/forms/label/labels-remove-parent-label.html [ Crash ] crbug.com/591099 fast/forms/label/labels-set-htmlFor-attribute.html [ Crash ] -crbug.com/591099 fast/forms/label/selection-disabled-label.html [ Failure ] +crbug.com/591099 fast/forms/label/selection-disabled-label.html [ Failure Crash ] crbug.com/591099 fast/forms/long-text-in-input.html [ Crash Failure ] crbug.com/591099 fast/forms/mailto/advanced-get.html [ Failure ] crbug.com/591099 fast/forms/mailto/advanced-put.html [ Failure ] @@ -3974,6 +3974,7 @@ crbug.com/591099 fast/forms/textarea/textarea-setinnerhtml.html [ Failure ] crbug.com/591099 fast/forms/textarea/textarea-width.html [ Failure ] crbug.com/714962 fast/forms/time-multiple-fields/time-multiple-fields-clearbutton-change-and-input-events.html [ Failure ] +crbug.com/591099 fast/forms/time-multiple-fields/time-multiple-fields-focus.html [ Failure ] crbug.com/714962 fast/forms/time-multiple-fields/time-multiple-fields-mouse-events.html [ Failure ] crbug.com/714962 fast/forms/time-multiple-fields/time-multiple-fields-narrow-width-scroll.html [ Failure ] crbug.com/714962 fast/forms/time-multiple-fields/time-multiple-fields-spinbutton-change-and-input-events.html [ Failure ] @@ -4109,6 +4110,7 @@ crbug.com/591099 fast/inline/inline-with-empty-inline-children.html [ Failure ] crbug.com/591099 fast/inline/inline-wrap-with-parent-padding.html [ Failure ] crbug.com/591099 fast/inline/justify-emphasis-inline-box.html [ Failure ] +crbug.com/591099 fast/inline/layout-after-inserting-nested-br.html [ Failure ] crbug.com/591099 fast/inline/left-right-center-inline-alignment-in-ltr-and-rtl-blocks.html [ Failure ] crbug.com/591099 fast/inline/outline-continuations.html [ Failure ] crbug.com/714962 fast/inline/outline-offset.html [ Failure ] @@ -4205,7 +4207,7 @@ crbug.com/591099 fast/lists/ordered-list-with-no-ol-tag.html [ Failure ] crbug.com/591099 fast/lists/remove-listmarker-and-make-anonblock-empty-2.html [ Failure ] crbug.com/591099 fast/lists/remove-listmarker-from-anonblock-with-continuation-crash.html [ Crash ] -crbug.com/591099 fast/loader/child-frame-add-after-back-forward.html [ Timeout ] +crbug.com/591099 fast/loader/child-frame-add-after-back-forward.html [ Timeout Failure ] crbug.com/591099 fast/loader/document-with-fragment-url-1.html [ Timeout ] crbug.com/591099 fast/loader/document-with-fragment-url-3.html [ Timeout ] crbug.com/591099 fast/loader/document-with-fragment-url-4.html [ Timeout ] @@ -4743,7 +4745,7 @@ crbug.com/714962 fast/replaced/vertical-rl/absolute-position-with-auto-height-and-top-and-bottom.html [ Failure ] crbug.com/714962 fast/replaced/vertical-rl/absolute-position-with-auto-width-and-left-and-right.html [ Failure ] crbug.com/591099 fast/replaced/width100percent-image.html [ Failure ] -crbug.com/714962 fast/replaced/width100percent-textarea.html [ Failure ] +crbug.com/714962 fast/replaced/width100percent-textarea.html [ Failure Pass ] crbug.com/591099 fast/ruby/add-text-to-block-ruby-with-after-pseudo-crash.html [ Crash ] crbug.com/591099 fast/ruby/base-shorter-than-text.html [ Failure ] crbug.com/591099 fast/ruby/float-object-doesnt-crash.html [ Crash ] @@ -5238,7 +5240,6 @@ crbug.com/591099 fast/text/sub-pixel/text-scaling-pixel.html [ Failure ] crbug.com/714962 fast/text/tab-min-size.html [ Failure Pass ] crbug.com/714962 fast/text/text-range-bounds.html [ Failure ] -crbug.com/591099 fast/text/textIteratorNilRenderer.html [ Failure Pass ] crbug.com/591099 fast/text/trailing-white-space-2.html [ Failure ] crbug.com/714962 fast/text/transform-text-first-line-capitalize.html [ Failure ] crbug.com/714962 fast/text/transform-text-first-line-lowercase.html [ Failure ] @@ -5625,6 +5626,7 @@ crbug.com/591099 http/tests/devtools/elements/navigate-styles-sidebar-with-arrow-keys.js [ Crash Pass ] crbug.com/714962 http/tests/devtools/elements/shadow/breadcrumb-shadow-roots.js [ Crash ] crbug.com/714962 http/tests/devtools/elements/shadow/create-shadow-root.js [ Crash ] +crbug.com/591099 http/tests/devtools/elements/shadow/elements-panel-shadow-selection-on-refresh-1.js [ Crash ] crbug.com/714962 http/tests/devtools/elements/shadow/inspect-deep-shadow-element.js [ Crash ] crbug.com/714962 http/tests/devtools/elements/shadow/shadow-distribution.js [ Crash ] crbug.com/714962 http/tests/devtools/elements/shadow/shadow-host-display-modes.js [ Crash ] @@ -5692,13 +5694,14 @@ crbug.com/591099 http/tests/devtools/sources/debugger-breakpoints/dom-breakpoints.js [ Crash ] crbug.com/591099 http/tests/devtools/sources/debugger-frameworks/frameworks-dom-xhr-event-breakpoints.js [ Crash ] crbug.com/591099 http/tests/devtools/sources/debugger-frameworks/frameworks-jquery.js [ Crash Pass ] +crbug.com/591099 http/tests/devtools/sources/debugger-frameworks/frameworks-steppings.js [ Crash ] crbug.com/591099 http/tests/devtools/sources/debugger-pause/debugger-eval-on-call-frame-inside-iframe.js [ Crash Pass ] crbug.com/591099 http/tests/devtools/sources/debugger-pause/debugger-eval-while-paused.js [ Crash Pass ] crbug.com/591099 http/tests/devtools/sources/debugger-pause/debugger-pause-in-internal.js [ Failure Pass ] crbug.com/591099 http/tests/devtools/sources/debugger-pause/debugger-pause-on-promise-rejection.js [ Crash ] crbug.com/591099 http/tests/devtools/sources/debugger-step/debugger-step-into-custom-element-callbacks.js [ Crash Pass ] crbug.com/591099 http/tests/devtools/sources/debugger-step/debugger-step-out-custom-element-callbacks.js [ Crash Pass ] -crbug.com/591099 http/tests/devtools/sources/debugger-step/debugger-step-out-event-listener.js [ Crash ] +crbug.com/591099 http/tests/devtools/sources/debugger-step/debugger-step-out-event-listener.js [ Crash Pass ] crbug.com/591099 http/tests/devtools/sources/debugger-ui/debugger-inline-values.js [ Crash ] crbug.com/591099 http/tests/devtools/sources/debugger-ui/function-generator-details.js [ Failure Pass ] crbug.com/591099 http/tests/devtools/sources/debugger-ui/watch-expressions-panel-switch.js [ Crash Pass ] @@ -5706,14 +5709,9 @@ crbug.com/591099 http/tests/devtools/sources/debugger/live-edit-no-reveal.js [ Failure ] crbug.com/591099 http/tests/devtools/sources/debugger/properties-special.js [ Failure Pass ] crbug.com/591099 http/tests/devtools/text-autosizing-override.js [ Failure ] -crbug.com/714962 http/tests/devtools/tracing/scroll-invalidations.js [ Failure Pass ] crbug.com/591099 http/tests/devtools/tracing/timeline-misc/timeline-bound-function.js [ Failure ] -crbug.com/714962 http/tests/devtools/tracing/timeline-misc/timeline-grouped-invalidations.js [ Failure Pass ] -crbug.com/591099 http/tests/devtools/tracing/timeline-paint/paint-profiler-update.js [ Pass Timeout ] -crbug.com/714962 http/tests/devtools/tracing/timeline-paint/timeline-paint-and-multiple-style-invalidations.js [ Failure Pass ] crbug.com/591099 http/tests/devtools/tracing/timeline-paint/timeline-paint-with-layout-invalidations-on-deleted-node.js [ Failure Timeout ] crbug.com/591099 http/tests/devtools/tracing/timeline-paint/timeline-paint-with-layout-invalidations.js [ Failure Timeout ] -crbug.com/591099 http/tests/devtools/tracing/timeline-paint/timeline-paint-with-style-recalc-invalidations.js [ Pass Timeout ] crbug.com/591099 http/tests/feature-policy-experimental-features/vibrate-allowed-by-container-policy-relocate-and-no-reload.html [ Timeout ] crbug.com/591099 http/tests/feature-policy-experimental-features/vibrate-allowed-by-container-policy-relocate-and-reload.html [ Timeout ] crbug.com/591099 http/tests/feature-policy-experimental-features/vibrate-allowed-by-container-policy.html [ Timeout ] @@ -5782,8 +5780,10 @@ crbug.com/714962 http/tests/navigation/javascriptlink-subframeload.html [ Timeout ] crbug.com/591099 http/tests/navigation/metaredirect-basic.html [ Failure ] crbug.com/591099 http/tests/navigation/metaredirect-goback.html [ Failure ] -crbug.com/591099 http/tests/navigation/no-referrer-reset.html [ Failure ] +crbug.com/591099 http/tests/navigation/no-referrer-reset.html [ Failure Timeout ] +crbug.com/591099 http/tests/navigation/no-referrer-same-window.html [ Timeout ] crbug.com/714962 http/tests/navigation/no-referrer-subframe.html [ Timeout ] +crbug.com/591099 http/tests/navigation/no-referrer-target-blank.html [ Timeout ] crbug.com/591099 http/tests/navigation/onload-navigation-iframe-2.html [ Failure ] crbug.com/714962 http/tests/navigation/ping-cookie.html [ Timeout ] crbug.com/714962 http/tests/navigation/ping-cross-origin-from-https.html [ Timeout ] @@ -6005,7 +6005,7 @@ crbug.com/591099 inspector-protocol/accessibility/accessibility-nameSources-labelledby.js [ Timeout ] crbug.com/591099 inspector-protocol/accessibility/accessibility-nameSources-summary.js [ Crash ] crbug.com/591099 inspector-protocol/accessibility/accessibility-nameSources-visiblity.js [ Timeout ] -crbug.com/591099 inspector-protocol/css/css-add-rule.js [ Timeout ] +crbug.com/591099 inspector-protocol/css/css-add-rule.js [ Pass Timeout ] crbug.com/714962 inspector-protocol/css/css-get-platform-fonts.js [ Failure ] crbug.com/591099 inspector-protocol/css/css-set-style-text.js [ Pass Timeout ] crbug.com/714962 inspector-protocol/dom-snapshot/dom-snapshot-getSnapshot-viewport.js [ Failure ] @@ -6511,7 +6511,6 @@ crbug.com/714962 paint/invalidation/svg/feImage-target-style-change.svg [ Failure ] crbug.com/714962 paint/invalidation/svg/filter-child-repaint.svg [ Failure ] crbug.com/714962 paint/invalidation/svg/filter-refresh.svg [ Failure ] -crbug.com/591099 paint/invalidation/svg/foreign-object-repaint.svg [ Failure Pass ] crbug.com/714962 paint/invalidation/svg/hairline-stroke-squarecap.svg [ Failure ] crbug.com/714962 paint/invalidation/svg/hit-test-with-br.xhtml [ Failure ] crbug.com/714962 paint/invalidation/svg/image-with-clip-path.svg [ Failure ] @@ -6604,7 +6603,6 @@ crbug.com/591099 paint/invalidation/svg/use-setAttribute-crash.svg [ Failure ] crbug.com/714962 paint/invalidation/svg/window.svg [ Failure ] crbug.com/714962 paint/invalidation/svg/zoom-coords-viewattr-01-b.svg [ Failure ] -crbug.com/714962 paint/invalidation/svg/zoom-foreignObject.svg [ Failure Pass ] crbug.com/591099 paint/invalidation/table/add-table-overpaint.html [ Failure ] crbug.com/591099 paint/invalidation/table/block-selection-gap-in-table-cell.html [ Failure ] crbug.com/591099 paint/invalidation/table/border-collapse-change-collapse-to-separate.html [ Failure ] @@ -6823,7 +6821,7 @@ crbug.com/591099 printing/thead-repeats-at-top-of-each-page.html [ Failure ] crbug.com/591099 printing/thead-under-multicol.html [ Failure ] crbug.com/591099 scrollbars/auto-scrollbar-fit-content.html [ Failure ] -crbug.com/714962 scrollbars/border-box-rect-clips-scrollbars.html [ Failure ] +crbug.com/714962 scrollbars/border-box-rect-clips-scrollbars.html [ Failure Pass ] crbug.com/591099 scrollbars/custom-scrollbar-enable-changes-thickness-with-iframe.html [ Failure ] crbug.com/591099 scrollbars/custom-scrollbar-with-incomplete-style.html [ Failure ] crbug.com/714962 scrollbars/custom-scrollbars-paint-outside-iframe.html [ Failure ] @@ -6940,7 +6938,7 @@ crbug.com/591099 svg/as-image/svg-as-relative-image-with-explicit-size.html [ Failure ] crbug.com/591099 svg/as-image/svg-as-relative-image.html [ Failure ] crbug.com/591099 svg/as-image/svg-image-leak-loader.html [ Failure ] -crbug.com/714962 svg/as-image/svg-image-with-css-animation.html [ Failure ] +crbug.com/714962 svg/as-image/svg-image-with-css-animation.html [ Failure Pass ] crbug.com/714962 svg/as-image/svg-intrinsic-size-rectangular-vertical.html [ Failure ] crbug.com/714962 svg/as-image/svg-intrinsic-size-rectangular.html [ Failure ] crbug.com/591099 svg/as-image/svg-non-integer-scaled-image.html [ Failure ] @@ -7033,8 +7031,8 @@ crbug.com/591099 svg/custom/foreign-object-skew.svg [ Failure ] crbug.com/591099 svg/custom/getscreenctm-in-mixed-content.xhtml [ Failure ] crbug.com/591099 svg/custom/getscreenctm-in-mixed-content2.xhtml [ Failure ] -crbug.com/591099 svg/custom/getscreenctm-in-scrollable-div-area-nested.xhtml [ Failure ] -crbug.com/591099 svg/custom/getscreenctm-in-scrollable-div-area.xhtml [ Failure ] +crbug.com/591099 svg/custom/getscreenctm-in-scrollable-div-area-nested.xhtml [ Failure Pass ] +crbug.com/591099 svg/custom/getscreenctm-in-scrollable-div-area.xhtml [ Failure Pass ] crbug.com/591099 svg/custom/getsvgdocument.html [ Failure ] crbug.com/714962 svg/custom/group-opacity.svg [ Failure ] crbug.com/591099 svg/custom/hit-test-path-stroke.svg [ Failure ] @@ -7068,7 +7066,6 @@ crbug.com/591099 svg/custom/svg-fonts-in-html.html [ Failure ] crbug.com/591099 svg/custom/svg-fonts-word-spacing.html [ Failure ] crbug.com/591099 svg/custom/tabindex-order.html [ Failure ] -crbug.com/714962 svg/custom/text-clip.svg [ Failure Pass ] crbug.com/591099 svg/custom/text-match-highlight.html [ Failure ] crbug.com/714962 svg/custom/transformed-outlines.svg [ Failure ] crbug.com/591099 svg/custom/transformed-text-pattern.html [ Failure ] @@ -7113,7 +7110,6 @@ crbug.com/591099 svg/foreignObject/mask.html [ Failure ] crbug.com/591099 svg/foreignObject/multiple-foreign-objects.html [ Failure ] crbug.com/591099 svg/foreignObject/svg-document-in-html-document.svg [ Failure ] -crbug.com/714962 svg/foreignObject/vertical-foreignObject.html [ Failure Pass ] crbug.com/591099 svg/hittest/clip-path-shape.html [ Failure ] crbug.com/591099 svg/hittest/ellipse-hittest.html [ Failure ] crbug.com/591099 svg/hittest/empty-container.html [ Failure ] @@ -7130,7 +7126,6 @@ crbug.com/591099 svg/hixie/error/012.xml [ Failure ] crbug.com/591099 svg/hixie/error/013.xml [ Failure ] crbug.com/591099 svg/hixie/mixed/006.xml [ Failure ] -crbug.com/591099 svg/hixie/mixed/009.xml [ Failure Pass ] crbug.com/591099 svg/hixie/mixed/011.xml [ Failure ] crbug.com/714962 svg/hixie/perf/007.xml [ Failure ] crbug.com/714962 svg/hixie/viewbox/preserveAspectRatio/001.xml [ Failure ] @@ -7192,7 +7187,6 @@ crbug.com/591099 svg/zoom/page/zoom-svg-through-object-with-absolute-size.xhtml [ Failure ] crbug.com/591099 svg/zoom/page/zoom-svg-through-object-with-override-size.html [ Failure ] crbug.com/591099 svg/zoom/page/zoom-svg-through-object-with-percentage-size.xhtml [ Failure ] -crbug.com/591099 svg/zoom/text/zoom-hixie-mixed-008.xml [ Failure Pass ] crbug.com/591099 svg/zoom/text/zoom-hixie-mixed-009.xml [ Failure ] crbug.com/591099 svg/zoom/text/zoom-svg-float-border-padding.xml [ Failure ] crbug.com/591099 tables/layering/paint-test-layering-1.html [ Failure ] @@ -7544,7 +7538,6 @@ crbug.com/714962 virtual/gpu/fast/canvas/canvas-css-clip-path.html [ Failure ] crbug.com/591099 virtual/gpu/fast/canvas/canvas-drawImage-animated-images.html [ Failure ] crbug.com/591099 virtual/gpu/fast/canvas/canvas-drawImage-video-imageSmoothingEnabled.html [ Pass ] -crbug.com/591099 virtual/gpu/fast/canvas/canvas-fillPath-shadow.html [ Pass Timeout ] crbug.com/591099 virtual/gpu/fast/canvas/canvas-imageSmoothingQuality.html [ Pass ] crbug.com/591099 virtual/gpu/fast/canvas/canvas-measure-bidi-text.html [ Failure ] crbug.com/714962 virtual/gpu/fast/canvas/canvas-textMetrics-width.html [ Failure ] @@ -7688,6 +7681,7 @@ crbug.com/591099 virtual/mouseevent_fractional/fast/events/mousemove-to-resizer-changes-cursor.html [ Failure ] crbug.com/591099 virtual/mouseevent_fractional/fast/events/mouseover-mouseout.html [ Failure ] crbug.com/591099 virtual/mouseevent_fractional/fast/events/no-blur-on-enter-button.html [ Failure ] +crbug.com/591099 virtual/mouseevent_fractional/fast/events/node-event-anchor-lock.html [ Failure ] crbug.com/714962 virtual/mouseevent_fractional/fast/events/offsetX-offsetY.html [ Failure ] crbug.com/591099 virtual/mouseevent_fractional/fast/events/onblur-remove.html [ Failure ] crbug.com/714962 virtual/mouseevent_fractional/fast/events/onchange-click-hang.html [ Failure ] @@ -7695,6 +7689,7 @@ crbug.com/591099 virtual/mouseevent_fractional/fast/events/onclick-list-marker.html [ Failure ] crbug.com/591099 virtual/mouseevent_fractional/fast/events/onload-re-entry.html [ Failure ] crbug.com/591099 virtual/mouseevent_fractional/fast/events/onload-webkit-before-webcore.html [ Failure ] +crbug.com/591099 virtual/mouseevent_fractional/fast/events/open-window-from-another-frame.html [ Timeout ] crbug.com/591099 virtual/mouseevent_fractional/fast/events/pointer-events-2.html [ Failure ] crbug.com/714962 virtual/mouseevent_fractional/fast/events/pointerevents/mouse-node-remove.html [ Failure ] crbug.com/714962 virtual/mouseevent_fractional/fast/events/pointerevents/mouse-pointer-boundary-events-for-shadowdom.html [ Failure ] @@ -7762,17 +7757,14 @@ crbug.com/591099 virtual/scalefactor150/fast/hidpi/static/calendar-picker-appearance.html [ Failure ] crbug.com/591099 virtual/scalefactor150/fast/hidpi/static/data-suggestion-picker-appearance.html [ Failure ] crbug.com/591099 virtual/scalefactor150/fast/hidpi/static/popup-menu-with-scrollbar-appearance.html [ Failure ] -crbug.com/591099 virtual/scalefactor150/fast/hidpi/static/validation-bubble-appearance-hidpi.html [ Failure Pass ] crbug.com/714962 virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance.html [ Failure ] crbug.com/714962 virtual/scalefactor200/fast/hidpi/static/data-suggestion-picker-appearance.html [ Failure ] crbug.com/714962 virtual/scalefactor200/fast/hidpi/static/popup-menu-appearance.html [ Failure ] crbug.com/591099 virtual/scalefactor200/fast/hidpi/static/popup-menu-with-scrollbar-appearance.html [ Failure ] -crbug.com/591099 virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi.html [ Failure Pass ] crbug.com/714962 virtual/scalefactor200withzoom/fast/hidpi/static/calendar-picker-appearance.html [ Failure ] crbug.com/714962 virtual/scalefactor200withzoom/fast/hidpi/static/data-suggestion-picker-appearance.html [ Failure ] crbug.com/714962 virtual/scalefactor200withzoom/fast/hidpi/static/popup-menu-appearance.html [ Failure ] crbug.com/591099 virtual/scalefactor200withzoom/fast/hidpi/static/popup-menu-with-scrollbar-appearance.html [ Failure ] -crbug.com/591099 virtual/scalefactor200withzoom/fast/hidpi/static/validation-bubble-appearance-hidpi.html [ Failure Pass ] crbug.com/591099 virtual/scroll_customization/ [ Skip ] crbug.com/591099 virtual/scroll_customization/fast/events/touch/compositor-touch-hit-rects-animation.html [ Pass ] crbug.com/591099 virtual/scroll_customization/fast/events/touch/compositor-touch-hit-rects-global.html [ Pass ]
diff --git a/third_party/WebKit/LayoutTests/LeakExpectations b/third_party/WebKit/LayoutTests/LeakExpectations index 9e9ef4b..0bbc033 100644 --- a/third_party/WebKit/LayoutTests/LeakExpectations +++ b/third_party/WebKit/LayoutTests/LeakExpectations
@@ -11,6 +11,7 @@ # FIXME: scroll customization leaks memory. See # codereview.chromium.org/1236913004/ for context. +crbug.com/410974 virtual/scroll_customization/fast/scroll-behavior/scroll-customization/scroll-customization-property.html [ Leak ] crbug.com/410974 virtual/scroll_customization/fast/scroll-behavior/scroll-customization/touch-scroll-customization.html [ Leak ] crbug.com/410974 virtual/scroll_customization/fast/scroll-behavior/scroll-customization/scrollstate-distribute-to-scroll-chain-descendant.html [ Leak ]
diff --git a/third_party/WebKit/LayoutTests/SlowTests b/third_party/WebKit/LayoutTests/SlowTests index ee29e4d..e5791c39 100644 --- a/third_party/WebKit/LayoutTests/SlowTests +++ b/third_party/WebKit/LayoutTests/SlowTests
@@ -467,3 +467,6 @@ crbug.com/779366 fast/shapes/crash-allocating-very-large-raster-shape.html [ Slow ] crbug.com/787971 external/wpt/WebCryptoAPI/wrapKey_unwrapKey/wrapKey_unwrapKey.https.worker.html [ Slow ] + +# This test has many test cases and each case requires a gesture scroll with pauses in between. +crbug.com/765326 virtual/scroll_customization/fast/scroll-behavior/scroll-customization/scroll-customization-property.html [ Slow ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 1ba11692..9cf1dafe 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -527,6 +527,7 @@ crbug.com/714962 virtual/layout_ng/fast/inline/drawStyledEmptyInlines.html [ Failure ] crbug.com/714962 virtual/layout_ng/fast/inline/inline-borders-with-bidi-override.html [ Failure ] crbug.com/714962 virtual/layout_ng/fast/inline/inline-focus-ring-under-absolute-enclosing-relative-div.html [ Failure ] +crbug.com/714962 virtual/layout_ng/fast/inline/layout-after-inserting-nested-br.html [ Failure ] crbug.com/714962 virtual/layout_ng/fast/inline/left-right-center-inline-alignment-in-ltr-and-rtl-blocks.html [ Failure ] crbug.com/714962 virtual/layout_ng/fast/inline/out-of-flow-objects-and-whitespace-after-empty-inline.html [ Failure ] crbug.com/714962 virtual/layout_ng/fast/inline/outline-continuations.html [ Failure ] @@ -710,8 +711,6 @@ crbug.com/788110 [ Linux Win10 ] inspector-protocol/layout-fonts/unicode-range-combining-chars-fallback.js [ Pass Failure ] -crbug.com/803276 [ Mac Win ] inspector-protocol/memory/sampling-native-profile.js [ Skip ] - # Run these tests with under virtual/scalefactor... only. crbug.com/567837 fast/hidpi/static [ Skip ] @@ -1401,6 +1400,7 @@ crbug.com/613672 [ Mac ] virtual/mouseevent_fractional/fast/events/pointerevents/pointer-event-consumed-touchstart-in-slop-region.html [ Skip ] crbug.com/613672 [ Mac ] virtual/mouseevent_fractional/fast/events/pointerevents/pointer-event-in-slop-region.html [ Skip ] crbug.com/613672 [ Mac ] virtual/mouseevent_fractional/fast/events/synthetic-events/tap-on-scaled-screen.html [ Skip ] +crbug.com/613672 [ Mac ] virtual/scroll_customization/fast/scroll-behavior/scroll-customization/scroll-customization-property.html [ Skip ] # We should send PointerLeave events for stylus devices. crbug.com/583413 external/wpt/pointerevents/pointerevent_pointerleave_pen-manual.html [ Failure ] @@ -3418,6 +3418,9 @@ # Does not work on Mac crbug.com/793771 [ Mac ] virtual/modern-media-controls/media/controls/modern/scrubbing.html [ Skip ] +# Flaky on Windows +crbug.com/801341 [ Win ] http/tests/misc/webtiming-resolution.html [ Failure Pass ] + crbug.com/797138 external/wpt/credential-management/federatedcredential-framed-get.sub.https.html [ Crash ] crbug.com/797138 external/wpt/credential-management/passwordcredential-framed-get.sub.https.html [ Crash ]
diff --git a/third_party/WebKit/LayoutTests/compositing/overflow/scrollbars-with-clipped-owner.html b/third_party/WebKit/LayoutTests/compositing/overflow/scrollbars-with-clipped-owner.html index af256e3d..cc81804 100644 --- a/third_party/WebKit/LayoutTests/compositing/overflow/scrollbars-with-clipped-owner.html +++ b/third_party/WebKit/LayoutTests/compositing/overflow/scrollbars-with-clipped-owner.html
@@ -1,6 +1,13 @@ <!DOCTYPE HTML> <html> <head> + <script> + // Disable implicit root scroller since the outer div is full screen + // and would otherwise be promoted to rootScroller. Doing so causes it + // to be composited and produces off-by-one differences due to how + // scrollbar positions are calculated in the compositor. + window.internals.runtimeFlags.implicitRootScrollerEnabled = false; + </script> <style> body { margin: 0px;
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json index 646fe916..7c5e182 100644 --- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json +++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -79925,6 +79925,18 @@ {} ] ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-paint-ordering-003.html": [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-paint-ordering-003.html", + [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-paint-ordering-003-ref.html", + "==" + ] + ], + {} + ] + ], "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-root-node-001a.html": [ [ "/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-root-node-001a.html", @@ -124564,6 +124576,11 @@ {} ] ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-paint-ordering-003-ref.html": [ + [ + {} + ] + ], "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-root-node-001-ref.html": [ [ {} @@ -151694,6 +151711,11 @@ {} ] ], + "webauthn/createcredential-badargs-rp.https-expected.txt": [ + [ + {} + ] + ], "webauthn/createcredential-passing.https-expected.txt": [ [ {} @@ -299472,6 +299494,14 @@ "6092f9269a40b5d763b3e71cb235d917c418ed38", "reftest" ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-paint-ordering-003-ref.html": [ + "8ce06ed245c0bb9d391c751ad73a8bdc9c6934ab", + "support" + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-paint-ordering-003.html": [ + "3f3c416f2f966ea2208f89a0e90b26385ee35694", + "reftest" + ], "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-root-node-001-ref.html": [ "b06b801d20ebf9776648cb522ec427a1676e7490", "support" @@ -353132,6 +353162,10 @@ "832fb99e215923e9d102f48f2a0cd06ea11ff86b", "support" ], + "webauthn/createcredential-badargs-rp.https-expected.txt": [ + "6b8193f882d66d96ace82fbd997eb624d90b19e7", + "support" + ], "webauthn/createcredential-badargs-rp.https.html": [ "941a9bda02e22b7d54855e3a4714a49d8392fa9d", "testharness"
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-paint-ordering-003-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-paint-ordering-003-ref.html new file mode 100644 index 0000000..5eadc30 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-paint-ordering-003-ref.html
@@ -0,0 +1,20 @@ +<!DOCTYPE html> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html> +<head> + <title>CSS Reftest Reference</title> + <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com"> + <style> + .limeSquare { + background: lime; + height: 100px; width: 100px; + } + </style> +</head> +<body> + <div class="limeSquare"></div> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-paint-ordering-003.html b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-paint-ordering-003.html new file mode 100644 index 0000000..1a5175c --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-paint-ordering-003.html
@@ -0,0 +1,52 @@ +<!DOCTYPE html> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html> +<head> + <title>CSS Test: Testing that paint order isn't influenced + by "order" for absolutely positioned flex children</title> + <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com"> + <link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#abspos-items"> + <link rel="help" href="http://www.w3.org/TR/css-flexbox-1/#painting"> + <link rel="match" href="flexbox-paint-ordering-003-ref.html"> + <style> + .container { display: flex; } + .absPosLowOrder { + position: absolute; + order: 5; + background: red; + height: 0; + width: 0; + } + .absPosHighOrder { + position: absolute; + order: 10; + height: 0; + width: 0; + } + .redBlock { + height: 100px; + width: 100px; + background: red; + } + .limeBlock { + height: 100px; + width: 100px; + background: lime; + } + </style> +</head> +<body> + <div class="container"> + <!-- Note: The following elements will be superimposed. If they weren't + positioned, then they'd be flex items, and their relative "order" + values would force the first one (with the red child) to paint on top. + But since they're absolutely positioned, they're not flex items & + "order" has no effect, and so the lime one should end up on top. --> + <div class="absPosHighOrder"><div class="redBlock"></div></div> + <div class="absPosLowOrder"><div class="limeBlock"></div></div> + </div> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/device-memory/OWNERS b/third_party/WebKit/LayoutTests/external/wpt/device-memory/OWNERS new file mode 100644 index 0000000..d7c51dc --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/device-memory/OWNERS
@@ -0,0 +1,4 @@ +# TEAM: progressive-web-metrics@chromium.org +# COMPONENT: Blink>PerformanceAPIs +fmeawad@chromium.org +panicker@chromium.org \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/navigator/device-memory.https.any.js b/third_party/WebKit/LayoutTests/external/wpt/device-memory/device-memory.https.any.js similarity index 100% rename from third_party/WebKit/LayoutTests/external/wpt/navigator/device-memory.https.any.js rename to third_party/WebKit/LayoutTests/external/wpt/device-memory/device-memory.https.any.js
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/dom/interfaces-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/html/dom/interfaces-expected.txt index 75e8ed7..a217f85f5 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/html/dom/interfaces-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/html/dom/interfaces-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 5263 tests; 5151 PASS, 112 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 5263 tests; 5152 PASS, 111 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS Test driver PASS Document interface: attribute domain PASS Document interface: attribute referrer @@ -4966,7 +4966,7 @@ PASS MessageEvent interface: attribute lastEventId PASS MessageEvent interface: attribute source PASS MessageEvent interface: attribute ports -FAIL MessageEvent interface: operation initMessageEvent(DOMString, boolean, boolean, any, USVString, DOMString, MessageEventSource, [object Object]) assert_equals: property has wrong .length expected 1 but got 0 +PASS MessageEvent interface: operation initMessageEvent(DOMString, boolean, boolean, any, USVString, DOMString, MessageEventSource, [object Object]) PASS MessageEvent must be primary interface of new MessageEvent("message", { data: 5 }) PASS Stringification of new MessageEvent("message", { data: 5 }) PASS MessageEvent interface: new MessageEvent("message", { data: 5 }) must inherit property "data" with the proper type
diff --git a/third_party/WebKit/LayoutTests/platform/mac/external/wpt/webauthn/createcredential-badargs-rp.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/webauthn/createcredential-badargs-rp.https-expected.txt similarity index 100% rename from third_party/WebKit/LayoutTests/platform/mac/external/wpt/webauthn/createcredential-badargs-rp.https-expected.txt rename to third_party/WebKit/LayoutTests/external/wpt/webauthn/createcredential-badargs-rp.https-expected.txt
diff --git a/third_party/WebKit/LayoutTests/fast/events/drag-on-removed-slider-does-not-crash.html b/third_party/WebKit/LayoutTests/fast/events/drag-on-removed-slider-does-not-crash.html new file mode 100644 index 0000000..094d4aa --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/events/drag-on-removed-slider-does-not-crash.html
@@ -0,0 +1,34 @@ +<!DOCTYPE html> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> + +<input max=100 type="range" id="slider"> + +<script> +document.getElementById("slider").addEventListener("input", function() { + this.removeAttribute("type"); +}); +var centerY = slider.offsetTop + slider.offsetHeight / 2; +var centerX = slider.offsetLeft + slider.offsetWidth / 2; +var rightEdgeX = slider.offsetLeft + slider.offsetWidth - 1; +const touchIdentifier = 1; + +function smoothDrag() { + return new Promise((resolve, reject) => { + chrome.gpuBenchmarking.smoothDrag(centerX, centerY, rightEdgeX, centerY, + resolve, touchIdentifier); + }) +} + +const IS_MAC = navigator.platform.indexOf('Mac') == 0; +promise_test(t => { + if (!IS_MAC) { + return smoothDrag(); + } else { + return new Promise((resolve, reject) => { + resolve(); + }); + } +}, 'Drag on removed slider should not crash.'); + +</script> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/fast/forms/file/file-input-click-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/file/file-input-click-expected.txt new file mode 100644 index 0000000..bdee900 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/forms/file/file-input-click-expected.txt
@@ -0,0 +1,4 @@ +Mock: Opening a file chooser. +Ensure clicking on an INPUT element with TYPE=FILE launches a file chooser. Automated test passes if 'Opening a file chooser' was logged. + +
diff --git a/third_party/WebKit/LayoutTests/fast/forms/file/file-input-click.html b/third_party/WebKit/LayoutTests/fast/forms/file/file-input-click.html new file mode 100644 index 0000000..0f2a035 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/forms/file/file-input-click.html
@@ -0,0 +1,21 @@ +<!DOCTYPE html> +<title>INPUT TYPE=FILE and click events</title> +<p> + Ensure clicking on an INPUT element with TYPE=FILE launches a file + chooser. Automated test passes if 'Opening a file chooser' was + logged. +</p> +<input type="file"> +<script> +if (testRunner && eventSender) { + testRunner.dumpAsText(); + const file = document.querySelector('input'); + const x = file.offsetLeft + file.offsetWidth / 2; + const y = file.offsetTop + file.offsetHeight / 2; + + eventSender.mouseMoveTo(x, y); + eventSender.mouseDown(); + eventSender.mouseMoveTo(x, y); + eventSender.mouseUp(); +} +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/forms/file/file-input-key-enter-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/file/file-input-key-enter-expected.txt new file mode 100644 index 0000000..b90e224 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/forms/file/file-input-key-enter-expected.txt
@@ -0,0 +1,4 @@ +Mock: Opening a file chooser. +Ensure pressing Enter key with focus on an INPUT element with TYPE=FILE launches a file chooser. Automated test passes if 'Opening a file chooser' was logged. + +
diff --git a/third_party/WebKit/LayoutTests/fast/forms/file/file-input-key-enter.html b/third_party/WebKit/LayoutTests/fast/forms/file/file-input-key-enter.html new file mode 100644 index 0000000..b670103 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/forms/file/file-input-key-enter.html
@@ -0,0 +1,17 @@ +<!DOCTYPE html> +<title>INPUT TYPE=FILE and key events - Enter key</title> +<p> + Ensure pressing Enter key with focus on an INPUT element with + TYPE=FILE launches a file chooser. Automated test passes if 'Opening + a file chooser' was logged. +</p> +<input type="file"> +<script> +if (testRunner && eventSender) { + testRunner.dumpAsText(); + const file = document.querySelector('input'); + file.focus(); + // Despite the name, 'keyDown' simulates a full down/press/up sequence. + eventSender.keyDown('Enter', []); +} +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/forms/file/file-input-key-other-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/file/file-input-key-other-expected.txt new file mode 100644 index 0000000..1ae0677 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/forms/file/file-input-key-other-expected.txt
@@ -0,0 +1,3 @@ +Ensure pressing non-enter/space keys with focus on an INPUT element with TYPE=FILE does not launch a file chooser. Automated test fails if 'Opening a file chooser' was logged. + +
diff --git a/third_party/WebKit/LayoutTests/fast/forms/file/file-input-key-other.html b/third_party/WebKit/LayoutTests/fast/forms/file/file-input-key-other.html new file mode 100644 index 0000000..7b35573 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/forms/file/file-input-key-other.html
@@ -0,0 +1,19 @@ +<!DOCTYPE html> +<title>INPUT TYPE=FILE and key events - Other keys</title> +<p> + Ensure pressing non-enter/space keys with focus on an INPUT element + with TYPE=FILE does <b>not</b> launch a file chooser. Automated test + <b>fails</b> if 'Opening a file chooser' was logged. +</p> +<input type="file"> +<script> +if (testRunner && eventSender) { + testRunner.dumpAsText(); + const file = document.querySelector('input'); + file.focus(); + ['x', '0', 'ArrowRight', 'ControlLeft'].forEach(key => { + // Despite the name, 'keyDown' simulates a full down/press/up sequence. + eventSender.keyDown(key, []); + }); +} +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/forms/file/file-input-key-space-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/file/file-input-key-space-expected.txt new file mode 100644 index 0000000..eee8e57 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/forms/file/file-input-key-space-expected.txt
@@ -0,0 +1,4 @@ +Mock: Opening a file chooser. +Ensure pressing Space key with focus on an INPUT element with TYPE=FILE launches a file chooser. Automated test passes if 'Opening a file chooser' was logged. + +
diff --git a/third_party/WebKit/LayoutTests/fast/forms/file/file-input-key-space.html b/third_party/WebKit/LayoutTests/fast/forms/file/file-input-key-space.html new file mode 100644 index 0000000..3eff66d --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/forms/file/file-input-key-space.html
@@ -0,0 +1,17 @@ +<!DOCTYPE html> +<title>INPUT TYPE=FILE and key events - Space key</title> +<p> + Ensure pressing Space key with focus on an INPUT element with + TYPE=FILE launches a file chooser. Automated test passes if 'Opening + a file chooser' was logged. +</p> +<input type="file"> +<script> +if (testRunner && eventSender) { + testRunner.dumpAsText(); + const file = document.querySelector('input'); + file.focus(); + // Despite the name, 'keyDown' simulates a full down/press/up sequence. + eventSender.keyDown(' ', []); +} +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/forms/file/file-input-webkitdirectory-click-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/file/file-input-webkitdirectory-click-expected.txt new file mode 100644 index 0000000..4c350037 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/forms/file/file-input-webkitdirectory-click-expected.txt
@@ -0,0 +1,4 @@ +Mock: Opening a file chooser. +Ensure clicking on an INPUT element with TYPE=FILE and WEBKITDIRECTORY launches a file chooser. Automated test passes if 'Opening a file chooser' was logged. + +
diff --git a/third_party/WebKit/LayoutTests/fast/forms/file/file-input-webkitdirectory-click.html b/third_party/WebKit/LayoutTests/fast/forms/file/file-input-webkitdirectory-click.html new file mode 100644 index 0000000..ade732ad --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/forms/file/file-input-webkitdirectory-click.html
@@ -0,0 +1,21 @@ +<!DOCTYPE html> +<title>INPUT TYPE=FILE WEBKITDIRECTORY and click events</title> +<p> + Ensure clicking on an INPUT element with TYPE=FILE and + WEBKITDIRECTORY launches a file chooser. Automated test passes if + 'Opening a file chooser' was logged. +</p> +<input type="file" webkitdirectory> +<script> +if (testRunner && eventSender) { + testRunner.dumpAsText(); + const file = document.querySelector('input'); + const x = file.offsetLeft + file.offsetWidth / 2; + const y = file.offsetTop + file.offsetHeight / 2; + + eventSender.mouseMoveTo(x, y); + eventSender.mouseDown(); + eventSender.mouseMoveTo(x, y); + eventSender.mouseUp(); +} +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/forms/file/file-input-webkitdirectory-key-enter-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/file/file-input-webkitdirectory-key-enter-expected.txt new file mode 100644 index 0000000..fe6cfc35 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/forms/file/file-input-webkitdirectory-key-enter-expected.txt
@@ -0,0 +1,4 @@ +Mock: Opening a file chooser. +Ensure pressing Enter key with focus on an INPUT element with TYPE=FILE and WEBKITDIRECTORY launches a file chooser. Automated test passes if 'Opening a file chooser' was logged. + +
diff --git a/third_party/WebKit/LayoutTests/fast/forms/file/file-input-webkitdirectory-key-enter.html b/third_party/WebKit/LayoutTests/fast/forms/file/file-input-webkitdirectory-key-enter.html new file mode 100644 index 0000000..ed28f60a --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/forms/file/file-input-webkitdirectory-key-enter.html
@@ -0,0 +1,17 @@ +<!DOCTYPE html> +<title>INPUT TYPE=FILE WEBKITDIRECTORY and key events - Enter key</title> +<p> + Ensure pressing Enter key with focus on an INPUT element with + TYPE=FILE and WEBKITDIRECTORY launches a file chooser. Automated + test passes if 'Opening a file chooser' was logged. +</p> +<input type="file" webkitdirectory> +<script> +if (testRunner && eventSender) { + testRunner.dumpAsText(); + const file = document.querySelector('input'); + file.focus(); + // Despite the name, 'keyDown' simulates a full down/press/up sequence. + eventSender.keyDown('Enter', []); +} +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/forms/file/file-input-webkitdirectory-key-other-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/file/file-input-webkitdirectory-key-other-expected.txt new file mode 100644 index 0000000..3b2aa3f --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/forms/file/file-input-webkitdirectory-key-other-expected.txt
@@ -0,0 +1,3 @@ +Ensure pressing non-enter/space keys with focus on an INPUT element with TYPE=FILE and WEBKITDIRECTORY does not launch a file chooser. Automated test fails if 'Opening a file chooser' was logged. + +
diff --git a/third_party/WebKit/LayoutTests/fast/forms/file/file-input-webkitdirectory-key-other.html b/third_party/WebKit/LayoutTests/fast/forms/file/file-input-webkitdirectory-key-other.html new file mode 100644 index 0000000..9281426c --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/forms/file/file-input-webkitdirectory-key-other.html
@@ -0,0 +1,20 @@ +<!DOCTYPE html> +<title>INPUT TYPE=FILE WEBKITDIRECTORY and key events - Other keys</title> +<p> + Ensure pressing non-enter/space keys with focus on an INPUT element + with TYPE=FILE and WEBKITDIRECTORY does <b>not</b> launch a file + chooser. Automated test <b>fails</b> if 'Opening a file chooser' was + logged. +</p> +<input type="file" webkitdirectory> +<script> +if (testRunner && eventSender) { + testRunner.dumpAsText(); + const file = document.querySelector('input'); + file.focus(); + ['x', '0', 'ArrowRight', 'ControlLeft'].forEach(key => { + // Despite the name, 'keyDown' simulates a full down/press/up sequence. + eventSender.keyDown(key, []); + }); +} +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/forms/file/file-input-webkitdirectory-key-space-expected.txt b/third_party/WebKit/LayoutTests/fast/forms/file/file-input-webkitdirectory-key-space-expected.txt new file mode 100644 index 0000000..2cb7d24 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/forms/file/file-input-webkitdirectory-key-space-expected.txt
@@ -0,0 +1,4 @@ +Mock: Opening a file chooser. +Ensure pressing Space key with focus on an INPUT element with TYPE=FILE and WEBKITDIRECTORY launches a file chooser. Automated test passes if 'Opening a file chooser' was logged. + +
diff --git a/third_party/WebKit/LayoutTests/fast/forms/file/file-input-webkitdirectory-key-space.html b/third_party/WebKit/LayoutTests/fast/forms/file/file-input-webkitdirectory-key-space.html new file mode 100644 index 0000000..7ba04ce --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/forms/file/file-input-webkitdirectory-key-space.html
@@ -0,0 +1,17 @@ +<!DOCTYPE html> +<title>INPUT TYPE=FILE WEBKITDIRECTORY and key events - Space key</title> +<p> + Ensure pressing Space key with focus on an INPUT element with + TYPE=FILE and WEBKITDIRECTORY launches a file chooser. Automated + test passes if 'Opening a file chooser' was logged. +</p> +<input type="file" webkitdirectory> +<script> +if (testRunner && eventSender) { + testRunner.dumpAsText(); + const file = document.querySelector('input'); + file.focus(); + // Despite the name, 'keyDown' simulates a full down/press/up sequence. + eventSender.keyDown(' ', []); +} +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/mediacapturefromelement/CanvasCaptureMediaStream-2d-events.html b/third_party/WebKit/LayoutTests/fast/mediacapturefromelement/CanvasCaptureMediaStream-2d-events.html index 8ed45f4..40931a2 100644 --- a/third_party/WebKit/LayoutTests/fast/mediacapturefromelement/CanvasCaptureMediaStream-2d-events.html +++ b/third_party/WebKit/LayoutTests/fast/mediacapturefromelement/CanvasCaptureMediaStream-2d-events.html
@@ -43,7 +43,7 @@ var video = document.createElement('video'); try { - video.src = window.URL.createObjectURL(stream); + video.srcObject = stream; testPassed('Plugged stream to video tag.'); } catch(e) { testFailed('Exception plugging stream to <video>: ' + e);
diff --git a/third_party/WebKit/LayoutTests/fast/mediacapturefromelement/CanvasCaptureMediaStream-request-frame-events.html b/third_party/WebKit/LayoutTests/fast/mediacapturefromelement/CanvasCaptureMediaStream-request-frame-events.html index e7af6132..6a35877 100644 --- a/third_party/WebKit/LayoutTests/fast/mediacapturefromelement/CanvasCaptureMediaStream-request-frame-events.html +++ b/third_party/WebKit/LayoutTests/fast/mediacapturefromelement/CanvasCaptureMediaStream-request-frame-events.html
@@ -47,7 +47,7 @@ // var video = document.createElement('video'); var video = document.getElementById('v'); try { - video.src = window.URL.createObjectURL(stream); + video.srcObject = stream; testPassed('Plugged stream to video tag.'); } catch(e) { testFailed('Exception plugging stream to <video>: ' + e);
diff --git a/third_party/WebKit/LayoutTests/fast/mediacapturefromelement/CanvasCaptureMediaStream-webgl-events.html b/third_party/WebKit/LayoutTests/fast/mediacapturefromelement/CanvasCaptureMediaStream-webgl-events.html index fd619c8..93cb03db 100644 --- a/third_party/WebKit/LayoutTests/fast/mediacapturefromelement/CanvasCaptureMediaStream-webgl-events.html +++ b/third_party/WebKit/LayoutTests/fast/mediacapturefromelement/CanvasCaptureMediaStream-webgl-events.html
@@ -40,7 +40,7 @@ var video = document.createElement('video'); try { - video.src = window.URL.createObjectURL(stream); + video.srcObject = stream; testPassed('Plugged stream to video tag.'); } catch(e) { testFailed('Exception plugging stream to <video>: ' + e);
diff --git a/third_party/WebKit/LayoutTests/fast/peerconnection/RTCPeerConnection-sdes-constraint.html b/third_party/WebKit/LayoutTests/fast/peerconnection/RTCPeerConnection-sdes-constraint.html new file mode 100644 index 0000000..c06dbda --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/peerconnection/RTCPeerConnection-sdes-constraint.html
@@ -0,0 +1,137 @@ +<!DOCTYPE html> +<html> +<head> +<title>RTCPeerConnection.createOffer</title> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +</head> +<body> +<script> + +sdes_constraint = {'mandatory': {'DtlsSrtpKeyAgreement': false}}; + +promise_test(async t => { + let pc1 = new RTCPeerConnection(); + let pc2 = new RTCPeerConnection(); + let stream = await navigator.mediaDevices.getUserMedia({audio: true}); + let track = stream.getAudioTracks()[0]; + pc1.addTrack(track); + let offer = await pc1.createOffer(); + assert_true(offer.sdp.match('\na=fingerprint') !== null); + assert_true(offer.sdp.match('\na=crypto') === null); + await pc1.setLocalDescription(offer); + await pc2.setRemoteDescription(offer); + let answer = await pc2.createAnswer(); + assert_true(answer.sdp.match('\na=fingerprint') !== null); + assert_true(answer.sdp.match('\na=crypto') === null); + await pc2.setLocalDescription(answer); + await pc1.setRemoteDescription(answer); +}, 'No constraints means DTLS-SRTP'); + +promise_test(async t => { + let pc1 = new RTCPeerConnection(null, sdes_constraint); + let pc2 = new RTCPeerConnection(null, sdes_constraint); + pc1.oncandidate = c => pc2.addCandidate(); + pc2.oncandidate = c => pc1.addCandidate(); + let stream = await navigator.mediaDevices.getUserMedia({audio: true}); + let track = stream.getAudioTracks()[0]; + pc1.addTrack(track); + let offer = await pc1.createOffer(); + // assert_regexp_match doesn't work + assert_true(offer.sdp.match('\na=fingerprint') === null); + assert_true(offer.sdp.match('\na=crypto') !== null); + await pc1.setLocalDescription(offer); + await pc2.setRemoteDescription(offer); + let answer = await pc2.createAnswer(); + assert_true(answer.sdp.match('\na=fingerprint') === null); + assert_true(answer.sdp.match('\na=crypto') !== null); + await pc2.setLocalDescription(answer); + await pc1.setRemoteDescription(answer); +}, 'DTLS constraint false means SDES'); + +promise_test(async t => { + let pc1 = new RTCPeerConnection(null, sdes_constraint); + let pc2 = new RTCPeerConnection(); + let stream = await navigator.mediaDevices.getUserMedia({audio: true}); + let track = stream.getAudioTracks()[0]; + pc1.addTrack(track); + let offer = await pc1.createOffer(); + await pc1.setLocalDescription(offer); + try { + await pc2.setRemoteDescription(offer); + assert_unreached('pc2.setRemote should have thrown'); + } catch(e) { + assert_equals(e.name, 'OperationError'); + } + +}, 'SDES can\'t connect to default configuration'); + +promise_test(async t => { + let pc1 = new RTCPeerConnection(); + let pc2 = new RTCPeerConnection(null, sdes_constraint); + let stream = await navigator.mediaDevices.getUserMedia({audio: true}); + let track = stream.getAudioTracks()[0]; + pc1.addTrack(track); + let offer = await pc1.createOffer(); + try { + await pc2.setRemoteDescription(offer); + assert_unreached('pc2.setRemote should have thrown'); + } catch(e) { + assert_equals(e.name, 'OperationError'); + } +}, 'Default configuration can\'t connect to SDES'); + +causes_sdes = async function(constraint) { + pc = new RTCPeerConnection(null, constraint); + let stream = await navigator.mediaDevices.getUserMedia({audio: true}); + let track = stream.getAudioTracks()[0]; + pc.addTrack(track); + let offer = await pc.createOffer(); + return offer.sdp.match('\na=crypto') !== null +} + +valid_constraint_for_pc = async function(constraint) { + console.log(JSON.stringify(constraint)); + try { + pc = new RTCPeerConnection(null, constraint); + return true; + } catch (e) { + assert_equals(e.name, 'OperationError'); + return false; + } +} + +promise_test(async t => { + assert_true(await causes_sdes(sdes_constraint)); + assert_false(await causes_sdes( + {'mandatory': {'DtlsSrtpKeyAgreement': true}})); + assert_true(await causes_sdes( + {'mandatory': {'DtlsSrtpKeyAgreement': 'false'}})); + assert_false(await causes_sdes( + {'optional': [{'DtlsSrtpKeyAgreement': true}]})); + assert_true(await causes_sdes( + {'optional': [{'DtlsSrtpKeyAgreement': false}]})); +}, 'SDES shows up when expected'); + +valid_for_pc = function(constraint) { + try { + pc = new RTCPeerConnection(null, constraint); + return true; + } catch (e) { + return false; + } +} + +test(t => { + assert_true(valid_for_pc(sdes_constraint)); + assert_true(valid_for_pc({'optional': [{'DtlsSrtpKeyAgreement': false}]})); + assert_true(valid_for_pc({'optional': [{'DtlsSrtpKeyAgreement': 'false'}]})); + assert_false(valid_for_pc({'DtlsSrtpKeyAgreement': false}), + 'Modern style constraint is not supported'); +}, 'Syntaxes valid for PC are as expected'); + + +</script> +</body> +</html> +
diff --git a/third_party/WebKit/LayoutTests/fast/scroll-behavior/scroll-customization/scrollstate-distribute-to-scroll-chain-descendant.html b/third_party/WebKit/LayoutTests/fast/scroll-behavior/scroll-customization/scrollstate-distribute-to-scroll-chain-descendant.html index 0bd6d4d..90bc078 100644 --- a/third_party/WebKit/LayoutTests/fast/scroll-behavior/scroll-customization/scrollstate-distribute-to-scroll-chain-descendant.html +++ b/third_party/WebKit/LayoutTests/fast/scroll-behavior/scroll-customization/scrollstate-distribute-to-scroll-chain-descendant.html
@@ -1,55 +1,85 @@ <!DOCTYPE html> -<html> -<head> <meta charset="utf-8"> <title>ScrollState constructor behaves correctly</title> <script src="../../../resources/testharness.js"></script> <script src="../../../resources/testharnessreport.js"></script> -</head> -<body> +<style> +* { + margin: 0 0; +} +div { + width: 400px; + height: 400px; + scroll-customization: auto; + overflow: scroll; +} +</style> + +<p> Verify the correctness of distributeToScrollChainDescendant(). </p> + <script> -test(function() { - assert_true('ScrollState' in window, "'ScrollState' in window"); - // TODO(tdresser): Don't rely on window.internals. See crbug.com/483091 for details. - assert_true(window.internals !== null, "'ScrollState' in window"); -}, "These tests only work with scroll customization enabled."); - -var elementCount = 10; -var remainingNumberOfTimesToBeCalled = elementCount; - -var distributeScroll = function(scrollState) { - this.calledOrder = elementCount - remainingNumberOfTimesToBeCalled; - remainingNumberOfTimesToBeCalled--; - scrollState.distributeToScrollChainDescendant(); -} - -var elements = []; -for (var i = 0; i < elementCount; ++i) { - var element = document.createElement("div"); - element.creationOrder = i; - element.setDistributeScroll(distributeScroll.bind(element), "disable-native-scroll"); - elements.push(element); -} - -if ('ScrollState' in window && window.internals) { test(function() { - var scrollState = new ScrollState({deltaX: 100, isDirectManipulation: true}); + assert_true('ScrollState' in window, "'ScrollState' in window"); + // TODO(tdresser): Don't rely on window.internals. See crbug.com/483091 for + // details. + assert_true(window.internals !== null, "'internals' in window"); + }, "These tests only work with scroll customization enabled."); + + var elementCount = 10; + var remainingNumberOfTimesToBeCalled = elementCount; + var elements = []; + + var distributeScroll = function(scrollState) { + this.calledOrder = elementCount - remainingNumberOfTimesToBeCalled; + remainingNumberOfTimesToBeCalled--; + scrollState.distributeToScrollChainDescendant(); + } + + var parentNode = document.body; + for (var i = 0; i < elementCount; ++i) { + var element = document.createElement("div"); + element.creationOrder = i; + element.id = 'e' + i; + element.style.scrollCustomization = 'auto'; + parentNode.appendChild(element); + elements.push(element); + parentNode = element; + } + + // Normal codepath for scrolling involves notifying all the elements in the + // scroll chain about a GestureScrollBegin. The element finds the direction + // of the scroll and decides whether or not its customization matches the + // direction. Since this test uses a synthetic chain, this step needs to + // be simulated by a GestureScrollBegin. This will also call an related + // customized scroll handlers. Therefore, to avoid the unwanted calls to the + // corresponding distributeScroll handlers, they are set up after the + // gesture. + eventSender.gestureScrollBegin(200, 200); + + elements.forEach((el) => { + el.setDistributeScroll(distributeScroll.bind(el), + "disable-native-scroll"); + }); + + + test(() => { + var scrollState = new ScrollState( + { deltaX: 100, isDirectManipulation: true}); window.internals.setScrollChain(scrollState, elements); scrollState.distributeToScrollChainDescendant(); - assert_equals(0, remainingNumberOfTimesToBeCalled); + assert_equals(remainingNumberOfTimesToBeCalled, 0); for (var i = 0; i < elementCount; ++i) { assert_equals(elements[i].creationOrder, elements[i].calledOrder); } - }, "distributeToScrollChainDescendant propagates correctly."); + }, "distributeToScrollChainDescendant propagates correctly"); - test(function() { - var scrollState = new ScrollState({deltaX: 100, isDirectManipulation: true}); + test(() => { + var scrollState = + new ScrollState({deltaX: 100, isDirectManipulation: true}); window.internals.setScrollChain(scrollState, []); assert_equals(0, remainingNumberOfTimesToBeCalled); scrollState.distributeToScrollChainDescendant(); assert_equals(0, remainingNumberOfTimesToBeCalled); - }, "distributeToScrollChainDescendant with empty scroll chain does nothing."); -} + }, + "distributeToScrollChainDescendant with empty scroll chain does nothing."); </script> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/fast/scroll-behavior/scroll-customization/touch-scroll-customization.html b/third_party/WebKit/LayoutTests/fast/scroll-behavior/scroll-customization/touch-scroll-customization.html index 49d119b..764ac2b 100644 --- a/third_party/WebKit/LayoutTests/fast/scroll-behavior/scroll-customization/touch-scroll-customization.html +++ b/third_party/WebKit/LayoutTests/fast/scroll-behavior/scroll-customization/touch-scroll-customization.html
@@ -10,6 +10,7 @@ * { margin:0; padding:0; + scroll-customization: auto; } *::-webkit-scrollbar {
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-worker-v8-cache-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-worker-v8-cache-expected.txt index d0d1b8b..2f4eb5e 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-worker-v8-cache-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/service-workers/service-worker-v8-cache-expected.txt
@@ -19,6 +19,19 @@ v8.compile Properties: { data : { + columnNumber : 0 + lineNumber : 0 + streamed : <boolean> + url : .../devtools/resources/v8-cache-script.js + } + endTime : <number> + startTime : <number> + type : "v8.compile" +} +Text details for v8.compile: v8-cache-script.js:1 +v8.compile Properties: +{ + data : { cacheProduceOptions : "code" columnNumber : 0 lineNumber : 0
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/memory/sampling-native-profile-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/memory/sampling-native-profile-expected.txt deleted file mode 100644 index 1664a79a..0000000 --- a/third_party/WebKit/LayoutTests/inspector-protocol/memory/sampling-native-profile-expected.txt +++ /dev/null
@@ -1,5 +0,0 @@ -Test sampling native memory profiler. -Sampling started -Sampling stopped -Found sample: true -
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/memory/sampling-native-profile.js b/third_party/WebKit/LayoutTests/inspector-protocol/memory/sampling-native-profile.js deleted file mode 100644 index e054cca..0000000 --- a/third_party/WebKit/LayoutTests/inspector-protocol/memory/sampling-native-profile.js +++ /dev/null
@@ -1,28 +0,0 @@ -(async function(testRunner) { - var {page, session, dp} = await testRunner.startBlank(`Test sampling native memory profiler.`); - - await dp.Memory.startSampling({ - samplingInterval: 100000, suppressRandomness: true}); - testRunner.log('Sampling started'); - await session.evaluate(` - const canvas = document.createElement('canvas'); - canvas.width = 500; - canvas.height = 200; - const ctx = canvas.getContext('2d'); - ctx.fillStyle = 'green'; - ctx.fillRect(0, 0, 10, 10); - document.body.appendChild(canvas); - `); - const message = await dp.Memory.getSamplingProfile(); - await dp.Memory.stopSampling(); - testRunner.log('Sampling stopped'); - - const profile = message.result.profile; - const foundTheSample = profile.samples.some(sample => - sample.size >= 500 * 200 && sample.stack.some(frame => frame.includes('HTMLCanvasElement'))); - testRunner.log('Found sample: ' + foundTheSample); - if (!foundTheSample) - testRunner.log(profile); - - testRunner.completeTest(); -})
diff --git a/third_party/WebKit/LayoutTests/media/autoplay-muted.html b/third_party/WebKit/LayoutTests/media/autoplay-muted.html index 424de18..4f3a9cae3 100644 --- a/third_party/WebKit/LayoutTests/media/autoplay-muted.html +++ b/third_party/WebKit/LayoutTests/media/autoplay-muted.html
@@ -94,6 +94,8 @@ document.onclick = t.step_func_done(function() { e.muted = false; assert_false(e.paused, "The video should not be paused."); + // Consume the triggered transient user activation + eventSender.consumeUserActivation(); }); }, "Test that unmuting autoplayed video with gesture doesn't pause it.");
diff --git a/third_party/WebKit/LayoutTests/media/controls/toggle-class-without-poster.html b/third_party/WebKit/LayoutTests/media/controls/toggle-class-with-preload-metadata.html similarity index 88% rename from third_party/WebKit/LayoutTests/media/controls/toggle-class-without-poster.html rename to third_party/WebKit/LayoutTests/media/controls/toggle-class-with-preload-metadata.html index 5c3e123..36877f3 100644 --- a/third_party/WebKit/LayoutTests/media/controls/toggle-class-without-poster.html +++ b/third_party/WebKit/LayoutTests/media/controls/toggle-class-with-preload-metadata.html
@@ -14,7 +14,7 @@ checkControlsClassName(video, 'phase-pre-ready state-no-source use-default-poster'); video.onloadedmetadata = t.step_func_done(() => { - checkControlsClassName(video, 'phase-ready state-stopped use-default-poster'); + checkControlsClassName(video, 'phase-ready state-stopped'); }); video.src = findMediaFile('video', '../content/counting');
diff --git a/third_party/WebKit/LayoutTests/media/controls/toggle-class-without-poster.html b/third_party/WebKit/LayoutTests/media/controls/toggle-class-with-preload-none.html similarity index 75% copy from third_party/WebKit/LayoutTests/media/controls/toggle-class-without-poster.html copy to third_party/WebKit/LayoutTests/media/controls/toggle-class-with-preload-none.html index 5c3e123..9f7dded 100644 --- a/third_party/WebKit/LayoutTests/media/controls/toggle-class-without-poster.html +++ b/third_party/WebKit/LayoutTests/media/controls/toggle-class-with-preload-none.html
@@ -5,7 +5,7 @@ <script src="../../resources/testharnessreport.js"></script> <script src="../media-controls.js"></script> <script src="../media-file.js"></script> -<video controls width=400 preload=metadata></video> +<video controls width=400 preload=none></video> <script> async_test(t => { const video = document.querySelector('video'); @@ -13,8 +13,8 @@ checkControlsClassName(video, 'phase-pre-ready state-no-source use-default-poster'); - video.onloadedmetadata = t.step_func_done(() => { - checkControlsClassName(video, 'phase-ready state-stopped use-default-poster'); + window.onload = t.step_func_done(() => { + checkControlsClassName(video, 'phase-pre-ready state-no-metadata use-default-poster'); }); video.src = findMediaFile('video', '../content/counting');
diff --git a/third_party/WebKit/LayoutTests/media/media-play-promise.html b/third_party/WebKit/LayoutTests/media/media-play-promise.html index e70ef77a..40cba406 100644 --- a/third_party/WebKit/LayoutTests/media/media-play-promise.html +++ b/third_party/WebKit/LayoutTests/media/media-play-promise.html
@@ -333,6 +333,8 @@ // Test that play() on an element when media playback requires a gesture // returns a rejected promise if there is no user gesture. function playRequiresUserGestureAndDoesNotHaveIt(t, audio) { + // Consume transient user activation triggered in the previous test. + eventSender.consumeUserActivation(); audio.src = findMediaFile("audio", "content/test"); playExpectingRejectedPromise(t, audio, "NotAllowedError"); }
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/resize-iframe-text.html b/third_party/WebKit/LayoutTests/paint/invalidation/resize-iframe-text.html index 11fbdea8..97f825e7 100644 --- a/third_party/WebKit/LayoutTests/paint/invalidation/resize-iframe-text.html +++ b/third_party/WebKit/LayoutTests/paint/invalidation/resize-iframe-text.html
@@ -2,11 +2,16 @@ <script src="../../resources/run-after-layout-and-paint.js"></script> <script src="resources/text-based-repaint.js"></script> <script> +// Disable implicit root scroller since the iframe full screen and would +// otherwise be promoted to rootScroller which changes painting and +// invalidation. +if (window.internals) + window.internals.runtimeFlags.implicitRootScrollerEnabled = false; if (window.testRunner) testRunner.useUnfortunateSynchronousResizeMode(); onload = function() { runAfterLayoutAndPaint(function() { - // Use smaller size because window.resizeTo/By() will fail if the sizae is + // Use smaller size because window.resizeTo/By() will fail if the size is // bigger than the screen size. window.resizeTo(500, 200); runRepaintAndPixelTest();
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/svg/js-late-marker-and-object-creation-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/svg/js-late-marker-and-object-creation-expected.txt index e3ff36489..23ac4fb1 100644 --- a/third_party/WebKit/LayoutTests/paint/invalidation/svg/js-late-marker-and-object-creation-expected.txt +++ b/third_party/WebKit/LayoutTests/paint/invalidation/svg/js-late-marker-and-object-creation-expected.txt
@@ -9,7 +9,7 @@ { "object": "LayoutSVGPath path", "rect": [189, 197, 139, 139], - "reason": "style change" + "reason": "full" }, { "object": "LayoutSVGPath path", @@ -35,7 +35,7 @@ }, { "object": "LayoutSVGPath path", - "reason": "style change" + "reason": "full" } ] }
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/svg/js-late-marker-creation-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/svg/js-late-marker-creation-expected.txt index 71d7a73..ca1d5b3 100644 --- a/third_party/WebKit/LayoutTests/paint/invalidation/svg/js-late-marker-creation-expected.txt +++ b/third_party/WebKit/LayoutTests/paint/invalidation/svg/js-late-marker-creation-expected.txt
@@ -9,7 +9,7 @@ { "object": "LayoutSVGPath path", "rect": [189, 197, 139, 139], - "reason": "style change" + "reason": "full" } ] } @@ -17,7 +17,7 @@ "objectPaintInvalidations": [ { "object": "LayoutSVGPath path", - "reason": "style change" + "reason": "full" } ] }
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/svg/js-late-mask-and-object-creation-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/svg/js-late-mask-and-object-creation-expected.txt index 1ea80a34..650c5220a 100644 --- a/third_party/WebKit/LayoutTests/paint/invalidation/svg/js-late-mask-and-object-creation-expected.txt +++ b/third_party/WebKit/LayoutTests/paint/invalidation/svg/js-late-mask-and-object-creation-expected.txt
@@ -14,7 +14,7 @@ { "object": "LayoutSVGRect rect", "rect": [0, 100, 800, 100], - "reason": "style change" + "reason": "full" }, { "object": "LayoutSVGRect rect", @@ -35,7 +35,7 @@ }, { "object": "LayoutSVGRect rect", - "reason": "style change" + "reason": "full" } ] }
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/svg/js-late-mask-creation-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/svg/js-late-mask-creation-expected.txt index 35c81cb..d54295d 100644 --- a/third_party/WebKit/LayoutTests/paint/invalidation/svg/js-late-mask-creation-expected.txt +++ b/third_party/WebKit/LayoutTests/paint/invalidation/svg/js-late-mask-creation-expected.txt
@@ -9,7 +9,7 @@ { "object": "LayoutSVGRect rect", "rect": [0, 100, 800, 100], - "reason": "style change" + "reason": "full" } ] } @@ -17,7 +17,7 @@ "objectPaintInvalidations": [ { "object": "LayoutSVGRect rect", - "reason": "style change" + "reason": "full" } ] }
diff --git a/third_party/WebKit/LayoutTests/platform/linux/external/wpt/webauthn/createcredential-badargs-rp.https-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/external/wpt/webauthn/createcredential-badargs-rp.https-expected.txt deleted file mode 100644 index 9ba21178..0000000 --- a/third_party/WebKit/LayoutTests/platform/linux/external/wpt/webauthn/createcredential-badargs-rp.https-expected.txt +++ /dev/null
@@ -1,14 +0,0 @@ -This is a testharness.js-based test. -PASS rp missing -PASS rp is string -FAIL Bad rp: id is object assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "SecurityError: The relying party ID '[object Object]' is not a registrable domain suffix of, nor equal to 'https://web-platform.test:8444'." ("SecurityError") expected object "TypeError" ("TypeError") -FAIL Bad rp: id is null assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "SecurityError: The relying party ID 'null' is not a registrable domain suffix of, nor equal to 'https://web-platform.test:8444'." ("SecurityError") expected object "TypeError" ("TypeError") -FAIL Bad rp: id is empty String assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError") -FAIL Bad rp: name is object assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError") -FAIL Bad rp: name is null assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError") -FAIL Bad rp: name is empty String assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError") -FAIL Bad rp: icon is object assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError") -FAIL Bad rp: icon is null assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError") -FAIL Bad rp: icon is empty String assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError") -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/js-late-clipPath-and-object-creation-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/js-late-clipPath-and-object-creation-expected.txt index b9d0c7a..33379cc 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/js-late-clipPath-and-object-creation-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/js-late-clipPath-and-object-creation-expected.txt
@@ -29,7 +29,7 @@ { "object": "LayoutSVGText text", "rect": [16, 39, 784, 174], - "reason": "style change" + "reason": "full" }, { "object": "LayoutSVGText text", @@ -66,11 +66,11 @@ }, { "object": "LayoutSVGText text", - "reason": "style change" + "reason": "full" }, { "object": "RootInlineBox", - "reason": "style change" + "reason": "full" }, { "object": "LayoutSVGInlineText #text",
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/js-late-clipPath-creation-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/js-late-clipPath-creation-expected.txt index f240fe95..ebbb60ac 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/js-late-clipPath-creation-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/js-late-clipPath-creation-expected.txt
@@ -19,7 +19,7 @@ { "object": "LayoutSVGText text", "rect": [16, 39, 784, 174], - "reason": "style change" + "reason": "full" } ] } @@ -31,11 +31,11 @@ }, { "object": "LayoutSVGText text", - "reason": "style change" + "reason": "full" }, { "object": "RootInlineBox", - "reason": "style change" + "reason": "full" }, { "object": "LayoutSVGInlineText #text",
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/js-late-gradient-creation-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/js-late-gradient-creation-expected.txt index 3716038..0a60892 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/js-late-gradient-creation-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/js-late-gradient-creation-expected.txt
@@ -14,7 +14,7 @@ { "object": "LayoutSVGText text", "rect": [33, 21, 693, 197], - "reason": "style change" + "reason": "full" } ] } @@ -22,11 +22,11 @@ "objectPaintInvalidations": [ { "object": "LayoutSVGText text", - "reason": "style change" + "reason": "full" }, { "object": "RootInlineBox", - "reason": "style change" + "reason": "full" }, { "object": "LayoutSVGInlineText #text",
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/js-late-pattern-creation-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/js-late-pattern-creation-expected.txt index 362c28e8..eac8a81 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/js-late-pattern-creation-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/svg/js-late-pattern-creation-expected.txt
@@ -14,7 +14,7 @@ { "object": "LayoutSVGText text", "rect": [33, 21, 618, 197], - "reason": "style change" + "reason": "full" } ] } @@ -22,11 +22,11 @@ "objectPaintInvalidations": [ { "object": "LayoutSVGText text", - "reason": "style change" + "reason": "full" }, { "object": "RootInlineBox", - "reason": "style change" + "reason": "full" }, { "object": "LayoutSVGInlineText #text",
diff --git a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/js-late-clipPath-and-object-creation-expected.txt b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/js-late-clipPath-and-object-creation-expected.txt index 1250726..b6e8e476 100644 --- a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/js-late-clipPath-and-object-creation-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/js-late-clipPath-and-object-creation-expected.txt
@@ -29,7 +29,7 @@ { "object": "LayoutSVGText text", "rect": [16, 42, 784, 170], - "reason": "style change" + "reason": "full" }, { "object": "LayoutSVGText text", @@ -66,11 +66,11 @@ }, { "object": "LayoutSVGText text", - "reason": "style change" + "reason": "full" }, { "object": "RootInlineBox", - "reason": "style change" + "reason": "full" }, { "object": "LayoutSVGInlineText #text",
diff --git a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/js-late-clipPath-creation-expected.txt b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/js-late-clipPath-creation-expected.txt index 1130e8d..e52307a8 100644 --- a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/js-late-clipPath-creation-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/js-late-clipPath-creation-expected.txt
@@ -19,7 +19,7 @@ { "object": "LayoutSVGText text", "rect": [16, 42, 784, 170], - "reason": "style change" + "reason": "full" } ] } @@ -31,11 +31,11 @@ }, { "object": "LayoutSVGText text", - "reason": "style change" + "reason": "full" }, { "object": "RootInlineBox", - "reason": "style change" + "reason": "full" }, { "object": "LayoutSVGInlineText #text",
diff --git a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/js-late-gradient-creation-expected.txt b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/js-late-gradient-creation-expected.txt index 4a6c1ef1..f8a23a0c 100644 --- a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/js-late-gradient-creation-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/js-late-gradient-creation-expected.txt
@@ -14,7 +14,7 @@ { "object": "LayoutSVGText text", "rect": [33, 23, 697, 194], - "reason": "style change" + "reason": "full" } ] } @@ -22,11 +22,11 @@ "objectPaintInvalidations": [ { "object": "LayoutSVGText text", - "reason": "style change" + "reason": "full" }, { "object": "RootInlineBox", - "reason": "style change" + "reason": "full" }, { "object": "LayoutSVGInlineText #text",
diff --git a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/js-late-pattern-creation-expected.txt b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/js-late-pattern-creation-expected.txt index 83a4a3e..d8b70f5 100644 --- a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/js-late-pattern-creation-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/svg/js-late-pattern-creation-expected.txt
@@ -14,7 +14,7 @@ { "object": "LayoutSVGText text", "rect": [33, 23, 622, 194], - "reason": "style change" + "reason": "full" } ] } @@ -22,11 +22,11 @@ "objectPaintInvalidations": [ { "object": "LayoutSVGText text", - "reason": "style change" + "reason": "full" }, { "object": "RootInlineBox", - "reason": "style change" + "reason": "full" }, { "object": "LayoutSVGInlineText #text",
diff --git a/third_party/WebKit/LayoutTests/platform/win7/external/wpt/webauthn/createcredential-badargs-rp.https-expected.txt b/third_party/WebKit/LayoutTests/platform/win7/external/wpt/webauthn/createcredential-badargs-rp.https-expected.txt deleted file mode 100644 index 9ba21178..0000000 --- a/third_party/WebKit/LayoutTests/platform/win7/external/wpt/webauthn/createcredential-badargs-rp.https-expected.txt +++ /dev/null
@@ -1,14 +0,0 @@ -This is a testharness.js-based test. -PASS rp missing -PASS rp is string -FAIL Bad rp: id is object assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "SecurityError: The relying party ID '[object Object]' is not a registrable domain suffix of, nor equal to 'https://web-platform.test:8444'." ("SecurityError") expected object "TypeError" ("TypeError") -FAIL Bad rp: id is null assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "SecurityError: The relying party ID 'null' is not a registrable domain suffix of, nor equal to 'https://web-platform.test:8444'." ("SecurityError") expected object "TypeError" ("TypeError") -FAIL Bad rp: id is empty String assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError") -FAIL Bad rp: name is object assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError") -FAIL Bad rp: name is null assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError") -FAIL Bad rp: name is empty String assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError") -FAIL Bad rp: icon is object assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError") -FAIL Bad rp: icon is null assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError") -FAIL Bad rp: icon is empty String assert_throws: Expected bad parameters to fail function "function() { throw e }" threw object "NotSupportedError: The user agent does not implement a password store." ("NotSupportedError") expected object "TypeError" ("TypeError") -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/rootscroller/rootscroller-during-fullscreen.html b/third_party/WebKit/LayoutTests/rootscroller/rootscroller-during-fullscreen.html new file mode 100644 index 0000000..c7c87fc --- /dev/null +++ b/third_party/WebKit/LayoutTests/rootscroller/rootscroller-during-fullscreen.html
@@ -0,0 +1,149 @@ +<!DOCTYPE html> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> +<script> + // This test verifies the rootScroller behavior while the document is in + // fullscreen. We expect that the effective rootScroller of all documents on + // a page revert to the document itself. On exiting fullscreen, the + // designated document.rootScroller should take effect again. + + // Helper async function to block execution for n number of rAFs. + async function nFrames(n) { + return new Promise(resolve => { + let remainingFrames = n; + let func = function() { + --remainingFrames; + if (remainingFrames === 0) + resolve(); + else { + requestAnimationFrame(func); + } + }; + + if (n === 0) { + resolve(); + } else { + requestAnimationFrame(() => { + func(resolve); + }); + } + }); + } + + const test = async_test("Fullscreen rootScroller Test"); + let iframe; + let childDocument; + let scroller; + + async function fullscreenChanged() { + if (document.webkitIsFullScreen) { + await nFrames(2); + test.step(() => { + assert_equals( + window.internals.effectiveRootScroller(document), + document, + "Entering fullscreen should reset root document's effective " + + "root scroller"); + assert_equals( + window.internals.effectiveRootScroller(childDocument), + childDocument, + "Entering fullscreen should reset iframe's effective root " + + "scroller"); + }); + document.webkitExitFullscreen(); + } else { + await nFrames(2); + test.step(() => { + assert_equals( + window.internals.effectiveRootScroller(document), + iframe, + "Exiting fullscreen should set the iframe back as the root " + + "document's effective root scroller."); + assert_equals( + window.internals.effectiveRootScroller(childDocument), + scroller, + "Exiting fullscreen should set the scroller div back as the " + + "iframe's effective root scroller."); + }); + test.done(); + } + } + + addEventListener('load', async () => { + if (!window.internals) + return; + + iframe = document.getElementById('frame'); + childDocument = iframe.contentDocument; + scroller = childDocument.getElementById('scroller'); + + scroller.addEventListener('click', () => { + scroller.webkitRequestFullscreen(); + }); + + document.addEventListener('webkitfullscreenchange', fullscreenChanged); + + document.rootScroller = iframe; + childDocument.rootScroller = scroller; + + await nFrames(1); + + test.step(() => { + assert_equals( + window.internals.effectiveRootScroller(document), + iframe, + "Root document should initially have iframe as effective root " + + "scroller"); + assert_equals( + window.internals.effectiveRootScroller(childDocument), + scroller, + "Iframe should initially have scroller div as effective root " + + "scroller"); + }); + + // Fullscreen must be click-activated since it needs a user gesture. + chrome.gpuBenchmarking.pointerActionSequence([ + { + "source": "mouse", + "actions": [ + { "name": "pointerDown", "x": 10, "y": 10 }, + { "name": "pointerUp" } + ] + }]); + }); +</script> + +<style> + ::-webkit-scrollbar { + width: 0px; + height: 0px; + } + html, body { + width: 100%; + height: 100%; + margin: 0; + } + iframe { + width: 100%; + height: 100%; + border: 0; + } +</style> + +<iframe id="frame" srcdoc=" + <!DOCTYPE html> + <style> + body,html { + width: 100%; + height: 100%; + margin: 0; + } + ::-webkit-scrollbar { + width: 0px; + height: 0px; + } + </style> + <div id='scroller' style='width:100%; height:100%; overflow: auto;'> + <div style='height: 2000px; width: 2000px;'></div> + </div>" allowfullscreen> +</iframe>
diff --git a/third_party/WebKit/LayoutTests/rootscroller/set-rootscroller-before-load-expected.html b/third_party/WebKit/LayoutTests/rootscroller/set-rootscroller-before-load-expected.html new file mode 100644 index 0000000..179a06d --- /dev/null +++ b/third_party/WebKit/LayoutTests/rootscroller/set-rootscroller-before-load-expected.html
@@ -0,0 +1,31 @@ +<!DOCTYPE html> +<meta name="viewport" content="width=device-width, user-scalable=no" /> +<style> + html, body { + height: 100%; + width: 100%; + margin: 0; + } + body { + background-color: red; + } + #bottom { + position: fixed; + left: 50px; + right: 50px; + height: 20px; + bottom: 0px; + background-color: coral; + z-index: 2; + } + #container { + width: 100%; + height: 600px; + background-color: #808080; + transform: translateZ(0); + } +</style> + +<div id="container"> + <div style="height: 2000px"></div> +</div>
diff --git a/third_party/WebKit/LayoutTests/rootscroller/set-rootscroller-before-load.html b/third_party/WebKit/LayoutTests/rootscroller/set-rootscroller-before-load.html new file mode 100644 index 0000000..5760a7c --- /dev/null +++ b/third_party/WebKit/LayoutTests/rootscroller/set-rootscroller-before-load.html
@@ -0,0 +1,68 @@ +<!DOCTYPE html> +<meta name="viewport" content="width=device-width, user-scalable=no" /> +<link rel=match href=set-root-scroller-before-load.html> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> +<script> + // Set the browser controls to be 100px and hidden. + // NOTE: It is important that this test be run with the Android viewport + // flags turned on. + if (window.internals) { + window.internals.setBrowserControlsState(100, 0, false); + testRunner.setShouldGeneratePixelResults(true); + testRunner.waitUntilDone(); + } + + addEventListener("load", function() { + const iframe = document.getElementById("iframe"); + const scroller = iframe.contentDocument.getElementById("scroller"); + document.rootScroller = iframe; + iframe.contentDocument.rootScroller = scroller; + requestAnimationFrame(() => { + assert_equals( + internals.effectiveRootScroller(document), iframe, + "rootScroller in main document should be iframe."); + assert_equals( + internals.effectiveRootScroller(iframe.contentDocument), scroller, + "rootScroller in iframe should be scroller element."); + testRunner.notifyDone(); + }); + }); +</script> +<style> + html, body { + height: 100%; + width: 100%; + margin: 0; + } + #iframe { + position: absolute; + width: 100%; + height: 100%; + border: 0; + } +</style> + +<iframe id="iframe" srcdoc=" + <style> + html,body { + height: 100%; + width: 100%; + margin:0; + background-color: blue; + } + #scroller { + position: absolute; + width: 100%; + height: 100%; + background-color: #808080; + overflow: auto; + } + </style> + <div id='scroller'> + <div style='height:2000px'></div> + </div> + "></iframe> +<script> + document.rootScroller = document.getElementById("iframe"); +</script>
diff --git a/third_party/WebKit/LayoutTests/svg/custom/duplicate-ids-remove-first-expected.html b/third_party/WebKit/LayoutTests/svg/custom/duplicate-ids-remove-first-expected.html new file mode 100644 index 0000000..f718ea6 --- /dev/null +++ b/third_party/WebKit/LayoutTests/svg/custom/duplicate-ids-remove-first-expected.html
@@ -0,0 +1,2 @@ +<!DOCTYPE html> +<div style="width: 100px; height: 100px; background-color: green"></div>
diff --git a/third_party/WebKit/LayoutTests/svg/custom/duplicate-ids-remove-first.html b/third_party/WebKit/LayoutTests/svg/custom/duplicate-ids-remove-first.html new file mode 100644 index 0000000..7c09acd --- /dev/null +++ b/third_party/WebKit/LayoutTests/svg/custom/duplicate-ids-remove-first.html
@@ -0,0 +1,16 @@ +<!DOCTYPE html> +<script src="../../resources/run-after-layout-and-paint.js"></script> +<svg> + <linearGradient id="f"> + <stop stop-color="red"/> + </linearGradient> + <linearGradient id="f"> + <stop stop-color="green"/> + </linearGradient> + <rect width="100" height="100" fill="url(#f) orange"/> +</svg> +<script> +runAfterLayoutAndPaint(function() { + document.querySelector('lineargradient').remove(); +}, true); +</script>
diff --git a/third_party/WebKit/LayoutTests/virtual/android/rootscroller/nested-rootscroller-browser-controls-bounds-hidden.html b/third_party/WebKit/LayoutTests/virtual/android/rootscroller/nested-rootscroller-browser-controls-bounds-hidden.html index ffe35d5..cce3b7e6 100644 --- a/third_party/WebKit/LayoutTests/virtual/android/rootscroller/nested-rootscroller-browser-controls-bounds-hidden.html +++ b/third_party/WebKit/LayoutTests/virtual/android/rootscroller/nested-rootscroller-browser-controls-bounds-hidden.html
@@ -6,13 +6,18 @@ // flags turned on. if (window.internals) { window.internals.setBrowserControlsState(100, 0, true); - window.internals.setBrowserControlsShownRatio(0); + testRunner.waitUntilDone(); } addEventListener("load", function() { var iframe = document.getElementById("iframe"); document.rootScroller = iframe; iframe.contentDocument.rootScroller = iframe.contentDocument.getElementById("scroller"); + + if (window.internals) + window.internals.setBrowserControlsShownRatio(0); + + requestAnimationFrame(() => { testRunner.notifyDone(); }); }); </script> <style>
diff --git a/third_party/WebKit/LayoutTests/virtual/android/rootscroller/nested-rootscroller-browser-controls-bounds-shown.html b/third_party/WebKit/LayoutTests/virtual/android/rootscroller/nested-rootscroller-browser-controls-bounds-shown.html index ba19c0c..70cb3f33 100644 --- a/third_party/WebKit/LayoutTests/virtual/android/rootscroller/nested-rootscroller-browser-controls-bounds-shown.html +++ b/third_party/WebKit/LayoutTests/virtual/android/rootscroller/nested-rootscroller-browser-controls-bounds-shown.html
@@ -6,13 +6,18 @@ // flags turned on. if (window.internals) { window.internals.setBrowserControlsState(100, 0, false); - window.internals.setBrowserControlsShownRatio(1); + testRunner.waitUntilDone(); } addEventListener("load", function() { var iframe = document.getElementById("iframe"); document.rootScroller = iframe; iframe.contentDocument.rootScroller = iframe.contentDocument.getElementById("scroller"); + + if (window.internals) + window.internals.setBrowserControlsShownRatio(1); + + requestAnimationFrame(() => { testRunner.notifyDone(); }); }); </script> <style>
diff --git a/third_party/WebKit/LayoutTests/virtual/scroll_customization/fast/scroll-behavior/scroll-customization/scroll-customization-property.html b/third_party/WebKit/LayoutTests/virtual/scroll_customization/fast/scroll-behavior/scroll-customization/scroll-customization-property.html new file mode 100644 index 0000000..642c98aa --- /dev/null +++ b/third_party/WebKit/LayoutTests/virtual/scroll_customization/fast/scroll-behavior/scroll-customization/scroll-customization-property.html
@@ -0,0 +1,213 @@ +<!doctype html> +<title> Scroll Customization Property </title> +<script src="../../../../../resources/testharness.js"></script> +<script src="../../../../../resources/testharnessreport.js"></script> +<style> +* { + margin: 0; + padding: 0; +} + + +p { + position: relative; +} + +#test-div { + height: 400px; + width: 400px; + overflow: scroll; +} +</style> + +<div id="test-div"> + <div id="spacer" style="width: 1000px; height:1000px;" ></div> +</div> + +<script> + test(function() { + assert_true('internals' in window, '"internals" is needed for this test.'); + assert_true('gpuBenchmarking' in chrome, + '"gpuBenchmarking" is required for this test'); + assert_true(internals.runtimeFlags.scrollCustomizationEnabled, + '"ScrollCustomization" feature must be enabled.'); + assert_true('ScrollState' in window, "'ScrollState' in window"); + }, 'These tests only work when certain features are enabled.'); + + var element = document.getElementById('test-div'); + test(function() { + assert_true('scrollCustomization' in element.style); + }, 'Verify "scroll-customization" is part of element\'s style.'); + + // Used to track invocation of scroll customization handlers. + element.didCallApplyScrollHandler = false; + element.didCallScrollCustomizationHandlers = false; + + var testCases = [ + // [scroll customization, gesture, scroll customization handler called] + ["pan-up pan-x", "pan-right", true], + ["pan-up pan-x", "pan-left", true], + ["pan-up pan-x", "pan-up", true], + ["pan-up pan-x", "pan-down", false], + ["pan-up pan-left", "pan-right", false], + ["pan-up pan-left", "pan-left", true], + ["pan-up pan-left", "pan-up", true], + ["pan-up pan-left", "pan-down", false], + ["pan-up pan-right", "pan-right", true], + ["pan-up pan-right", "pan-left", false], + ["pan-up pan-right", "pan-up", true], + ["pan-up pan-right", "pan-down", false], + ["pan-up", "pan-right", false], + ["pan-up", "pan-left", false], + ["pan-up", "pan-up", true], + ["pan-up", "pan-down", false], + ["pan-x", "pan-right", true], + ["pan-x", "pan-left", true], + ["pan-x", "pan-up", false], + ["pan-x", "pan-down", false], + ["pan-left", "pan-right", false], + ["pan-left", "pan-left", true], + ["pan-left", "pan-up", false], + ["pan-left", "pan-down", false], + ["pan-right", "pan-right", true], + ["pan-right", "pan-left", false], + ["pan-right", "pan-up", false], + ["pan-right", "pan-down", false], + ["none", "pan-right", false], + ["none", "pan-left", false], + ["none", "pan-up", false], + ["none", "pan-down", false], + ["auto", "pan-right", true], + ["auto", "pan-left", true], + ["auto", "pan-up", true], + ["auto", "pan-down", true], + ["pan-left pan-y", "pan-right", false], + ["pan-left pan-y", "pan-left", true], + ["pan-left pan-y", "pan-up", true], + ["pan-left pan-y", "pan-down", true], + ["pan-right pan-y", "pan-right", true], + ["pan-right pan-y", "pan-left", false], + ["pan-right pan-y", "pan-up", true], + ["pan-right pan-y", "pan-down", true], + ["pan-y", "pan-right", false], + ["pan-y", "pan-left", false], + ["pan-y", "pan-up", true], + ["pan-y", "pan-down", true], + ["pan-down pan-x", "pan-right", true], + ["pan-down pan-x", "pan-left", true], + ["pan-down pan-x", "pan-up", false], + ["pan-down pan-x", "pan-down", true], + ["pan-down pan-left", "pan-right", false], + ["pan-down pan-left", "pan-left", true], + ["pan-down pan-left", "pan-up", false], + ["pan-down pan-left", "pan-down", true], + ["pan-down pan-right", "pan-right", true], + ["pan-down pan-right", "pan-left", false], + ["pan-down pan-right", "pan-up", false], + ["pan-down pan-right", "pan-down", true], + ["pan-down", "pan-right", false], + ["pan-down", "pan-left", false], + ["pan-down", "pan-up", false], + ["pan-down", "pan-down", true], + // The following cases are invalid and should not be set as customization. + ["pan-left pan-right", "pan-left", false], + ["pan-left pan-right", "pan-right", false], + ["pan-left pan-right", "pan-up", false], + ["pan-left pan-right", "pan-down", false], + ["pan-y pan-y", "pan-left", false], + ["pan-y pan-y", "pan-right", false], + ["pan-y pan-y", "pan-up", false], + ["pan-y pan-y", "pan-down", false], + ]; + + + function applyScrollCallback(unused_ss) { + element.didCallApplyScrollHandler = true; + } + + function distributeScrollCallback(unused_ss) { + element.didCallDistributeScrollHandler = true; + } + + element.setApplyScroll( + applyScrollCallback, 'perform-before-native-scroll'); + element.setDistributeScroll( + distributeScrollCallback, 'perform-before-native-scroll'); + + + // Called before each test. + function resetState() { + // Make sure the <div> can scroll in all directions. This is necessary or + // otherwise there won't be a scroll chain containing which includes + // |element|. + element.scrollTop = 400; + element.scrollLeft = 400; + + element.didCallApplyScrollHandler = false; + element.didCallDistributeScrollHandler = false; + element.style.scrollCustomization = 'none'; + } + + function didCallScrollCustomizationHandlers() { + assert_equals(element.didCallApplyScrollHandler, element.didCallDistributeScrollHandler, + "It is invalid to call only one of the applyScroll" + + " and distributeScroll handler methods."); + return element.didCallApplyScrollHandler; + } + + // Returns a promise after applying the |gesture|. The |gesture| will result + // in a scrolling phase. + function applyGesture(gesture) { + var deltaX = 0, deltaY = 0; + // The delta has to be large enough to avoid getting a fling instead. + var delta = 50; + switch (gesture) { + case 'pan-right': + deltaX = -delta; + break; + case 'pan-left': + deltaX = delta; + break; + case 'pan-down': + deltaY = -delta; + break; + case 'pan-up': + deltaY = delta; + break; + } + + var startingX = 100, startingY = 100; + // TODO(ekaramad): The test takes too long due to mandatory delay. Revisit + // this when and if it becomes possible to create gesture scroll without the + // delay (https://crbug.com/803168). + // Necessary to avoid getting a fling instead. Cannot be too small. + var pauseSeconds = 0.05; + return new Promise((resolve) => { + chrome.gpuBenchmarking.pointerActionSequence([{ + source: 'touch', + actions: [ + { name: 'pointerDown', x: startingX, y: startingY }, + //{ name: 'pause', duration: pauseSeconds}, + { name: 'pointerMove', x: (startingX + deltaX), + y: (startingY + deltaY)}, + { name: 'pause', duration: pauseSeconds}, + { name: 'pointerUp'} + ] + }], resolve); + }); + } + + // Define the set of promise tests for all test cases. + testCases.forEach((testcase) => { + promise_test(async() => { + resetState(); + element.style.scrollCustomization = testcase[0]; + await applyGesture(testcase[1]); + let handlersWereCalled = didCallScrollCustomizationHandlers(); + assert_equals(handlersWereCalled, testcase[2], + `Handlers were ${handlersWereCalled ? '' : 'not '}called. They must` + + ` ${testcase[2] ? '' : 'not '}have.`); + }, `Verify correctness of "scroll-customization: ${testcase[0]}"` + + ` when gesture "${testcase[1]}" is applied.`); + }); +</script>
diff --git a/third_party/WebKit/LayoutTests/virtual/spv175/paint/invalidation/svg/js-late-gradient-creation-expected.txt b/third_party/WebKit/LayoutTests/virtual/spv175/paint/invalidation/svg/js-late-gradient-creation-expected.txt index d210fa0..f1b014ba 100644 --- a/third_party/WebKit/LayoutTests/virtual/spv175/paint/invalidation/svg/js-late-gradient-creation-expected.txt +++ b/third_party/WebKit/LayoutTests/virtual/spv175/paint/invalidation/svg/js-late-gradient-creation-expected.txt
@@ -27,11 +27,11 @@ "objectPaintInvalidations": [ { "object": "LayoutSVGText text", - "reason": "style change" + "reason": "full" }, { "object": "RootInlineBox", - "reason": "style change" + "reason": "full" }, { "object": "LayoutSVGInlineText #text",
diff --git a/third_party/WebKit/LayoutTests/virtual/spv175/paint/invalidation/svg/js-late-marker-and-object-creation-expected.txt b/third_party/WebKit/LayoutTests/virtual/spv175/paint/invalidation/svg/js-late-marker-and-object-creation-expected.txt index 7d033ce..4cad7811 100644 --- a/third_party/WebKit/LayoutTests/virtual/spv175/paint/invalidation/svg/js-late-marker-and-object-creation-expected.txt +++ b/third_party/WebKit/LayoutTests/virtual/spv175/paint/invalidation/svg/js-late-marker-and-object-creation-expected.txt
@@ -19,7 +19,7 @@ { "object": "LayoutSVGPath path", "rect": [189, 197, 139, 139], - "reason": "style change" + "reason": "full" }, { "object": "LayoutSVGRoot svg id='svg-root'", @@ -40,7 +40,7 @@ }, { "object": "LayoutSVGPath path", - "reason": "style change" + "reason": "full" } ] }
diff --git a/third_party/WebKit/LayoutTests/virtual/spv175/paint/invalidation/svg/js-late-marker-creation-expected.txt b/third_party/WebKit/LayoutTests/virtual/spv175/paint/invalidation/svg/js-late-marker-creation-expected.txt index 8a7be2e..5c3a253 100644 --- a/third_party/WebKit/LayoutTests/virtual/spv175/paint/invalidation/svg/js-late-marker-creation-expected.txt +++ b/third_party/WebKit/LayoutTests/virtual/spv175/paint/invalidation/svg/js-late-marker-creation-expected.txt
@@ -19,7 +19,7 @@ { "object": "LayoutSVGPath path", "rect": [189, 197, 139, 139], - "reason": "style change" + "reason": "full" } ] } @@ -27,7 +27,7 @@ "objectPaintInvalidations": [ { "object": "LayoutSVGPath path", - "reason": "style change" + "reason": "full" } ] }
diff --git a/third_party/WebKit/LayoutTests/virtual/spv175/paint/invalidation/svg/js-late-mask-and-object-creation-expected.txt b/third_party/WebKit/LayoutTests/virtual/spv175/paint/invalidation/svg/js-late-mask-and-object-creation-expected.txt index e65f85a5..eed315f4 100644 --- a/third_party/WebKit/LayoutTests/virtual/spv175/paint/invalidation/svg/js-late-mask-and-object-creation-expected.txt +++ b/third_party/WebKit/LayoutTests/virtual/spv175/paint/invalidation/svg/js-late-mask-and-object-creation-expected.txt
@@ -50,7 +50,7 @@ }, { "object": "LayoutSVGRect rect", - "reason": "style change" + "reason": "full" } ] }
diff --git a/third_party/WebKit/LayoutTests/virtual/spv175/paint/invalidation/svg/js-late-mask-creation-expected.txt b/third_party/WebKit/LayoutTests/virtual/spv175/paint/invalidation/svg/js-late-mask-creation-expected.txt index 29e43ef..ef536ce 100644 --- a/third_party/WebKit/LayoutTests/virtual/spv175/paint/invalidation/svg/js-late-mask-creation-expected.txt +++ b/third_party/WebKit/LayoutTests/virtual/spv175/paint/invalidation/svg/js-late-mask-creation-expected.txt
@@ -37,7 +37,7 @@ "objectPaintInvalidations": [ { "object": "LayoutSVGRect rect", - "reason": "style change" + "reason": "full" } ] }
diff --git a/third_party/WebKit/LayoutTests/virtual/spv175/paint/invalidation/svg/js-late-pattern-creation-expected.txt b/third_party/WebKit/LayoutTests/virtual/spv175/paint/invalidation/svg/js-late-pattern-creation-expected.txt index 4451434..064a88a5 100644 --- a/third_party/WebKit/LayoutTests/virtual/spv175/paint/invalidation/svg/js-late-pattern-creation-expected.txt +++ b/third_party/WebKit/LayoutTests/virtual/spv175/paint/invalidation/svg/js-late-pattern-creation-expected.txt
@@ -27,11 +27,11 @@ "objectPaintInvalidations": [ { "object": "LayoutSVGText text", - "reason": "style change" + "reason": "full" }, { "object": "RootInlineBox", - "reason": "style change" + "reason": "full" }, { "object": "LayoutSVGInlineText #text",
diff --git a/third_party/WebKit/Source/BUILD.gn b/third_party/WebKit/Source/BUILD.gn index b029620..1e970fa 100644 --- a/third_party/WebKit/Source/BUILD.gn +++ b/third_party/WebKit/Source/BUILD.gn
@@ -24,6 +24,10 @@ # a class has an empty destructor which would be unnecessarily invoked # when finalized. blink_gc_plugin_option_warn_unneeded_finalizer = false + + # Set to true to have the clang Blink GC plugin additionally check if a + # TraceWrappers method also dispatches to all its base classes. + blink_gc_plugin_option_warn_trace_wrappers_missing_base_dispatch = false } # features --------------------------------------------------------------------- @@ -140,6 +144,14 @@ "warn-unneeded-finalizer", ] } + if (blink_gc_plugin_option_warn_trace_wrappers_missing_base_dispatch) { + cflags += [ + "-Xclang", + "-plugin-arg-blink-gc-plugin", + "-Xclang", + "warn_trace_wrappers_missing_base_dispatch", + ] + } } }
diff --git a/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorldTest.cpp b/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorldTest.cpp index eacb6d5..4365830 100644 --- a/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorldTest.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/DOMWrapperWorldTest.cpp
@@ -116,8 +116,8 @@ retrieved_worlds.clear(); // Start a worker thread and create worlds on that. - std::unique_ptr<WorkerBackingThread> thread = - WorkerBackingThread::Create("DOMWrapperWorld test thread"); + std::unique_ptr<WorkerBackingThread> thread = WorkerBackingThread::Create( + WebThreadCreationParams("DOMWrapperWorld test thread")); scoped_refptr<WebTaskRunner> main_thread_task_runner = Platform::Current()->CurrentThread()->GetWebTaskRunner(); thread->BackingThread().PostTask(
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptController.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptController.cpp index c4e7f6a..b2dd852 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ScriptController.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptController.cpp
@@ -134,12 +134,20 @@ v8::Local<v8::Script> script; + v8::ScriptCompiler::CompileOptions compile_options; + V8ScriptRunner::ProduceCacheOptions produce_cache_options; + v8::ScriptCompiler::NoCacheReason no_cache_reason; + std::tie(compile_options, produce_cache_options, no_cache_reason) = + V8ScriptRunner::GetCompileOptions(v8_cache_options, source); if (!V8ScriptRunner::CompileScript(ScriptState::From(context), source, - access_control_status, v8_cache_options, - referrer_info) + access_control_status, compile_options, + no_cache_reason, referrer_info) .ToLocal(&script)) return result; + V8ScriptRunner::ProduceCache(GetIsolate(), script, source, + produce_cache_options, compile_options); + if (!V8ScriptRunner::RunCompiledScript(GetIsolate(), script, GetFrame()->GetDocument()) .ToLocal(&result))
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptStreamerTest.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptStreamerTest.cpp index 812faca2..5ea1e01e 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ScriptStreamerTest.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptStreamerTest.cpp
@@ -167,9 +167,14 @@ EXPECT_TRUE(source_code.Streamer()); v8::TryCatch try_catch(scope.GetIsolate()); v8::Local<v8::Script> script; + v8::ScriptCompiler::CompileOptions compile_options; + V8ScriptRunner::ProduceCacheOptions produce_cache_options; + v8::ScriptCompiler::NoCacheReason no_cache_reason; + std::tie(compile_options, produce_cache_options, no_cache_reason) = + V8ScriptRunner::GetCompileOptions(kV8CacheOptionsDefault, source_code); EXPECT_TRUE(V8ScriptRunner::CompileScript( scope.GetScriptState(), source_code, kSharableCrossOrigin, - kV8CacheOptionsDefault, ReferrerScriptInfo()) + compile_options, no_cache_reason, ReferrerScriptInfo()) .ToLocal(&script)); EXPECT_FALSE(try_catch.HasCaught()); } @@ -207,9 +212,14 @@ EXPECT_TRUE(source_code.Streamer()); v8::TryCatch try_catch(scope.GetIsolate()); v8::Local<v8::Script> script; + v8::ScriptCompiler::CompileOptions compile_options; + V8ScriptRunner::ProduceCacheOptions produce_cache_options; + v8::ScriptCompiler::NoCacheReason no_cache_reason; + std::tie(compile_options, produce_cache_options, no_cache_reason) = + V8ScriptRunner::GetCompileOptions(kV8CacheOptionsDefault, source_code); EXPECT_FALSE(V8ScriptRunner::CompileScript( scope.GetScriptState(), source_code, kSharableCrossOrigin, - kV8CacheOptionsDefault, ReferrerScriptInfo()) + compile_options, no_cache_reason, ReferrerScriptInfo()) .ToLocal(&script)); EXPECT_TRUE(try_catch.HasCaught()); } @@ -359,9 +369,14 @@ EXPECT_TRUE(source_code.Streamer()); v8::TryCatch try_catch(scope.GetIsolate()); v8::Local<v8::Script> script; + v8::ScriptCompiler::CompileOptions compile_options; + V8ScriptRunner::ProduceCacheOptions produce_cache_options; + v8::ScriptCompiler::NoCacheReason no_cache_reason; + std::tie(compile_options, produce_cache_options, no_cache_reason) = + V8ScriptRunner::GetCompileOptions(kV8CacheOptionsDefault, source_code); EXPECT_TRUE(V8ScriptRunner::CompileScript( scope.GetScriptState(), source_code, kSharableCrossOrigin, - kV8CacheOptionsDefault, ReferrerScriptInfo()) + compile_options, no_cache_reason, ReferrerScriptInfo()) .ToLocal(&script)); EXPECT_FALSE(try_catch.HasCaught()); } @@ -396,9 +411,14 @@ EXPECT_TRUE(source_code.Streamer()); v8::TryCatch try_catch(scope.GetIsolate()); v8::Local<v8::Script> script; + v8::ScriptCompiler::CompileOptions compile_options; + V8ScriptRunner::ProduceCacheOptions produce_cache_options; + v8::ScriptCompiler::NoCacheReason no_cache_reason; + std::tie(compile_options, produce_cache_options, no_cache_reason) = + V8ScriptRunner::GetCompileOptions(kV8CacheOptionsDefault, source_code); EXPECT_TRUE(V8ScriptRunner::CompileScript( scope.GetScriptState(), source_code, kSharableCrossOrigin, - kV8CacheOptionsDefault, ReferrerScriptInfo()) + compile_options, no_cache_reason, ReferrerScriptInfo()) .ToLocal(&script)); EXPECT_FALSE(try_catch.HasCaught()); } @@ -434,9 +454,14 @@ EXPECT_TRUE(source_code.Streamer()); v8::TryCatch try_catch(scope.GetIsolate()); v8::Local<v8::Script> script; + v8::ScriptCompiler::CompileOptions compile_options; + V8ScriptRunner::ProduceCacheOptions produce_cache_options; + v8::ScriptCompiler::NoCacheReason no_cache_reason; + std::tie(compile_options, produce_cache_options, no_cache_reason) = + V8ScriptRunner::GetCompileOptions(kV8CacheOptionsDefault, source_code); EXPECT_TRUE(V8ScriptRunner::CompileScript( scope.GetScriptState(), source_code, kSharableCrossOrigin, - kV8CacheOptionsDefault, ReferrerScriptInfo()) + compile_options, no_cache_reason, ReferrerScriptInfo()) .ToLocal(&script)); EXPECT_FALSE(try_catch.HasCaught()); }
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptStreamerThread.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptStreamerThread.cpp index 309535d0..5b8f5c50 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ScriptStreamerThread.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptStreamerThread.cpp
@@ -50,7 +50,8 @@ WebThread& ScriptStreamerThread::PlatformThread() { if (!IsRunning()) { - thread_ = Platform::Current()->CreateThread("ScriptStreamerThread"); + thread_ = Platform::Current()->CreateThread( + WebThreadCreationParams("ScriptStreamerThread")); } return *thread_; }
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitorTest.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitorTest.cpp index aa9b6dc..0671710 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitorTest.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitorTest.cpp
@@ -35,10 +35,12 @@ return false; } -TEST(ScriptWrappableVisitorTest, ScriptWrappableVisitorTracesWrappers) { +TEST(ScriptWrappableMarkingVisitorTest, + ScriptWrappableMarkingVisitorTracesWrappers) { V8TestingScope scope; - ScriptWrappableVisitor* visitor = - V8PerIsolateData::From(scope.GetIsolate())->GetScriptWrappableVisitor(); + ScriptWrappableMarkingVisitor* visitor = + V8PerIsolateData::From(scope.GetIsolate()) + ->GetScriptWrappableMarkingVisitor(); DeathAwareScriptWrappable* target = DeathAwareScriptWrappable::Create(); DeathAwareScriptWrappable* dependency = DeathAwareScriptWrappable::Create(); target->SetWrappedDependency(dependency); @@ -70,7 +72,8 @@ visitor->AbortTracing(); } -TEST(ScriptWrappableVisitorTest, OilpanCollectObjectsNotReachableFromV8) { +TEST(ScriptWrappableMarkingVisitorTest, + OilpanCollectObjectsNotReachableFromV8) { V8TestingScope scope; v8::Isolate* isolate = scope.GetIsolate(); @@ -90,7 +93,8 @@ EXPECT_TRUE(DeathAwareScriptWrappable::HasDied()); } -TEST(ScriptWrappableVisitorTest, OilpanDoesntCollectObjectsReachableFromV8) { +TEST(ScriptWrappableMarkingVisitorTest, + OilpanDoesntCollectObjectsReachableFromV8) { V8TestingScope scope; v8::Isolate* isolate = scope.GetIsolate(); v8::HandleScope handle_scope(isolate); @@ -107,7 +111,7 @@ EXPECT_FALSE(DeathAwareScriptWrappable::HasDied()); } -TEST(ScriptWrappableVisitorTest, V8ReportsLiveObjectsDuringScavenger) { +TEST(ScriptWrappableMarkingVisitorTest, V8ReportsLiveObjectsDuringScavenger) { V8TestingScope scope; v8::Isolate* isolate = scope.GetIsolate(); v8::HandleScope handle_scope(isolate); @@ -130,7 +134,7 @@ EXPECT_FALSE(DeathAwareScriptWrappable::HasDied()); } -TEST(ScriptWrappableVisitorTest, V8ReportsLiveObjectsDuringFullGc) { +TEST(ScriptWrappableMarkingVisitorTest, V8ReportsLiveObjectsDuringFullGc) { V8TestingScope scope; v8::Isolate* isolate = scope.GetIsolate(); v8::HandleScope handle_scope(isolate); @@ -146,12 +150,13 @@ EXPECT_FALSE(DeathAwareScriptWrappable::HasDied()); } -TEST(ScriptWrappableVisitorTest, OilpanClearsHeadersWhenObjectDied) { +TEST(ScriptWrappableMarkingVisitorTest, OilpanClearsHeadersWhenObjectDied) { V8TestingScope scope; DeathAwareScriptWrappable* object = DeathAwareScriptWrappable::Create(); - ScriptWrappableVisitor* visitor = - V8PerIsolateData::From(scope.GetIsolate())->GetScriptWrappableVisitor(); + ScriptWrappableMarkingVisitor* visitor = + V8PerIsolateData::From(scope.GetIsolate()) + ->GetScriptWrappableMarkingVisitor(); visitor->TracePrologue(); auto header = HeapObjectHeader::FromPayload(object); visitor->HeadersToUnmark()->push_back(header); @@ -162,12 +167,14 @@ visitor->AbortTracing(); } -TEST(ScriptWrappableVisitorTest, OilpanClearsMarkingDequeWhenObjectDied) { +TEST(ScriptWrappableMarkingVisitorTest, + OilpanClearsMarkingDequeWhenObjectDied) { V8TestingScope scope; DeathAwareScriptWrappable* object = DeathAwareScriptWrappable::Create(); - ScriptWrappableVisitor* visitor = - V8PerIsolateData::From(scope.GetIsolate())->GetScriptWrappableVisitor(); + ScriptWrappableMarkingVisitor* visitor = + V8PerIsolateData::From(scope.GetIsolate()) + ->GetScriptWrappableMarkingVisitor(); visitor->TracePrologue(); visitor->TraceWrappersWithManualWriteBarrier(object); @@ -181,12 +188,13 @@ visitor->AbortTracing(); } -TEST(ScriptWrappableVisitorTest, +TEST(ScriptWrappableMarkingVisitorTest, MarkedObjectDoesNothingOnWriteBarrierHitWhenDependencyIsMarkedToo) { V8TestingScope scope; - ScriptWrappableVisitor* visitor = - V8PerIsolateData::From(scope.GetIsolate())->GetScriptWrappableVisitor(); + ScriptWrappableMarkingVisitor* visitor = + V8PerIsolateData::From(scope.GetIsolate()) + ->GetScriptWrappableMarkingVisitor(); visitor->TracePrologue(); DeathAwareScriptWrappable* target = DeathAwareScriptWrappable::Create(); @@ -209,12 +217,13 @@ visitor->AbortTracing(); } -TEST(ScriptWrappableVisitorTest, +TEST(ScriptWrappableMarkingVisitorTest, MarkedObjectMarksDependencyOnWriteBarrierHitWhenNotMarked) { V8TestingScope scope; - ScriptWrappableVisitor* visitor = - V8PerIsolateData::From(scope.GetIsolate())->GetScriptWrappableVisitor(); + ScriptWrappableMarkingVisitor* visitor = + V8PerIsolateData::From(scope.GetIsolate()) + ->GetScriptWrappableMarkingVisitor(); visitor->TracePrologue(); DeathAwareScriptWrappable* target = DeathAwareScriptWrappable::Create(); @@ -261,12 +270,13 @@ TraceWrapperV8Reference<v8::String> handle_; }; -class InterceptingScriptWrappableVisitor - : public blink::ScriptWrappableVisitor { +class InterceptingScriptWrappableMarkingVisitor + : public blink::ScriptWrappableMarkingVisitor { public: - InterceptingScriptWrappableVisitor(v8::Isolate* isolate) - : ScriptWrappableVisitor(isolate), marked_wrappers_(new size_t(0)) {} - ~InterceptingScriptWrappableVisitor() { delete marked_wrappers_; } + InterceptingScriptWrappableMarkingVisitor(v8::Isolate* isolate) + : ScriptWrappableMarkingVisitor(isolate), + marked_wrappers_(new size_t(0)) {} + ~InterceptingScriptWrappableMarkingVisitor() { delete marked_wrappers_; } void Visit(const TraceWrapperV8Reference<v8::Value>&) const override { *marked_wrappers_ += 1; @@ -291,33 +301,36 @@ size_t* marked_wrappers_; // Indirection required because of const override. }; -class InterceptingScriptWrappableVisitorScope +class InterceptingScriptWrappableMarkingVisitorScope : public V8PerIsolateData::TemporaryScriptWrappableVisitorScope { - WTF_MAKE_NONCOPYABLE(InterceptingScriptWrappableVisitorScope); + WTF_MAKE_NONCOPYABLE(InterceptingScriptWrappableMarkingVisitorScope); STACK_ALLOCATED(); public: - InterceptingScriptWrappableVisitorScope(v8::Isolate* isolate) + InterceptingScriptWrappableMarkingVisitorScope(v8::Isolate* isolate) : V8PerIsolateData::TemporaryScriptWrappableVisitorScope( isolate, - std::unique_ptr<InterceptingScriptWrappableVisitor>( - new InterceptingScriptWrappableVisitor(isolate))) { + std::unique_ptr<InterceptingScriptWrappableMarkingVisitor>( + new InterceptingScriptWrappableMarkingVisitor(isolate))) { Visitor()->Start(); } - virtual ~InterceptingScriptWrappableVisitorScope() { Visitor()->end(); } + virtual ~InterceptingScriptWrappableMarkingVisitorScope() { + Visitor()->end(); + } - InterceptingScriptWrappableVisitor* Visitor() { - return reinterpret_cast<InterceptingScriptWrappableVisitor*>( + InterceptingScriptWrappableMarkingVisitor* Visitor() { + return reinterpret_cast<InterceptingScriptWrappableMarkingVisitor*>( CurrentVisitor()); } }; } // namespace -TEST(ScriptWrappableVisitorTest, WriteBarrierOnUnmarkedContainer) { +TEST(ScriptWrappableMarkingVisitorTest, WriteBarrierOnUnmarkedContainer) { V8TestingScope scope; - InterceptingScriptWrappableVisitorScope visitor_scope(scope.GetIsolate()); + InterceptingScriptWrappableMarkingVisitorScope visitor_scope( + scope.GetIsolate()); auto* raw_visitor = visitor_scope.Visitor(); v8::Local<v8::String> str = @@ -332,9 +345,10 @@ CHECK_EQ(1u, raw_visitor->NumberOfMarkedWrappers()); } -TEST(ScriptWrappableVisitorTest, WriteBarrierTriggersOnMarkedContainer) { +TEST(ScriptWrappableMarkingVisitorTest, WriteBarrierTriggersOnMarkedContainer) { V8TestingScope scope; - InterceptingScriptWrappableVisitorScope visitor_scope(scope.GetIsolate()); + InterceptingScriptWrappableMarkingVisitorScope visitor_scope( + scope.GetIsolate()); auto* raw_visitor = visitor_scope.Visitor(); v8::Local<v8::String> str = @@ -348,23 +362,24 @@ CHECK_EQ(1u, raw_visitor->NumberOfMarkedWrappers()); } -TEST(ScriptWrappableVisitorTest, VtableAtObjectStart) { +TEST(ScriptWrappableMarkingVisitorTest, VtableAtObjectStart) { // This test makes sure that the subobject v8::EmbedderHeapTracer is placed - // at the start of a ScriptWrappableVisitor object. We do this to mitigate - // potential problems that could be caused by LTO when passing + // at the start of a ScriptWrappableMarkingVisitor object. We do this to + // mitigate potential problems that could be caused by LTO when passing // v8::EmbedderHeapTracer across the API boundary. V8TestingScope scope; - std::unique_ptr<blink::ScriptWrappableVisitor> visitor( - new ScriptWrappableVisitor(scope.GetIsolate())); + std::unique_ptr<blink::ScriptWrappableMarkingVisitor> visitor( + new ScriptWrappableMarkingVisitor(scope.GetIsolate())); CHECK_EQ( static_cast<void*>(visitor.get()), static_cast<void*>(dynamic_cast<v8::EmbedderHeapTracer*>(visitor.get()))); } -TEST(ScriptWrappableVisitor, WriteBarrierForScriptWrappable) { +TEST(ScriptWrappableMarkingVisitor, WriteBarrierForScriptWrappable) { // Regression test for crbug.com/702490. V8TestingScope scope; - InterceptingScriptWrappableVisitorScope visitor_scope(scope.GetIsolate()); + InterceptingScriptWrappableMarkingVisitorScope visitor_scope( + scope.GetIsolate()); auto* raw_visitor = visitor_scope.Visitor(); // Mark the ScriptWrappable. @@ -385,10 +400,11 @@ CHECK_EQ(1u, raw_visitor->NumberOfMarkedWrappers()); } -TEST(ScriptWrappableVisitorTest, WriteBarrierOnHeapVectorSwap1) { +TEST(ScriptWrappableMarkingVisitorTest, WriteBarrierOnHeapVectorSwap1) { V8TestingScope scope; - ScriptWrappableVisitor* visitor = - V8PerIsolateData::From(scope.GetIsolate())->GetScriptWrappableVisitor(); + ScriptWrappableMarkingVisitor* visitor = + V8PerIsolateData::From(scope.GetIsolate()) + ->GetScriptWrappableMarkingVisitor(); HeapVector<DeathAwareScriptWrappable::Wrapper> vector1; DeathAwareScriptWrappable* entry1 = DeathAwareScriptWrappable::Create(); @@ -408,10 +424,11 @@ visitor->AbortTracing(); } -TEST(ScriptWrappableVisitorTest, WriteBarrierOnHeapVectorSwap2) { +TEST(ScriptWrappableMarkingVisitorTest, WriteBarrierOnHeapVectorSwap2) { V8TestingScope scope; - ScriptWrappableVisitor* visitor = - V8PerIsolateData::From(scope.GetIsolate())->GetScriptWrappableVisitor(); + ScriptWrappableMarkingVisitor* visitor = + V8PerIsolateData::From(scope.GetIsolate()) + ->GetScriptWrappableMarkingVisitor(); HeapVector<DeathAwareScriptWrappable::Wrapper> vector1; DeathAwareScriptWrappable* entry1 = DeathAwareScriptWrappable::Create(); @@ -482,10 +499,11 @@ } // namespace -TEST(ScriptWrappableVisitorTest, MixinTracing) { +TEST(ScriptWrappableMarkingVisitorTest, MixinTracing) { V8TestingScope scope; - ScriptWrappableVisitor* visitor = - V8PerIsolateData::From(scope.GetIsolate())->GetScriptWrappableVisitor(); + ScriptWrappableMarkingVisitor* visitor = + V8PerIsolateData::From(scope.GetIsolate()) + ->GetScriptWrappableMarkingVisitor(); DeathAwareScriptWrappable* base_wrapper = DeathAwareScriptWrappable::Create(); DeathAwareScriptWrappable* mixin_wrapper =
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8GCController.cpp b/third_party/WebKit/Source/bindings/core/v8/V8GCController.cpp index 0b6b84d..d790900 100644 --- a/third_party/WebKit/Source/bindings/core/v8/V8GCController.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/V8GCController.cpp
@@ -123,11 +123,13 @@ v8::Isolate* isolate_; }; -class HeapSnaphotWrapperVisitor : public ScriptWrappableVisitor, +// TODO(ulan): Refactor this class to derive from ScriptWrappableVisitor +// and not rely on marking infrastructure. +class HeapSnaphotWrapperVisitor : public ScriptWrappableMarkingVisitor, public v8::PersistentHandleVisitor { public: explicit HeapSnaphotWrapperVisitor(v8::Isolate* isolate) - : ScriptWrappableVisitor(isolate), + : ScriptWrappableMarkingVisitor(isolate), current_parent_(nullptr), only_trace_single_level_(false), first_script_wrappable_traced_(false) {
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8Initializer.cpp b/third_party/WebKit/Source/bindings/core/v8/V8Initializer.cpp index c5a1ecc..5a26332 100644 --- a/third_party/WebKit/Source/bindings/core/v8/V8Initializer.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/V8Initializer.cpp
@@ -515,12 +515,12 @@ static void InitializeV8Common(v8::Isolate* isolate) { isolate->AddGCPrologueCallback(V8GCController::GcPrologue); isolate->AddGCEpilogueCallback(V8GCController::GcEpilogue); - std::unique_ptr<ScriptWrappableVisitor> visitor( - new ScriptWrappableVisitor(isolate)); - V8PerIsolateData::From(isolate)->SetScriptWrappableVisitor( + std::unique_ptr<ScriptWrappableMarkingVisitor> visitor( + new ScriptWrappableMarkingVisitor(isolate)); + V8PerIsolateData::From(isolate)->SetScriptWrappableMarkingVisitor( std::move(visitor)); isolate->SetEmbedderHeapTracer( - V8PerIsolateData::From(isolate)->GetScriptWrappableVisitor()); + V8PerIsolateData::From(isolate)->GetScriptWrappableMarkingVisitor()); isolate->SetMicrotasksPolicy(v8::MicrotasksPolicy::kScoped); @@ -679,8 +679,8 @@ DCHECK(ThreadState::MainThreadState()); ThreadState::MainThreadState()->RegisterTraceDOMWrappers( isolate, V8GCController::TraceDOMWrappers, - ScriptWrappableVisitor::InvalidateDeadObjectsInMarkingDeque, - ScriptWrappableVisitor::PerformCleanup); + ScriptWrappableMarkingVisitor::InvalidateDeadObjectsInMarkingDeque, + ScriptWrappableMarkingVisitor::PerformCleanup); V8PerIsolateData::From(isolate)->SetThreadDebugger( std::make_unique<MainThreadDebugger>(isolate));
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8ScriptRunner.cpp b/third_party/WebKit/Source/bindings/core/v8/V8ScriptRunner.cpp index add5cc7..7af2beb 100644 --- a/third_party/WebKit/Source/bindings/core/v8/V8ScriptRunner.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/V8ScriptRunner.cpp
@@ -112,6 +112,19 @@ no_cache_reason); } +// Compile a script eagerly so that we can produce full code cache. +v8::MaybeLocal<v8::Script> CompileEager( + v8::ScriptCompiler::NoCacheReason no_cache_reason, + v8::Isolate* isolate, + v8::Local<v8::String> code, + v8::ScriptOrigin origin, + InspectorCompileScriptEvent::V8CacheResult*) { + v8::ScriptCompiler::Source source(code, origin); + return v8::ScriptCompiler::Compile(isolate->GetCurrentContext(), &source, + v8::ScriptCompiler::kEagerCompile, + no_cache_reason); +} + // Compile a script, and consume a V8 cache that was generated previously. static v8::MaybeLocal<v8::Script> CompileAndConsumeCache( CachedMetadataHandler* cache_handler, @@ -152,9 +165,10 @@ v8::Local<v8::String> code, v8::ScriptOrigin origin, InspectorCompileScriptEvent::V8CacheResult* cache_result) { - DCHECK(produce_options == v8::ScriptCompiler::kProduceParserCache || - produce_options == v8::ScriptCompiler::kProduceCodeCache || - produce_options == v8::ScriptCompiler::kProduceFullCodeCache); + // TODO(crbug.com/783124): We want to remove the support for producing + // parser cache soon. This function should be removed once the support + // for parser cache is removed. + DCHECK_EQ(produce_options, v8::ScriptCompiler::kProduceParserCache); v8::ScriptCompiler::Source source(code, origin); v8::MaybeLocal<v8::Script> script = v8::ScriptCompiler::Compile( isolate->GetCurrentContext(), &source, produce_options); @@ -210,9 +224,9 @@ bool IsResourceHotForCaching(CachedMetadataHandler* cache_handler, int hot_hours) { const double cache_within_seconds = hot_hours * 60 * 60; - uint32_t tag = CacheTag(kCacheTagTimeStamp, cache_handler->Encoding()); scoped_refptr<CachedMetadata> cached_metadata = - cache_handler->GetCachedMetadata(tag); + cache_handler->GetCachedMetadata( + V8ScriptRunner::TagForTimeStamp(cache_handler)); if (!cached_metadata) return false; double time_stamp; @@ -225,7 +239,7 @@ // Final compile call for a streamed compilation. Most decisions have already // been made, but we need to write back data into the cache. v8::MaybeLocal<v8::Script> PostStreamCompile( - V8CacheOptions cache_options, + v8::ScriptCompiler::CompileOptions compile_options, CachedMetadataHandler* cache_handler, ScriptStreamer* streamer, v8::Isolate* isolate, @@ -241,8 +255,8 @@ // If the non-streaming compiler uses the parser cache, retrieve and store // the cache data. If the code cache uses time stamp as heuristic, set that // time stamp. - switch (cache_options) { - case kV8CacheOptionsParse: { + switch (compile_options) { + case v8::ScriptCompiler::kProduceParserCache: { const v8::ScriptCompiler::CachedData* new_cached_data = streamer->Source()->GetCachedData(); if (!new_cached_data) @@ -263,17 +277,15 @@ break; } - case kV8CacheOptionsDefault: - case kV8CacheOptionsCode: - V8ScriptRunner::SetCacheTimeStamp(cache_handler); + case v8::ScriptCompiler::kConsumeParserCache: + case v8::ScriptCompiler::kConsumeCodeCache: + case v8::ScriptCompiler::kNoCompileOptions: + case v8::ScriptCompiler::kEagerCompile: break; - case kV8CacheOptionsCodeWithoutHeatCheck: - case kV8CacheOptionsFullCodeWithoutHeatCheck: - // Currently WithoutHeatCheck doesn't support streaming. + case v8::ScriptCompiler::kProduceCodeCache: + case v8::ScriptCompiler::kProduceFullCodeCache: NOTREACHED(); - case kV8CacheOptionsNone: - break; } return script; } @@ -285,80 +297,159 @@ InspectorCompileScriptEvent::V8CacheResult*)> CompileFn; -// Select a compile function from any of the above, mainly depending on -// cacheOptions. +// Select a compile function from any of the above depending on compile_options. static CompileFn SelectCompileFunction( - V8CacheOptions cache_options, + v8::ScriptCompiler::CompileOptions compile_options, CachedMetadataHandler* cache_handler, - v8::Local<v8::String> code, - v8::ScriptCompiler::NoCacheReason no_handler_reason) { - static const int kMinimalCodeLength = 1024; - static const int kHotHours = 72; - - // Caching is not available in this case. - if (!cache_handler) { - return WTF::Bind(CompileWithoutOptions, no_handler_reason); - } - - if (cache_options == kV8CacheOptionsNone) { - return WTF::Bind(CompileWithoutOptions, - v8::ScriptCompiler::kNoCacheBecauseCachingDisabled); - } - - // Caching is not worthwhile for small scripts. Do not use caching - // unless explicitly expected, indicated by the cache option. - if (code->Length() < kMinimalCodeLength) { - return WTF::Bind(CompileWithoutOptions, - v8::ScriptCompiler::kNoCacheBecauseScriptTooSmall); - } - - // The cacheOptions will guide our strategy: - switch (cache_options) { - case kV8CacheOptionsParse: { - // Use parser-cache; in-memory only. + v8::ScriptCompiler::NoCacheReason no_cache_reason) { + switch (compile_options) { + case v8::ScriptCompiler::kNoCompileOptions: + return WTF::Bind(CompileWithoutOptions, no_cache_reason); + case v8::ScriptCompiler::kEagerCompile: + return WTF::Bind(CompileEager, no_cache_reason); + case v8::ScriptCompiler::kProduceParserCache: { uint32_t parser_tag = V8ScriptRunner::TagForParserCache(cache_handler); - scoped_refptr<CachedMetadata> parser_cache( - cache_handler->GetCachedMetadata(parser_tag)); - if (parser_cache) { - return WTF::Bind(CompileAndConsumeCache, WrapPersistent(cache_handler), - std::move(parser_cache), - v8::ScriptCompiler::kConsumeParserCache); - } return WTF::Bind(CompileAndProduceCache, WrapPersistent(cache_handler), parser_tag, v8::ScriptCompiler::kProduceParserCache, CachedMetadataHandler::kCacheLocally); } + case v8::ScriptCompiler::kConsumeParserCache: { + // Use parser-cache; in-memory only. + uint32_t parser_tag = V8ScriptRunner::TagForParserCache(cache_handler); + scoped_refptr<CachedMetadata> parser_cache( + cache_handler->GetCachedMetadata(parser_tag)); + DCHECK(parser_cache); + return WTF::Bind(CompileAndConsumeCache, WrapPersistent(cache_handler), + std::move(parser_cache), + v8::ScriptCompiler::kConsumeParserCache); + } + case v8::ScriptCompiler::kConsumeCodeCache: { + uint32_t code_cache_tag = V8ScriptRunner::TagForCodeCache(cache_handler); + scoped_refptr<CachedMetadata> code_cache = + cache_handler->GetCachedMetadata(code_cache_tag); + DCHECK(code_cache); + return WTF::Bind(CompileAndConsumeCache, WrapPersistent(cache_handler), + std::move(code_cache), + v8::ScriptCompiler::kConsumeCodeCache); + } + case v8::ScriptCompiler::kProduceCodeCache: + case v8::ScriptCompiler::kProduceFullCodeCache: + NOTREACHED(); + } + // All switch branches should return and we should never get here. + // But some compilers aren't sure, hence this default. + NOTREACHED(); + return WTF::Bind(CompileWithoutOptions, v8::ScriptCompiler::kNoCacheNoReason); +} + +// Select a compile function for a streaming compile. +CompileFn SelectCompileFunction( + v8::ScriptCompiler::CompileOptions compile_options, + CachedMetadataHandler* cache_handler, + ScriptStreamer* streamer) { + DCHECK(streamer->IsFinished()); + DCHECK(!streamer->StreamingSuppressed()); + + // Streaming compilation may involve use of code cache. + // TODO(leszeks): Add compile timer to streaming compilation. + return WTF::Bind(PostStreamCompile, compile_options, + WrapPersistent(cache_handler), WrapPersistent(streamer)); +} +} // namespace + +std::tuple<v8::ScriptCompiler::CompileOptions, + V8ScriptRunner::ProduceCacheOptions, + v8::ScriptCompiler::NoCacheReason> +V8ScriptRunner::GetCompileOptions(V8CacheOptions cache_options, + const ScriptSourceCode& source) { + static const int kMinimalCodeLength = 1024; + static const int kHotHours = 72; + v8::ScriptCompiler::NoCacheReason no_cache_reason; + + switch (source.SourceLocationType()) { + case ScriptSourceLocationType::kInline: + no_cache_reason = v8::ScriptCompiler::kNoCacheBecauseInlineScript; + break; + case ScriptSourceLocationType::kInlineInsideDocumentWrite: + no_cache_reason = v8::ScriptCompiler::kNoCacheBecauseInDocumentWrite; + break; + case ScriptSourceLocationType::kExternalFile: + no_cache_reason = + v8::ScriptCompiler::kNoCacheBecauseResourceWithNoCacheHandler; + break; + // TODO(leszeks): Possibly differentiate between the other kinds of script + // origin also. + default: + no_cache_reason = v8::ScriptCompiler::kNoCacheBecauseNoResource; + break; + } + + CachedMetadataHandler* cache_handler = source.CacheHandler(); + if (!cache_handler) { + return std::make_tuple(v8::ScriptCompiler::kNoCompileOptions, + ProduceCacheOptions::kNoProduceCache, + no_cache_reason); + } + + if (cache_options == kV8CacheOptionsNone) { + no_cache_reason = v8::ScriptCompiler::kNoCacheBecauseCachingDisabled; + return std::make_tuple(v8::ScriptCompiler::kNoCompileOptions, + ProduceCacheOptions::kNoProduceCache, + no_cache_reason); + } + + if (source.Source().length() < kMinimalCodeLength) { + no_cache_reason = v8::ScriptCompiler::kNoCacheBecauseScriptTooSmall; + return std::make_tuple(v8::ScriptCompiler::kNoCompileOptions, + ProduceCacheOptions::kNoProduceCache, + no_cache_reason); + } + + switch (cache_options) { + case kV8CacheOptionsParse: { + uint32_t parser_tag = V8ScriptRunner::TagForParserCache(cache_handler); + scoped_refptr<CachedMetadata> parser_cache( + cache_handler->GetCachedMetadata(parser_tag)); + if (parser_cache) { + return std::make_tuple(v8::ScriptCompiler::kConsumeParserCache, + ProduceCacheOptions::kNoProduceCache, + no_cache_reason); + } + return std::make_tuple(v8::ScriptCompiler::kProduceParserCache, + ProduceCacheOptions::kNoProduceCache, + no_cache_reason); + } case kV8CacheOptionsDefault: case kV8CacheOptionsCode: case kV8CacheOptionsCodeWithoutHeatCheck: case kV8CacheOptionsFullCodeWithoutHeatCheck: { uint32_t code_cache_tag = V8ScriptRunner::TagForCodeCache(cache_handler); - // Use code caching for recently seen resources. - // Use compression depending on the cache option. scoped_refptr<CachedMetadata> code_cache = cache_handler->GetCachedMetadata(code_cache_tag); if (code_cache) { - return WTF::Bind(CompileAndConsumeCache, WrapPersistent(cache_handler), - std::move(code_cache), - v8::ScriptCompiler::kConsumeCodeCache); + return std::make_tuple(v8::ScriptCompiler::kConsumeCodeCache, + ProduceCacheOptions::kNoProduceCache, + no_cache_reason); } if (cache_options != kV8CacheOptionsCodeWithoutHeatCheck && cache_options != kV8CacheOptionsFullCodeWithoutHeatCheck && !IsResourceHotForCaching(cache_handler, kHotHours)) { - V8ScriptRunner::SetCacheTimeStamp(cache_handler); - return WTF::Bind(CompileWithoutOptions, - v8::ScriptCompiler::kNoCacheBecauseCacheTooCold); + return std::make_tuple(v8::ScriptCompiler::kNoCompileOptions, + ProduceCacheOptions::kSetTimeStamp, + v8::ScriptCompiler::kNoCacheBecauseCacheTooCold); } - return WTF::Bind( - CompileAndProduceCache, WrapPersistent(cache_handler), code_cache_tag, - (cache_options == kV8CacheOptionsFullCodeWithoutHeatCheck) - ? v8::ScriptCompiler::kProduceFullCodeCache - : v8::ScriptCompiler::kProduceCodeCache, - CachedMetadataHandler::kSendToPlatform); - break; + if (cache_options == kV8CacheOptionsFullCodeWithoutHeatCheck) { + return std::make_tuple( + v8::ScriptCompiler::kEagerCompile, + ProduceCacheOptions::kProduceCodeCache, + v8::ScriptCompiler::kNoCacheBecauseDeferredProduceCodeCache); + } + return std::make_tuple( + v8::ScriptCompiler::kNoCompileOptions, + ProduceCacheOptions::kProduceCodeCache, + v8::ScriptCompiler::kNoCacheBecauseDeferredProduceCodeCache); } - case kV8CacheOptionsNone: // Shouldn't happen, as this is handled above. // Case is here so that compiler can check all cases are handled. @@ -369,28 +460,17 @@ // All switch branches should return and we should never get here. // But some compilers aren't sure, hence this default. NOTREACHED(); - return WTF::Bind(CompileWithoutOptions, v8::ScriptCompiler::kNoCacheNoReason); + return std::make_tuple(v8::ScriptCompiler::kNoCompileOptions, + ProduceCacheOptions::kNoProduceCache, + v8::ScriptCompiler::kNoCacheNoReason); } -// Select a compile function for a streaming compile. -CompileFn SelectCompileFunction(V8CacheOptions cache_options, - CachedMetadataHandler* cache_handler, - ScriptStreamer* streamer) { - DCHECK(streamer->IsFinished()); - DCHECK(!streamer->StreamingSuppressed()); - - // Streaming compilation may involve use of code cache. - // TODO(leszeks): Add compile timer to streaming compilation. - return WTF::Bind(PostStreamCompile, cache_options, - WrapPersistent(cache_handler), WrapPersistent(streamer)); -} -} // namespace - v8::MaybeLocal<v8::Script> V8ScriptRunner::CompileScript( ScriptState* script_state, const ScriptSourceCode& source, AccessControlStatus access_control_status, - V8CacheOptions cache_options, + v8::ScriptCompiler::CompileOptions compile_options, + v8::ScriptCompiler::NoCacheReason no_cache_reason, const ReferrerScriptInfo& referrer_info) { v8::Isolate* isolate = script_state->GetIsolate(); if (source.Source().length() >= v8::String::kMaxLength) { @@ -424,29 +504,10 @@ v8::False(isolate), // is_module referrer_info.ToV8HostDefinedOptions(isolate)); - v8::ScriptCompiler::NoCacheReason no_handler_reason; - switch (source.SourceLocationType()) { - case ScriptSourceLocationType::kInline: - no_handler_reason = v8::ScriptCompiler::kNoCacheBecauseInlineScript; - break; - case ScriptSourceLocationType::kInlineInsideDocumentWrite: - no_handler_reason = v8::ScriptCompiler::kNoCacheBecauseInDocumentWrite; - break; - case ScriptSourceLocationType::kExternalFile: - no_handler_reason = - v8::ScriptCompiler::kNoCacheBecauseResourceWithNoCacheHandler; - break; - // TODO(leszeks): Possibly differentiate between the other kinds of script - // origin also. - default: - no_handler_reason = v8::ScriptCompiler::kNoCacheBecauseNoResource; - break; - } - CompileFn compile_fn = - streamer ? SelectCompileFunction(cache_options, cache_handler, streamer) - : SelectCompileFunction(cache_options, cache_handler, code, - no_handler_reason); + streamer ? SelectCompileFunction(compile_options, cache_handler, streamer) + : SelectCompileFunction(compile_options, cache_handler, + no_cache_reason); if (!*TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(kTraceEventCategoryGroup)) return std::move(compile_fn).Run(isolate, code, origin, nullptr); @@ -522,19 +583,90 @@ return result; } +void V8ScriptRunner::ProduceCache( + v8::Isolate* isolate, + v8::Local<v8::Script> script, + const ScriptSourceCode& source, + ProduceCacheOptions produce_cache_options, + v8::ScriptCompiler::CompileOptions compile_options) { + TRACE_EVENT0("v8", "v8.run"); + RuntimeCallStatsScopedTracer rcs_scoped_tracer(isolate); + RUNTIME_CALL_TIMER_SCOPE(isolate, RuntimeCallStats::CounterId::kV8); + + switch (produce_cache_options) { + case ProduceCacheOptions::kSetTimeStamp: + V8ScriptRunner::SetCacheTimeStamp(source.CacheHandler()); + break; + case ProduceCacheOptions::kProduceCodeCache: { + constexpr const char* kTraceEventCategoryGroup = "v8,devtools.timeline"; + TRACE_EVENT_BEGIN1(kTraceEventCategoryGroup, "v8.compile", "fileName", + source.Url().GetString().Utf8()); + + std::unique_ptr<v8::ScriptCompiler::CachedData> cached_data( + v8::ScriptCompiler::CreateCodeCache( + script->GetUnboundScript(), V8String(isolate, source.Source()))); + if (cached_data) { + // TODO(crbug.com/783124): This code is mostly a duplicate of code in + // CompileAndProduceCache that is used to produce parser cache. + // We want to remove the support for producing parser cache soon and + // CompileAndProduceCache function should be removed then. + const char* data = reinterpret_cast<const char*>(cached_data->data); + int length = cached_data->length; + if (length > 1024) { + // Omit histogram samples for small cache data to avoid outliers. + int cache_size_ratio = + static_cast<int>(100.0 * length / source.Source().length()); + DEFINE_THREAD_SAFE_STATIC_LOCAL( + CustomCountHistogram, code_cache_size_histogram, + ("V8.CodeCacheSizeRatio", 0, 10000, 50)); + code_cache_size_histogram.Count(cache_size_ratio); + } + CachedMetadataHandler* cache_handler = source.CacheHandler(); + cache_handler->ClearCachedMetadata( + CachedMetadataHandler::kCacheLocally); + cache_handler->SetCachedMetadata( + V8ScriptRunner::TagForCodeCache(cache_handler), data, length, + CachedMetadataHandler::kSendToPlatform); + } + + TRACE_EVENT_END1( + kTraceEventCategoryGroup, "v8.compile", "data", + InspectorCompileScriptEvent::Data( + source.Url().GetString(), source.StartPosition(), + InspectorCompileScriptEvent::V8CacheResult( + InspectorCompileScriptEvent::V8CacheResult::ProduceResult( + compile_options, cached_data ? cached_data->length : 0), + Optional<InspectorCompileScriptEvent::V8CacheResult:: + ConsumeResult>()), + source.Streamer())); + break; + } + case ProduceCacheOptions::kNoProduceCache: + break; + } +} + v8::MaybeLocal<v8::Value> V8ScriptRunner::CompileAndRunInternalScript( v8::Isolate* isolate, ScriptState* script_state, const ScriptSourceCode& source_code) { DCHECK_EQ(isolate, script_state->GetIsolate()); + v8::ScriptCompiler::CompileOptions compile_options; + V8ScriptRunner::ProduceCacheOptions produce_cache_options; + v8::ScriptCompiler::NoCacheReason no_cache_reason; + std::tie(compile_options, produce_cache_options, no_cache_reason) = + V8ScriptRunner::GetCompileOptions(kV8CacheOptionsDefault, source_code); + // Currently internal scripts don't have cache handlers. So we should not + // produce cache for them. + DCHECK_EQ(produce_cache_options, ProduceCacheOptions::kNoProduceCache); v8::Local<v8::Script> script; // Use default ScriptReferrerInfo here: // - nonce: empty for internal script, and // - parser_state: always "not parser inserted" for internal scripts. - if (!V8ScriptRunner::CompileScript( - script_state, source_code, kSharableCrossOrigin, - kV8CacheOptionsDefault, ReferrerScriptInfo()) + if (!V8ScriptRunner::CompileScript(script_state, source_code, + kSharableCrossOrigin, compile_options, + no_cache_reason, ReferrerScriptInfo()) .ToLocal(&script)) return v8::MaybeLocal<v8::Value>(); @@ -678,13 +810,16 @@ return CacheTag(kCacheTagCode, cache_handler->Encoding()); } +uint32_t V8ScriptRunner::TagForTimeStamp(CachedMetadataHandler* cache_handler) { + return CacheTag(kCacheTagTimeStamp, cache_handler->Encoding()); +} + // Store a timestamp to the cache as hint. void V8ScriptRunner::SetCacheTimeStamp(CachedMetadataHandler* cache_handler) { double now = WTF::CurrentTime(); - uint32_t tag = CacheTag(kCacheTagTimeStamp, cache_handler->Encoding()); cache_handler->ClearCachedMetadata(CachedMetadataHandler::kCacheLocally); - cache_handler->SetCachedMetadata(tag, reinterpret_cast<char*>(&now), - sizeof(now), + cache_handler->SetCachedMetadata(TagForTimeStamp(cache_handler), + reinterpret_cast<char*>(&now), sizeof(now), CachedMetadataHandler::kSendToPlatform); } @@ -749,13 +884,14 @@ v8::Local<v8::String> code(V8String(isolate, script_string)); v8::ScriptCompiler::Source source(code, origin); scoped_refptr<CachedMetadata> cached_metadata; - const v8::ScriptCompiler::CachedData* cached_data = nullptr; + std::unique_ptr<v8::ScriptCompiler::CachedData> cached_data; v8::Local<v8::UnboundScript> unbound_script; if (v8::ScriptCompiler::CompileUnboundScript( - isolate, &source, v8::ScriptCompiler::kProduceFullCodeCache) + isolate, &source, v8::ScriptCompiler::kEagerCompile) .ToLocal(&unbound_script)) { - cached_data = source.GetCachedData(); + cached_data.reset( + v8::ScriptCompiler::CreateCodeCache(unbound_script, code)); if (cached_data && cached_data->length) { cached_metadata = CachedMetadata::Create( CacheTag(kCacheTagCode, encoding.GetName()), @@ -770,7 +906,7 @@ file_name, TextPosition(), InspectorCompileScriptEvent::V8CacheResult( InspectorCompileScriptEvent::V8CacheResult::ProduceResult( - v8::ScriptCompiler::kProduceFullCodeCache, + v8::ScriptCompiler::kEagerCompile, cached_data ? cached_data->length : 0), Optional< InspectorCompileScriptEvent::V8CacheResult::ConsumeResult>()),
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8ScriptRunner.h b/third_party/WebKit/Source/bindings/core/v8/V8ScriptRunner.h index a370fc4..660bf596 100644 --- a/third_party/WebKit/Source/bindings/core/v8/V8ScriptRunner.h +++ b/third_party/WebKit/Source/bindings/core/v8/V8ScriptRunner.h
@@ -61,14 +61,22 @@ kNotOpaque, }; + enum class ProduceCacheOptions { + kNoProduceCache, + kSetTimeStamp, + kProduceCodeCache, + }; + // For the following methods, the caller sites have to hold // a HandleScope and a ContextScope. // CachedMetadataHandler is set when metadata caching is supported. - static v8::MaybeLocal<v8::Script> CompileScript(ScriptState*, - const ScriptSourceCode&, - AccessControlStatus, - V8CacheOptions, - const ReferrerScriptInfo&); + static v8::MaybeLocal<v8::Script> CompileScript( + ScriptState*, + const ScriptSourceCode&, + AccessControlStatus, + v8::ScriptCompiler::CompileOptions, + v8::ScriptCompiler::NoCacheReason, + const ReferrerScriptInfo&); static v8::MaybeLocal<v8::Module> CompileModule(v8::Isolate*, const String& source, const String& file_name, @@ -107,6 +115,17 @@ v8::Local<v8::Module>, v8::Local<v8::Context>); + static std::tuple<v8::ScriptCompiler::CompileOptions, + ProduceCacheOptions, + v8::ScriptCompiler::NoCacheReason> + GetCompileOptions(V8CacheOptions, const ScriptSourceCode&); + + static void ProduceCache(v8::Isolate*, + v8::Local<v8::Script>, + const ScriptSourceCode&, + ProduceCacheOptions, + v8::ScriptCompiler::CompileOptions); + // Only to be used from ScriptModule::ReportException(). static void ReportExceptionForModule(v8::Isolate*, v8::Local<v8::Value> exception, @@ -115,6 +134,7 @@ static uint32_t TagForParserCache(CachedMetadataHandler*); static uint32_t TagForCodeCache(CachedMetadataHandler*); + static uint32_t TagForTimeStamp(CachedMetadataHandler*); static void SetCacheTimeStamp(CachedMetadataHandler*); // Utilities for calling functions added to the V8 extras binding object.
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8ScriptRunnerTest.cpp b/third_party/WebKit/Source/bindings/core/v8/V8ScriptRunnerTest.cpp index 3b4c677..c224f4ad 100644 --- a/third_party/WebKit/Source/bindings/core/v8/V8ScriptRunnerTest.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/V8ScriptRunnerTest.cpp
@@ -48,17 +48,51 @@ unsigned TagForCodeCache(CachedMetadataHandler* cache_handler) const { return V8ScriptRunner::TagForCodeCache(cache_handler); } + unsigned TagForTimeStamp(CachedMetadataHandler* cache_handler) const { + return V8ScriptRunner::TagForTimeStamp(cache_handler); + } void SetCacheTimeStamp(CachedMetadataHandler* cache_handler) { V8ScriptRunner::SetCacheTimeStamp(cache_handler); } - bool CompileScript(ScriptState* script_state, + bool CompileScript(v8::Isolate* isolate, + ScriptState* script_state, const ScriptSourceCode& source_code, V8CacheOptions cache_options) { - return !V8ScriptRunner::CompileScript(script_state, source_code, - kNotSharableCrossOrigin, - cache_options, ReferrerScriptInfo()) - .IsEmpty(); + v8::ScriptCompiler::CompileOptions compile_options; + V8ScriptRunner::ProduceCacheOptions produce_cache_options; + v8::ScriptCompiler::NoCacheReason no_cache_reason; + std::tie(compile_options, produce_cache_options, no_cache_reason) = + V8ScriptRunner::GetCompileOptions(cache_options, source_code); + v8::MaybeLocal<v8::Script> compiled_script = V8ScriptRunner::CompileScript( + script_state, source_code, kNotSharableCrossOrigin, compile_options, + no_cache_reason, ReferrerScriptInfo()); + if (compiled_script.IsEmpty()) { + return false; + } + V8ScriptRunner::ProduceCache(isolate, compiled_script.ToLocalChecked(), + source_code, produce_cache_options, + compile_options); + return true; + } + + bool CompileScript( + v8::Isolate* isolate, + ScriptState* script_state, + const ScriptSourceCode& source_code, + v8::ScriptCompiler::CompileOptions compile_options, + v8::ScriptCompiler::NoCacheReason no_cache_reason, + V8ScriptRunner::ProduceCacheOptions produce_cache_options) { + v8::MaybeLocal<v8::Script> compiled_script = V8ScriptRunner::CompileScript( + script_state, source_code, kNotSharableCrossOrigin, compile_options, + no_cache_reason, ReferrerScriptInfo()); + if (compiled_script.IsEmpty()) { + return false; + } + V8ScriptRunner::ProduceCache(isolate, compiled_script.ToLocalChecked(), + source_code, produce_cache_options, + compile_options); + return true; } ScriptResource* CreateEmptyResource() { @@ -86,12 +120,12 @@ V8TestingScope scope; ScriptSourceCode source_code(Code(), ScriptSourceLocationType::kInternal, nullptr /* cache_handler */, Url()); - EXPECT_TRUE( - CompileScript(scope.GetScriptState(), source_code, kV8CacheOptionsNone)); - EXPECT_TRUE( - CompileScript(scope.GetScriptState(), source_code, kV8CacheOptionsParse)); - EXPECT_TRUE( - CompileScript(scope.GetScriptState(), source_code, kV8CacheOptionsCode)); + EXPECT_TRUE(CompileScript(scope.GetIsolate(), scope.GetScriptState(), + source_code, kV8CacheOptionsNone)); + EXPECT_TRUE(CompileScript(scope.GetIsolate(), scope.GetScriptState(), + source_code, kV8CacheOptionsParse)); + EXPECT_TRUE(CompileScript(scope.GetIsolate(), scope.GetScriptState(), + source_code, kV8CacheOptionsCode)); } TEST_F(V8ScriptRunnerTest, emptyResourceDoesNotHaveCacheHandler) { @@ -102,8 +136,8 @@ TEST_F(V8ScriptRunnerTest, parseOption) { V8TestingScope scope; ScriptSourceCode source_code(nullptr, CreateResource(UTF8Encoding())); - EXPECT_TRUE( - CompileScript(scope.GetScriptState(), source_code, kV8CacheOptionsParse)); + EXPECT_TRUE(CompileScript(scope.GetIsolate(), scope.GetScriptState(), + source_code, kV8CacheOptionsParse)); CachedMetadataHandler* cache_handler = source_code.CacheHandler(); EXPECT_TRUE( cache_handler->GetCachedMetadata(TagForParserCache(cache_handler))); @@ -122,8 +156,8 @@ CachedMetadataHandler* cache_handler = source_code.CacheHandler(); SetCacheTimeStamp(cache_handler); - EXPECT_TRUE( - CompileScript(scope.GetScriptState(), source_code, kV8CacheOptionsCode)); + EXPECT_TRUE(CompileScript(scope.GetIsolate(), scope.GetScriptState(), + source_code, kV8CacheOptionsCode)); EXPECT_FALSE( cache_handler->GetCachedMetadata(TagForParserCache(cache_handler))); @@ -135,6 +169,71 @@ TagForCodeCache(another_resource->CacheHandler()))); } +TEST_F(V8ScriptRunnerTest, consumeCodeOption) { + V8TestingScope scope; + ScriptSourceCode source_code(nullptr, CreateResource(UTF8Encoding())); + // Set timestamp to simulate a warm run. + CachedMetadataHandler* cache_handler = source_code.CacheHandler(); + SetCacheTimeStamp(cache_handler); + + // Warm run - should produce code cache. + EXPECT_TRUE(CompileScript(scope.GetIsolate(), scope.GetScriptState(), + source_code, kV8CacheOptionsCode)); + + // Check the produced cache is for code and not parser cache. + EXPECT_FALSE( + cache_handler->GetCachedMetadata(TagForParserCache(cache_handler))); + EXPECT_TRUE(cache_handler->GetCachedMetadata(TagForCodeCache(cache_handler))); + + // Hot run - should consume code cache. + v8::ScriptCompiler::CompileOptions compile_options; + V8ScriptRunner::ProduceCacheOptions produce_cache_options; + v8::ScriptCompiler::NoCacheReason no_cache_reason; + std::tie(compile_options, produce_cache_options, no_cache_reason) = + V8ScriptRunner::GetCompileOptions(kV8CacheOptionsDefault, source_code); + EXPECT_EQ(produce_cache_options, + V8ScriptRunner::ProduceCacheOptions::kNoProduceCache); + EXPECT_EQ(compile_options, + v8::ScriptCompiler::CompileOptions::kConsumeCodeCache); + EXPECT_TRUE(CompileScript(scope.GetIsolate(), scope.GetScriptState(), + source_code, compile_options, no_cache_reason, + produce_cache_options)); + EXPECT_TRUE(cache_handler->GetCachedMetadata(TagForCodeCache(cache_handler))); +} + +TEST_F(V8ScriptRunnerTest, produceAndConsumeCodeOption) { + V8TestingScope scope; + ScriptSourceCode source_code(nullptr, CreateResource(UTF8Encoding())); + CachedMetadataHandler* cache_handler = source_code.CacheHandler(); + + // Cold run - should set the timestamp + EXPECT_TRUE(CompileScript(scope.GetIsolate(), scope.GetScriptState(), + source_code, kV8CacheOptionsDefault)); + EXPECT_TRUE(cache_handler->GetCachedMetadata(TagForTimeStamp(cache_handler))); + EXPECT_FALSE( + cache_handler->GetCachedMetadata(TagForCodeCache(cache_handler))); + + // Warm run - should produce code cache + EXPECT_TRUE(CompileScript(scope.GetIsolate(), scope.GetScriptState(), + source_code, kV8CacheOptionsDefault)); + EXPECT_TRUE(cache_handler->GetCachedMetadata(TagForCodeCache(cache_handler))); + + // Hot run - should consume code cache + v8::ScriptCompiler::CompileOptions compile_options; + V8ScriptRunner::ProduceCacheOptions produce_cache_options; + v8::ScriptCompiler::NoCacheReason no_cache_reason; + std::tie(compile_options, produce_cache_options, no_cache_reason) = + V8ScriptRunner::GetCompileOptions(kV8CacheOptionsDefault, source_code); + EXPECT_EQ(produce_cache_options, + V8ScriptRunner::ProduceCacheOptions::kNoProduceCache); + EXPECT_EQ(compile_options, + v8::ScriptCompiler::CompileOptions::kConsumeCodeCache); + EXPECT_TRUE(CompileScript(scope.GetIsolate(), scope.GetScriptState(), + source_code, compile_options, no_cache_reason, + produce_cache_options)); + EXPECT_TRUE(cache_handler->GetCachedMetadata(TagForCodeCache(cache_handler))); +} + } // namespace } // namespace blink
diff --git a/third_party/WebKit/Source/bindings/core/v8/WorkerOrWorkletScriptController.cpp b/third_party/WebKit/Source/bindings/core/v8/WorkerOrWorkletScriptController.cpp index e851064b..af33a7b 100644 --- a/third_party/WebKit/Source/bindings/core/v8/WorkerOrWorkletScriptController.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/WorkerOrWorkletScriptController.cpp
@@ -271,12 +271,20 @@ // - A work{er,let} script doesn't have a nonce, and // - a work{er,let} script is always "not parser inserted". ReferrerScriptInfo referrer_info; + v8::ScriptCompiler::CompileOptions compile_options; + V8ScriptRunner::ProduceCacheOptions produce_cache_options; + v8::ScriptCompiler::NoCacheReason no_cache_reason; + std::tie(compile_options, produce_cache_options, no_cache_reason) = + V8ScriptRunner::GetCompileOptions(v8_cache_options, source_code); if (V8ScriptRunner::CompileScript(script_state_.get(), source_code, - kSharableCrossOrigin, v8_cache_options, - referrer_info) - .ToLocal(&compiled_script)) + kSharableCrossOrigin, compile_options, + no_cache_reason, referrer_info) + .ToLocal(&compiled_script)) { + V8ScriptRunner::ProduceCache(isolate_, compiled_script, source_code, + produce_cache_options, compile_options); maybe_result = V8ScriptRunner::RunCompiledScript(isolate_, compiled_script, global_scope_); + } if (!block.CanContinue()) { ForbidExecution();
diff --git a/third_party/WebKit/Source/core/BUILD.gn b/third_party/WebKit/Source/core/BUILD.gn index bcc7d65e..0aee4be 100644 --- a/third_party/WebKit/Source/core/BUILD.gn +++ b/third_party/WebKit/Source/core/BUILD.gn
@@ -775,6 +775,7 @@ "$blink_core_output_dir/css/properties/longhands/Ry.h", "$blink_core_output_dir/css/properties/longhands/Scale.h", "$blink_core_output_dir/css/properties/longhands/ScrollBehavior.h", + "$blink_core_output_dir/css/properties/longhands/ScrollCustomization.h", "$blink_core_output_dir/css/properties/longhands/ScrollMarginBlockEnd.h", "$blink_core_output_dir/css/properties/longhands/ScrollMarginBlockStart.h", "$blink_core_output_dir/css/properties/longhands/ScrollMarginBottom.h",
diff --git a/third_party/WebKit/Source/core/css/BUILD.gn b/third_party/WebKit/Source/core/css/BUILD.gn index e880527..c82f9a4 100644 --- a/third_party/WebKit/Source/core/css/BUILD.gn +++ b/third_party/WebKit/Source/core/css/BUILD.gn
@@ -644,6 +644,7 @@ "properties/longhands/RyCustom.cpp", "properties/longhands/ScaleCustom.cpp", "properties/longhands/ScrollBehaviorCustom.cpp", + "properties/longhands/ScrollCustomizationCustom.cpp", "properties/longhands/ScrollMarginBlockEndCustom.cpp", "properties/longhands/ScrollMarginBlockStartCustom.cpp", "properties/longhands/ScrollMarginBottomCustom.cpp",
diff --git a/third_party/WebKit/Source/core/css/CSSComputedStyleDeclaration.cpp b/third_party/WebKit/Source/core/css/CSSComputedStyleDeclaration.cpp index 54e48645..231294f0 100644 --- a/third_party/WebKit/Source/core/css/CSSComputedStyleDeclaration.cpp +++ b/third_party/WebKit/Source/core/css/CSSComputedStyleDeclaration.cpp
@@ -97,9 +97,9 @@ CSSPropertyOverflowX, CSSPropertyOverflowY, CSSPropertyPaddingBottom, CSSPropertyPaddingLeft, CSSPropertyPaddingRight, CSSPropertyPaddingTop, CSSPropertyPointerEvents, CSSPropertyPosition, CSSPropertyResize, - CSSPropertyRight, CSSPropertyScrollBehavior, CSSPropertySpeak, - CSSPropertyTableLayout, CSSPropertyTabSize, CSSPropertyTextAlign, - CSSPropertyTextAlignLast, CSSPropertyTextDecoration, + CSSPropertyRight, CSSPropertyScrollBehavior, CSSPropertyScrollCustomization, + CSSPropertySpeak, CSSPropertyTableLayout, CSSPropertyTabSize, + CSSPropertyTextAlign, CSSPropertyTextAlignLast, CSSPropertyTextDecoration, CSSPropertyTextDecorationLine, CSSPropertyTextDecorationStyle, CSSPropertyTextDecorationColor, CSSPropertyTextDecorationSkipInk, CSSPropertyTextJustify, CSSPropertyTextUnderlinePosition,
diff --git a/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h b/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h index 0afcd5e..3c21b9c 100644 --- a/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h +++ b/third_party/WebKit/Source/core/css/CSSPrimitiveValueMappings.h
@@ -47,6 +47,7 @@ #include "platform/fonts/TextRenderingMode.h" #include "platform/graphics/GraphicsTypes.h" #include "platform/graphics/TouchAction.h" +#include "platform/scroll/ScrollCustomization.h" #include "platform/scroll/ScrollableArea.h" #include "platform/text/TextRun.h" #include "platform/text/WritingMode.h" @@ -1511,6 +1512,34 @@ } template <> +inline ScrollCustomization::ScrollDirection CSSIdentifierValue::ConvertTo() + const { + switch (value_id_) { + case CSSValueNone: + return ScrollCustomization::kScrollDirectionNone; + case CSSValueAuto: + return ScrollCustomization::kScrollDirectionAuto; + case CSSValuePanLeft: + return ScrollCustomization::kScrollDirectionPanLeft; + case CSSValuePanRight: + return ScrollCustomization::kScrollDirectionPanRight; + case CSSValuePanX: + return ScrollCustomization::kScrollDirectionPanX; + case CSSValuePanUp: + return ScrollCustomization::kScrollDirectionPanUp; + case CSSValuePanDown: + return ScrollCustomization::kScrollDirectionPanDown; + case CSSValuePanY: + return ScrollCustomization::kScrollDirectionPanY; + default: + break; + } + + NOTREACHED(); + return ScrollCustomization::kScrollDirectionNone; +} + +template <> inline CSSIdentifierValue::CSSIdentifierValue(CSSBoxType css_box) : CSSValue(kIdentifierClass) { switch (css_box) {
diff --git a/third_party/WebKit/Source/core/css/CSSProperties.json5 b/third_party/WebKit/Source/core/css/CSSProperties.json5 index e1277c9d4e..4db7537f 100644 --- a/third_party/WebKit/Source/core/css/CSSProperties.json5 +++ b/third_party/WebKit/Source/core/css/CSSProperties.json5
@@ -2194,6 +2194,18 @@ }, }, { + name: "scroll-customization", + property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"], + converter: "ConvertFlags<blink::ScrollCustomization::ScrollDirection>", + type_name: "ScrollCustomization::ScrollDirection", + field_group: "*", + field_size: 4, + field_template: "primitive", + default_value: "ScrollCustomization::kScrollDirectionNone", + include_paths: ["platform/scroll/ScrollCustomization.h"], + runtime_flag: "ScrollCustomization", + }, + { name: "scroll-margin-block-start", property_methods: ["ParseSingleValue"], runtime_flag: "CSSScrollSnapPoints",
diff --git a/third_party/WebKit/Source/core/css/CSSRule.cpp b/third_party/WebKit/Source/core/css/CSSRule.cpp index fa928b5..2d75fe4 100644 --- a/third_party/WebKit/Source/core/css/CSSRule.cpp +++ b/third_party/WebKit/Source/core/css/CSSRule.cpp
@@ -48,13 +48,13 @@ void CSSRule::SetParentStyleSheet(CSSStyleSheet* style_sheet) { parent_is_rule_ = false; parent_style_sheet_ = style_sheet; - ScriptWrappableVisitor::WriteBarrier(parent_style_sheet_); + ScriptWrappableMarkingVisitor::WriteBarrier(parent_style_sheet_); } void CSSRule::SetParentRule(CSSRule* rule) { parent_is_rule_ = true; parent_rule_ = rule; - ScriptWrappableVisitor::WriteBarrier(parent_rule_); + ScriptWrappableMarkingVisitor::WriteBarrier(parent_rule_); } void CSSRule::Trace(blink::Visitor* visitor) {
diff --git a/third_party/WebKit/Source/core/css/CSSValueKeywords.json5 b/third_party/WebKit/Source/core/css/CSSValueKeywords.json5 index f736793..8627816 100644 --- a/third_party/WebKit/Source/core/css/CSSValueKeywords.json5 +++ b/third_party/WebKit/Source/core/css/CSSValueKeywords.json5
@@ -1172,5 +1172,15 @@ // auto, // contain // none + + //scroll-customization + // auto + // pan-x, + // pan-left, + // pan-right, + // pan-y, + // pan-up, + // pan-down + // none ], }
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParserTest.cpp b/third_party/WebKit/Source/core/css/parser/CSSPropertyParserTest.cpp index 12bf5de..05df892 100644 --- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParserTest.cpp +++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParserTest.cpp
@@ -5,6 +5,7 @@ #include "core/css/parser/CSSPropertyParser.h" #include "core/css/CSSColorValue.h" +#include "core/css/CSSIdentifierValue.h" #include "core/css/CSSValueList.h" #include "core/css/StyleSheetContents.h" #include "core/css/parser/CSSParser.h" @@ -344,4 +345,47 @@ UseCounter::IsCounted(*doc, WebFeature::kBasicShapeEllipseNoRadius)); } +TEST(CSSPropertyParserTest, ScrollCustomizationPropertySingleValue) { + RuntimeEnabledFeatures::SetScrollCustomizationEnabled(true); + const CSSValue* value = CSSParser::ParseSingleValue( + CSSPropertyScrollCustomization, "pan-down", + StrictCSSParserContext(SecureContextMode::kSecureContext)); + DCHECK(value); + const CSSValueList* list = ToCSSValueList(value); + EXPECT_EQ(1U, list->length()); + EXPECT_EQ(CSSValuePanDown, ToCSSIdentifierValue(list->Item(0U)).GetValueID()); +} + +TEST(CSSPropertyParserTest, ScrollCustomizationPropertyTwoValuesCombined) { + RuntimeEnabledFeatures::SetScrollCustomizationEnabled(true); + const CSSValue* value = CSSParser::ParseSingleValue( + CSSPropertyScrollCustomization, "pan-left pan-y", + StrictCSSParserContext(SecureContextMode::kSecureContext)); + const CSSValueList* list = ToCSSValueList(value); + EXPECT_EQ(2U, list->length()); + EXPECT_EQ(CSSValuePanLeft, ToCSSIdentifierValue(list->Item(0U)).GetValueID()); + EXPECT_EQ(CSSValuePanY, ToCSSIdentifierValue(list->Item(1U)).GetValueID()); +} + +TEST(CSSPropertyParserTest, ScrollCustomizationPropertyInvalidEntries) { + // We expect exactly one property value per coordinate. + RuntimeEnabledFeatures::SetScrollCustomizationEnabled(true); + const CSSValue* value = CSSParser::ParseSingleValue( + CSSPropertyScrollCustomization, "pan-left pan-right", + StrictCSSParserContext(SecureContextMode::kSecureContext)); + EXPECT_FALSE(value); + value = CSSParser::ParseSingleValue( + CSSPropertyScrollCustomization, "pan-up pan-down", + StrictCSSParserContext(SecureContextMode::kSecureContext)); + EXPECT_FALSE(value); + value = CSSParser::ParseSingleValue( + CSSPropertyScrollCustomization, "pan-x pan-left", + StrictCSSParserContext(SecureContextMode::kSecureContext)); + EXPECT_FALSE(value); + value = CSSParser::ParseSingleValue( + CSSPropertyScrollCustomization, "pan-x pan-x", + StrictCSSParserContext(SecureContextMode::kSecureContext)); + EXPECT_FALSE(value); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/core/css/properties/ComputedStyleUtils.cpp b/third_party/WebKit/Source/core/css/properties/ComputedStyleUtils.cpp index f671701..751b65aa 100644 --- a/third_party/WebKit/Source/core/css/properties/ComputedStyleUtils.cpp +++ b/third_party/WebKit/Source/core/css/properties/ComputedStyleUtils.cpp
@@ -2276,4 +2276,38 @@ } } +// Returns up to two values for 'scroll-customization' property. The values +// correspond to the customization values for 'x' and 'y' axes. +CSSValue* ComputedStyleUtils::ScrollCustomizationFlagsToCSSValue( + ScrollCustomization::ScrollDirection scroll_customization) { + CSSValueList* list = CSSValueList::CreateSpaceSeparated(); + if (scroll_customization == ScrollCustomization::kScrollDirectionAuto) { + list->Append(*CSSIdentifierValue::Create(CSSValueAuto)); + } else if (scroll_customization == + ScrollCustomization::kScrollDirectionNone) { + list->Append(*CSSIdentifierValue::Create(CSSValueNone)); + } else { + if ((scroll_customization & ScrollCustomization::kScrollDirectionPanX) == + ScrollCustomization::kScrollDirectionPanX) + list->Append(*CSSIdentifierValue::Create(CSSValuePanX)); + else if (scroll_customization & + ScrollCustomization::kScrollDirectionPanLeft) + list->Append(*CSSIdentifierValue::Create(CSSValuePanLeft)); + else if (scroll_customization & + ScrollCustomization::kScrollDirectionPanRight) + list->Append(*CSSIdentifierValue::Create(CSSValuePanRight)); + if ((scroll_customization & ScrollCustomization::kScrollDirectionPanY) == + ScrollCustomization::kScrollDirectionPanY) + list->Append(*CSSIdentifierValue::Create(CSSValuePanY)); + else if (scroll_customization & ScrollCustomization::kScrollDirectionPanUp) + list->Append(*CSSIdentifierValue::Create(CSSValuePanUp)); + else if (scroll_customization & + ScrollCustomization::kScrollDirectionPanDown) + list->Append(*CSSIdentifierValue::Create(CSSValuePanDown)); + } + + DCHECK(list->length()); + return list; +} + } // namespace blink
diff --git a/third_party/WebKit/Source/core/css/properties/ComputedStyleUtils.h b/third_party/WebKit/Source/core/css/properties/ComputedStyleUtils.h index 4b9b7383..2330805 100644 --- a/third_party/WebKit/Source/core/css/properties/ComputedStyleUtils.h +++ b/third_party/WebKit/Source/core/css/properties/ComputedStyleUtils.h
@@ -195,6 +195,8 @@ const LayoutObject*, Node*, bool allow_visited_style); + static CSSValue* ScrollCustomizationFlagsToCSSValue( + ScrollCustomization::ScrollDirection); }; } // namespace blink
diff --git a/third_party/WebKit/Source/core/css/properties/longhands/ScrollCustomizationCustom.cpp b/third_party/WebKit/Source/core/css/properties/longhands/ScrollCustomizationCustom.cpp new file mode 100644 index 0000000..ca81dd2f --- /dev/null +++ b/third_party/WebKit/Source/core/css/properties/longhands/ScrollCustomizationCustom.cpp
@@ -0,0 +1,73 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "core/css/properties/longhands/ScrollCustomization.h" + +#include "core/css/CSSValueList.h" +#include "core/css/parser/CSSPropertyParserHelpers.h" +#include "core/css/properties/ComputedStyleUtils.h" +#include "core/style/ComputedStyle.h" + +class CSSParserLocalContext; +namespace blink { + +namespace { + +static bool ConsumePan(CSSParserTokenRange& range, + CSSValue** pan_x, + CSSValue** pan_y) { + CSSValueID id = range.Peek().Id(); + if ((id == CSSValuePanX || id == CSSValuePanRight || id == CSSValuePanLeft) && + !*pan_x) { + *pan_x = CSSPropertyParserHelpers::ConsumeIdent(range); + } else if ((id == CSSValuePanY || id == CSSValuePanDown || + id == CSSValuePanUp) && + !*pan_y) { + *pan_y = CSSPropertyParserHelpers::ConsumeIdent(range); + } else { + return false; + } + return true; +} + +} // namespace +namespace CSSLonghand { + +const CSSValue* ScrollCustomization::ParseSingleValue( + CSSParserTokenRange& range, + const CSSParserContext& context, + const CSSParserLocalContext&) const { + CSSValueList* list = CSSValueList::CreateSpaceSeparated(); + CSSValueID id = range.Peek().Id(); + if (id == CSSValueAuto || id == CSSValueNone) { + list->Append(*CSSPropertyParserHelpers::ConsumeIdent(range)); + return list; + } + + CSSValue* pan_x = nullptr; + CSSValue* pan_y = nullptr; + if (!ConsumePan(range, &pan_x, &pan_y)) + return nullptr; + if (!range.AtEnd() && !ConsumePan(range, &pan_x, &pan_y)) + return nullptr; + + if (pan_x) + list->Append(*pan_x); + if (pan_y) + list->Append(*pan_y); + return list; +} + +const CSSValue* ScrollCustomization::CSSValueFromComputedStyleInternal( + const ComputedStyle& style, + const SVGComputedStyle&, + const LayoutObject*, + Node*, + bool allow_visited_style) const { + return ComputedStyleUtils::ScrollCustomizationFlagsToCSSValue( + style.ScrollCustomization()); +} + +} // namespace CSSLonghand +} // namespace blink
diff --git a/third_party/WebKit/Source/core/css/threaded/MultiThreadedTestUtil.h b/third_party/WebKit/Source/core/css/threaded/MultiThreadedTestUtil.h index 64e32bc..78c9657 100644 --- a/third_party/WebKit/Source/core/css/threaded/MultiThreadedTestUtil.h +++ b/third_party/WebKit/Source/core/css/threaded/MultiThreadedTestUtil.h
@@ -57,7 +57,8 @@ Vector<std::unique_ptr<WaitableEvent>> waits; for (int i = 0; i < num_threads_; ++i) { - threads.push_back(WebThreadSupportingGC::Create("")); + threads.push_back( + WebThreadSupportingGC::Create(WebThreadCreationParams(""))); waits.push_back(std::make_unique<WaitableEvent>()); }
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp index 939ffe2..17b4f87 100644 --- a/third_party/WebKit/Source/core/dom/Document.cpp +++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -4684,10 +4684,10 @@ static void LiveNodeListBaseWriteBarrier(void* parent, const LiveNodeListBase* list) { if (IsHTMLCollectionType(list->GetType())) { - ScriptWrappableVisitor::WriteBarrier( + ScriptWrappableMarkingVisitor::WriteBarrier( static_cast<const HTMLCollection*>(list)); } else { - ScriptWrappableVisitor::WriteBarrier( + ScriptWrappableMarkingVisitor::WriteBarrier( static_cast<const LiveNodeList*>(list)); } }
diff --git a/third_party/WebKit/Source/core/dom/Element.cpp b/third_party/WebKit/Source/core/dom/Element.cpp index 516e6bdb..aec9faf 100644 --- a/third_party/WebKit/Source/core/dom/Element.cpp +++ b/third_party/WebKit/Source/core/dom/Element.cpp
@@ -124,12 +124,14 @@ #include "core/layout/AdjustForAbsoluteZoom.h" #include "core/layout/LayoutTextFragment.h" #include "core/layout/LayoutView.h" +#include "core/layout/svg/SVGResources.h" #include "core/page/ChromeClient.h" #include "core/page/FocusController.h" #include "core/page/Page.h" #include "core/page/PointerLockController.h" #include "core/page/SpatialNavigation.h" #include "core/page/scrolling/RootScrollerController.h" +#include "core/page/scrolling/RootScrollerUtil.h" #include "core/page/scrolling/ScrollCustomizationCallbacks.h" #include "core/page/scrolling/ScrollState.h" #include "core/page/scrolling/ScrollStateCallback.h" @@ -139,7 +141,6 @@ #include "core/resize_observer/ResizeObservation.h" #include "core/svg/SVGAElement.h" #include "core/svg/SVGElement.h" -#include "core/svg/SVGTreeScopeResources.h" #include "core/svg_names.h" #include "core/xml_names.h" #include "platform/EventDispatchForbiddenScope.h" @@ -615,6 +616,11 @@ ->GlobalRootScrollerController() .IsViewportScrollCallback(callback); + disable_custom_callbacks |= + !RootScrollerUtil::IsGlobal(this) && + RuntimeEnabledFeatures::ScrollCustomizationEnabled() && + !GetScrollCustomizationCallbacks().InScrollPhase(this); + if (!callback || disable_custom_callbacks) { NativeDistributeScroll(scroll_state); return; @@ -628,7 +634,7 @@ if (callback->NativeScrollBehavior() == WebNativeScrollBehavior::kPerformAfterNativeScroll) callback->handleEvent(&scroll_state); -}; +} void Element::NativeApplyScroll(ScrollState& scroll_state) { // All elements in the scroll chain should be boxes. @@ -697,6 +703,10 @@ .GetPage() ->GlobalRootScrollerController() .IsViewportScrollCallback(callback); + disable_custom_callbacks |= + !RootScrollerUtil::IsGlobal(this) && + RuntimeEnabledFeatures::ScrollCustomizationEnabled() && + !GetScrollCustomizationCallbacks().InScrollPhase(this); if (!callback || disable_custom_callbacks) { NativeApplyScroll(scroll_state); @@ -1794,11 +1804,8 @@ if (this == GetDocument().CssTarget()) GetDocument().SetCSSTarget(nullptr); - if (HasPendingResources()) { - GetTreeScope() - .EnsureSVGTreeScopedResources() - .RemoveElementFromPendingResources(*this); - } + if (HasPendingResources()) + SVGResources::RemoveWatchesForElement(*this); if (GetCustomElementState() == CustomElementState::kCustom) CustomElement::EnqueueDisconnectedCallback(this); @@ -3271,6 +3278,24 @@ } } +void Element::WillBeginCustomizedScrollPhase( + ScrollCustomization::ScrollDirection direction) { + DCHECK(!GetScrollCustomizationCallbacks().InScrollPhase(this)); + LayoutBox* box = GetLayoutBox(); + if (!box) + return; + + ScrollCustomization::ScrollDirection scroll_customization = + box->Style()->ScrollCustomization(); + + GetScrollCustomizationCallbacks().SetInScrollPhase( + this, direction & scroll_customization); +} + +void Element::DidEndCustomizedScrollPhase() { + GetScrollCustomizationCallbacks().SetInScrollPhase(this, false); +} + // Step 1 of http://domparsing.spec.whatwg.org/#insertadjacenthtml() static Element* ContextElementForInsertion(const String& where, Element* element,
diff --git a/third_party/WebKit/Source/core/dom/Element.h b/third_party/WebKit/Source/core/dom/Element.h index 3ca2c75..c244f88b 100644 --- a/third_party/WebKit/Source/core/dom/Element.h +++ b/third_party/WebKit/Source/core/dom/Element.h
@@ -36,6 +36,7 @@ #include "core/resize_observer/ResizeObserver.h" #include "platform/bindings/TraceWrapperMember.h" #include "platform/heap/Handle.h" +#include "platform/scroll/ScrollCustomization.h" #include "platform/scroll/ScrollTypes.h" #include "public/platform/WebFocusType.h" @@ -839,6 +840,9 @@ EnsureResizeObserverData(); void SetNeedsResizeObserverUpdate(); + void WillBeginCustomizedScrollPhase(ScrollCustomization::ScrollDirection); + void DidEndCustomizedScrollPhase(); + protected: Element(const QualifiedName& tag_name, Document*, ConstructionType);
diff --git a/third_party/WebKit/Source/core/dom/IdTargetObserver.h b/third_party/WebKit/Source/core/dom/IdTargetObserver.h index 8952e72..5b74de2 100644 --- a/third_party/WebKit/Source/core/dom/IdTargetObserver.h +++ b/third_party/WebKit/Source/core/dom/IdTargetObserver.h
@@ -43,6 +43,8 @@ protected: IdTargetObserver(IdTargetObserverRegistry&, const AtomicString& id); + const AtomicString& Id() const { return id_; } + private: IdTargetObserverRegistry& Registry() { return *registry_; }
diff --git a/third_party/WebKit/Source/core/dom/Node.cpp b/third_party/WebKit/Source/core/dom/Node.cpp index be06d6e..295b3e3 100644 --- a/third_party/WebKit/Source/core/dom/Node.cpp +++ b/third_party/WebKit/Source/core/dom/Node.cpp
@@ -340,7 +340,7 @@ DCHECK(data_.rare_data_); SetFlag(kHasRareDataFlag); - ScriptWrappableVisitor::WriteBarrier(RareData()); + ScriptWrappableMarkingVisitor::WriteBarrier(RareData()); return *RareData(); }
diff --git a/third_party/WebKit/Source/core/editing/EditingUtilities.cpp b/third_party/WebKit/Source/core/editing/EditingUtilities.cpp index c86b5d7..edb5c59 100644 --- a/third_party/WebKit/Source/core/editing/EditingUtilities.cpp +++ b/third_party/WebKit/Source/core/editing/EditingUtilities.cpp
@@ -1577,12 +1577,6 @@ ToHTMLInputElement(text_control)->type() == InputTypeNames::password; } -bool IsTextSecurityNode(const Node* node) { - return node && node->GetLayoutObject() && - node->GetLayoutObject()->Style()->TextSecurity() != - ETextSecurity::kNone; -} - // If current position is at grapheme boundary, return 0; otherwise, return the // distance to its nearest left grapheme boundary. size_t ComputeDistanceToLeftGraphemeBoundary(const Position& position) {
diff --git a/third_party/WebKit/Source/core/editing/EditingUtilities.h b/third_party/WebKit/Source/core/editing/EditingUtilities.h index c0bd3f3..4ddf35b 100644 --- a/third_party/WebKit/Source/core/editing/EditingUtilities.h +++ b/third_party/WebKit/Source/core/editing/EditingUtilities.h
@@ -174,7 +174,6 @@ bool IsBlockFlowElement(const Node&); EUserSelect UsedValueOfUserSelect(const Node&); bool IsInPasswordField(const Position&); -bool IsTextSecurityNode(const Node*); CORE_EXPORT TextDirection DirectionOfEnclosingBlockOf(const Position&); CORE_EXPORT TextDirection DirectionOfEnclosingBlockOf(const PositionInFlatTree&);
diff --git a/third_party/WebKit/Source/core/editing/iterators/TextIteratorTextState.cpp b/third_party/WebKit/Source/core/editing/iterators/TextIteratorTextState.cpp index 5ca993d..184fe4a 100644 --- a/third_party/WebKit/Source/core/editing/iterators/TextIteratorTextState.cpp +++ b/third_party/WebKit/Source/core/editing/iterators/TextIteratorTextState.cpp
@@ -30,10 +30,21 @@ #include "core/editing/EditingUtilities.h" #include "core/editing/iterators/BackwardsTextBuffer.h" #include "core/html/HTMLElement.h" +#include "core/layout/LayoutObject.h" #include "platform/wtf/text/StringBuilder.h" namespace blink { +namespace { + +bool IsTextSecurityNode(const Node& node) { + return node.GetLayoutObject() && + node.GetLayoutObject()->Style()->TextSecurity() != + ETextSecurity::kNone; +} + +} // anonymous namespace + TextIteratorTextState::TextIteratorTextState( const TextIteratorBehavior& behavior) : behavior_(behavior) {} @@ -146,7 +157,7 @@ unsigned text_end_offset) { DCHECK(text_node); text_ = - behavior_.EmitsSmallXForTextSecurity() && IsTextSecurityNode(text_node) + behavior_.EmitsSmallXForTextSecurity() && IsTextSecurityNode(*text_node) ? RepeatString("x", string.length()) : string,
diff --git a/third_party/WebKit/Source/core/events/MessageEvent.idl b/third_party/WebKit/Source/core/events/MessageEvent.idl index 7be2489..2226c4a 100644 --- a/third_party/WebKit/Source/core/events/MessageEvent.idl +++ b/third_party/WebKit/Source/core/events/MessageEvent.idl
@@ -40,10 +40,9 @@ [CachedAttribute=isPortsDirty] readonly attribute FrozenArray<MessagePort> ports; [RuntimeEnabled=Suborigins] readonly attribute DOMString suborigin; - // TODO(foolip): |typeArg| should not be optional, none of the arguments - // should have [Default=Undefined] (they have other default values in the - // spec) and |sourceArg|'s type is wrong. - [Custom, MeasureAs=InitMessageEvent] void initMessageEvent([Default=Undefined] optional DOMString typeArg, + // TODO(foolip): none of the arguments should have [Default=Undefined] (they + // have other default values in the spec) and |sourceArg|'s type is wrong. + [Custom, MeasureAs=InitMessageEvent] void initMessageEvent([Default=Undefined] DOMString typeArg, [Default=Undefined] optional boolean canBubbleArg, [Default=Undefined] optional boolean cancelableArg, [Default=Undefined] optional any dataArg,
diff --git a/third_party/WebKit/Source/core/fetch/DataConsumerHandleTestUtil.cpp b/third_party/WebKit/Source/core/fetch/DataConsumerHandleTestUtil.cpp index 366558c..38c6a66 100644 --- a/third_party/WebKit/Source/core/fetch/DataConsumerHandleTestUtil.cpp +++ b/third_party/WebKit/Source/core/fetch/DataConsumerHandleTestUtil.cpp
@@ -40,7 +40,7 @@ DataConsumerHandleTestUtil::Thread::Thread( const char* name, InitializationPolicy initialization_policy) - : thread_(WebThreadSupportingGC::Create(name)), + : thread_(WebThreadSupportingGC::Create(WebThreadCreationParams(name))), initialization_policy_(initialization_policy), waitable_event_(std::make_unique<WaitableEvent>()) { thread_->PostTask(FROM_HERE, CrossThreadBind(&Thread::Initialize,
diff --git a/third_party/WebKit/Source/core/frame/Deprecation.cpp b/third_party/WebKit/Source/core/frame/Deprecation.cpp index b0bf07bf..23da9fd6 100644 --- a/third_party/WebKit/Source/core/frame/Deprecation.cpp +++ b/third_party/WebKit/Source/core/frame/Deprecation.cpp
@@ -549,6 +549,12 @@ String("CSS cannot be loaded from `file:` URLs unless they end " "in a `.css` file extension.")}; + case WebFeature::kCreateObjectURLMediaStream: + return {"CreateObjectURLMediaStreamDeprecated", M68, + replacedWillBeRemoved("URL.createObjectURL with media streams", + "HTMLMediaElement.srcObject", M68, + "5618491470118912")}; + case WebFeature::kWebAudioDezipperGainNodeGain: return {"WebAudioDezipperGainNodeGain", Unknown, DeprecatedWebAudioDezippering("GainNode.gain")};
diff --git a/third_party/WebKit/Source/core/frame/UseCounter.cpp b/third_party/WebKit/Source/core/frame/UseCounter.cpp index 84f99b2..6ce902b 100644 --- a/third_party/WebKit/Source/core/frame/UseCounter.cpp +++ b/third_party/WebKit/Source/core/frame/UseCounter.cpp
@@ -48,7 +48,7 @@ } // Make sure update_use_counter_css.py was run which updates histograms.xml. -constexpr int kMaximumCSSSampleId = 589; +constexpr int kMaximumCSSSampleId = 590; } // namespace @@ -1138,12 +1138,13 @@ return 588; case CSSPropertyTextDecorationSkipInk: return 589; + case CSSPropertyScrollCustomization: + return 590; // 1. Add new features above this line (don't change the assigned numbers of // the existing items). // 2. Update kMaximumCSSSampleId with the new maximum value. // 3. Run the update_use_counter_css.py script in // chromium/src/tools/metrics/histograms to update the UMA histogram names. - case CSSPropertyInvalid: NOTREACHED(); return 0;
diff --git a/third_party/WebKit/Source/core/html/HTMLFrameOwnerElement.cpp b/third_party/WebKit/Source/core/html/HTMLFrameOwnerElement.cpp index 86fee14b..c0eea8a 100644 --- a/third_party/WebKit/Source/core/html/HTMLFrameOwnerElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLFrameOwnerElement.cpp
@@ -35,6 +35,7 @@ #include "core/loader/FrameLoadRequest.h" #include "core/loader/FrameLoader.h" #include "core/page/Page.h" +#include "core/page/scrolling/RootScrollerController.h" #include "core/probe/CoreProbes.h" #include "core/timing/DOMWindowPerformance.h" #include "core/timing/Performance.h" @@ -273,6 +274,8 @@ embedded_content_view_->AttachToLayout(); } + GetDocument().GetRootScrollerController().DidUpdateIFrameFrameView(*this); + if (AXObjectCache* cache = GetDocument().ExistingAXObjectCache()) cache->ChildrenChanged(layout_embedded_content); }
diff --git a/third_party/WebKit/Source/core/html/forms/SliderThumbElement.cpp b/third_party/WebKit/Source/core/html/forms/SliderThumbElement.cpp index 5fa5989..ebbd609 100644 --- a/third_party/WebKit/Source/core/html/forms/SliderThumbElement.cpp +++ b/third_party/WebKit/Source/core/html/forms/SliderThumbElement.cpp
@@ -344,7 +344,7 @@ void SliderContainerElement::HandleTouchEvent(TouchEvent* event) { HTMLInputElement* input = HostInput(); - if (input->IsDisabledFormControl()) + if (!input || input->IsDisabledFormControl() || !event) return; if (event->type() == EventTypeNames::touchend) { @@ -365,6 +365,9 @@ TouchList* touches = event->targetTouches(); SliderThumbElement* thumb = ToSliderThumbElement( GetTreeScope().getElementById(ShadowElementNames::SliderThumb())); + if (!thumb || !touches) + return; + if (touches->length() == 1) { if (event->type() == EventTypeNames::touchstart) { start_point_ = touches->item(0)->AbsoluteLocation();
diff --git a/third_party/WebKit/Source/core/html/media/HTMLMediaElement.cpp b/third_party/WebKit/Source/core/html/media/HTMLMediaElement.cpp index 241d5d8..513023f4 100644 --- a/third_party/WebKit/Source/core/html/media/HTMLMediaElement.cpp +++ b/third_party/WebKit/Source/core/html/media/HTMLMediaElement.cpp
@@ -3609,7 +3609,7 @@ #if DCHECK_IS_ON() // There can be up to three children: an interstitial (media remoting or // picture in picture), text track container, and media controls. The media - // controls has to be the last child if presend, and has to be the next + // controls has to be the last child if present, and has to be the next // sibling of the text track container if both present. When present, media // remoting interstitial has to be the first child. unsigned number_of_children = shadow_root.CountChildren();
diff --git a/third_party/WebKit/Source/core/input/ScrollManager.cpp b/third_party/WebKit/Source/core/input/ScrollManager.cpp index a843c09..4cb5ac5 100644 --- a/third_party/WebKit/Source/core/input/ScrollManager.cpp +++ b/third_party/WebKit/Source/core/input/ScrollManager.cpp
@@ -24,6 +24,7 @@ #include "core/page/scrolling/SnapCoordinator.h" #include "core/paint/PaintLayer.h" #include "platform/Histogram.h" +#include "platform/scroll/ScrollCustomization.h" #include "platform/wtf/PtrUtil.h" namespace blink { @@ -252,6 +253,7 @@ frame_->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets(); DCHECK(!current_scroll_chain_.empty()); + scroll_state.SetScrollChain(current_scroll_chain_); scroll_state.distributeToScrollChainDescendant(); @@ -363,6 +365,8 @@ if (current_scroll_chain_.empty()) return WebInputEventResult::kNotHandled; + NotifyScrollPhaseBeginForCustomizedScroll(*scroll_state); + CustomizedScroll(*scroll_state); if (gesture_event.source_device == kWebGestureDeviceTouchscreen) @@ -516,6 +520,7 @@ ScrollState::Create(std::move(scroll_state_data)); CustomizedScroll(*scroll_state); SnapAtGestureScrollEnd(); + NotifyScrollPhaseEndForCustomizedScroll(); } ClearGestureScrollState(); @@ -744,4 +749,24 @@ return scroll_begin; } +void ScrollManager::NotifyScrollPhaseBeginForCustomizedScroll( + const ScrollState& scroll_state) { + ScrollCustomization::ScrollDirection direction = + ScrollCustomization::GetScrollDirectionFromDeltas( + scroll_state.deltaXHint(), scroll_state.deltaYHint()); + for (auto id : current_scroll_chain_) { + Node* node = DOMNodeIds::NodeForId(id); + if (node && node->IsElementNode()) + ToElement(node)->WillBeginCustomizedScrollPhase(direction); + } +} + +void ScrollManager::NotifyScrollPhaseEndForCustomizedScroll() { + for (auto id : current_scroll_chain_) { + Node* node = DOMNodeIds::NodeForId(id); + if (node && node->IsElementNode()) + ToElement(node)->DidEndCustomizedScrollPhase(); + } +} + } // namespace blink
diff --git a/third_party/WebKit/Source/core/input/ScrollManager.h b/third_party/WebKit/Source/core/input/ScrollManager.h index 545313b..60b14be1 100644 --- a/third_party/WebKit/Source/core/input/ScrollManager.h +++ b/third_party/WebKit/Source/core/input/ScrollManager.h
@@ -122,6 +122,9 @@ void SnapAtGestureScrollEnd(); + void NotifyScrollPhaseBeginForCustomizedScroll(const ScrollState&); + void NotifyScrollPhaseEndForCustomizedScroll(); + // NOTE: If adding a new field to this class please ensure that it is // cleared in |ScrollManager::clear()|.
diff --git a/third_party/WebKit/Source/core/inspector/InspectorMemoryAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorMemoryAgent.cpp index b425d02..2fd5a1f 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorMemoryAgent.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorMemoryAgent.cpp
@@ -30,21 +30,12 @@ #include "core/inspector/InspectorMemoryAgent.h" -#include "base/debug/stack_trace.h" #include "core/frame/LocalFrameClient.h" #include "core/inspector/InspectedFrames.h" #include "platform/InstanceCounters.h" -#include "platform/memory_profiler/SamplingNativeHeapProfiler.h" namespace blink { -const unsigned kDefaultNativeMemorySamplingInterval = 128 * 1024; - -namespace MemoryAgentState { -static const char samplingProfileInterval[] = - "memoryAgentSamplingProfileInterval"; -} // namespace MemoryAgentState - using PrepareForLeakDetectionCallback = protocol::Memory::Backend::PrepareForLeakDetectionCallback; using protocol::Response; @@ -85,87 +76,4 @@ InspectorBaseAgent::Trace(visitor); } -void InspectorMemoryAgent::Restore() { - int sampling_interval = 0; - state_->getInteger(MemoryAgentState::samplingProfileInterval, - &sampling_interval); - // The action below won't start sampling if the sampling_interval is zero. - startSampling(protocol::Maybe<int>(sampling_interval), - protocol::Maybe<bool>()); -} - -Response InspectorMemoryAgent::startSampling( - protocol::Maybe<int> in_sampling_interval, - protocol::Maybe<bool> in_suppressRandomness) { - int interval = - in_sampling_interval.fromMaybe(kDefaultNativeMemorySamplingInterval); - if (interval <= 0) - return Response::Error("Invalid sampling rate."); - SamplingNativeHeapProfiler::GetInstance()->SetSamplingInterval(interval); - state_->setInteger(MemoryAgentState::samplingProfileInterval, interval); - if (in_suppressRandomness.fromMaybe(false)) - SamplingNativeHeapProfiler::GetInstance()->SuppressRandomnessForTest(); - SamplingNativeHeapProfiler::GetInstance()->Start(); - return Response::OK(); -} - -Response InspectorMemoryAgent::stopSampling() { - int sampling_interval = 0; - state_->getInteger(MemoryAgentState::samplingProfileInterval, - &sampling_interval); - if (!sampling_interval) - return Response::Error("Sampling profiler is not started."); - SamplingNativeHeapProfiler::GetInstance()->Stop(); - state_->setInteger(MemoryAgentState::samplingProfileInterval, 0); - return Response::OK(); -} - -Response InspectorMemoryAgent::getSamplingProfile( - std::unique_ptr<protocol::Memory::SamplingProfile>* out_profile) { - std::unique_ptr<protocol::Array<protocol::Memory::SamplingProfileNode>> - samples = - protocol::Array<protocol::Memory::SamplingProfileNode>::create(); - std::vector<SamplingNativeHeapProfiler::Sample> raw_samples = - SamplingNativeHeapProfiler::GetInstance()->GetSamples(); - // TODO(alph): Only report samples recorded within the current session. - for (auto it = raw_samples.begin(); it != raw_samples.end(); ++it) { - std::unique_ptr<protocol::Array<protocol::String>> stack = - protocol::Array<protocol::String>::create(); - std::vector<std::string> source_stack = Symbolize(it->stack); - for (auto it2 = source_stack.begin(); it2 != source_stack.end(); ++it2) - stack->addItem(it2->c_str()); - samples->addItem(protocol::Memory::SamplingProfileNode::create() - .setSize(it->size) - .setCount(it->count) - .setStack(std::move(stack)) - .build()); - } - std::unique_ptr<protocol::Memory::SamplingProfile> result = - protocol::Memory::SamplingProfile::create() - .setSamples(std::move(samples)) - .build(); - *out_profile = std::move(result); - return Response::OK(); -} - -std::vector<std::string> InspectorMemoryAgent::Symbolize( - const std::vector<void*>& addresses) { - // TODO(alph): Move symbolization to the client. - std::vector<std::string> result; - base::debug::StackTrace trace(addresses.data(), addresses.size()); - std::string text = trace.ToString(); - - size_t next_pos; - for (size_t pos = 0;; pos = next_pos + 1) { - next_pos = text.find('\n', pos); - if (next_pos == std::string::npos) - break; - std::string line = text.substr(pos, next_pos - pos); - size_t space_pos = line.rfind(' '); - result.push_back( - line.substr(space_pos == std::string::npos ? 0 : space_pos + 1)); - } - return result; -} - } // namespace blink
diff --git a/third_party/WebKit/Source/core/inspector/InspectorMemoryAgent.h b/third_party/WebKit/Source/core/inspector/InspectorMemoryAgent.h index 8f88c04a..2c953846 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorMemoryAgent.h +++ b/third_party/WebKit/Source/core/inspector/InspectorMemoryAgent.h
@@ -52,7 +52,6 @@ ~InspectorMemoryAgent() override; void Trace(blink::Visitor*) override; - void Restore() override; protocol::Response getDOMCounters(int* documents, int* nodes, @@ -63,24 +62,11 @@ // BlinkLeakDetectorClient: void OnLeakDetectionComplete() override; - // Memory protocol domain: - protocol::Response startSampling( - protocol::Maybe<int> in_samplingInterval, - protocol::Maybe<bool> in_suppressRandomness) override; - protocol::Response stopSampling() override; - protocol::Response getSamplingProfile( - std::unique_ptr<protocol::Memory::SamplingProfile>*) override; - private: explicit InspectorMemoryAgent(InspectedFrames*); - - std::vector<std::string> Symbolize(const std::vector<void*>& addresses); - std::unique_ptr<BlinkLeakDetector> detector_; std::unique_ptr<PrepareForLeakDetectionCallback> callback_; Member<InspectedFrames> frames_; - std::map<void*, std::string> symbols_cache_; - DISALLOW_COPY_AND_ASSIGN(InspectorMemoryAgent); };
diff --git a/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp b/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp index 00298cb..20b205a 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp
@@ -335,18 +335,17 @@ const char* CompileOptionsString(v8::ScriptCompiler::CompileOptions options) { switch (options) { case v8::ScriptCompiler::kNoCompileOptions: - return "no"; + return "code"; case v8::ScriptCompiler::kProduceParserCache: return "parser"; case v8::ScriptCompiler::kConsumeParserCache: return "parser"; - case v8::ScriptCompiler::kProduceCodeCache: - return "code"; - case v8::ScriptCompiler::kProduceFullCodeCache: - return "full code"; case v8::ScriptCompiler::kConsumeCodeCache: return "code"; - default: + case v8::ScriptCompiler::kEagerCompile: + return "full code"; + case v8::ScriptCompiler::kProduceCodeCache: + case v8::ScriptCompiler::kProduceFullCodeCache: NOTREACHED(); } NOTREACHED(); @@ -1057,8 +1056,8 @@ int cache_size) : produce_options(produce_options), cache_size(cache_size) { DCHECK(produce_options == v8::ScriptCompiler::kProduceParserCache || - produce_options == v8::ScriptCompiler::kProduceCodeCache || - produce_options == v8::ScriptCompiler::kProduceFullCodeCache); + produce_options == v8::ScriptCompiler::kNoCompileOptions || + produce_options == v8::ScriptCompiler::kEagerCompile); } InspectorCompileScriptEvent::V8CacheResult::ConsumeResult::ConsumeResult(
diff --git a/third_party/WebKit/Source/core/inspector/browser_protocol.json b/third_party/WebKit/Source/core/inspector/browser_protocol.json index a19cf00..377abc97 100644 --- a/third_party/WebKit/Source/core/inspector/browser_protocol.json +++ b/third_party/WebKit/Source/core/inspector/browser_protocol.json
@@ -6886,45 +6886,6 @@ "moderate", "critical" ] - }, - { - "id": "SamplingProfileNode", - "description": "Heap profile sample.", - "type": "object", - "properties": [ - { - "name": "size", - "description": "Size of the sampled allocation.", - "type": "number" - }, - { - "name": "count", - "description": "Number of sampled allocations of that size.", - "type": "number" - }, - { - "name": "stack", - "description": "Execution stack at the point of allocation.", - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - { - "id": "SamplingProfile", - "description": "Array of heap profile samples.", - "type": "object", - "properties": [ - { - "name": "samples", - "type": "array", - "items": { - "$ref": "SamplingProfileNode" - } - } - ] } ], "commands": [ @@ -6969,38 +6930,6 @@ "$ref": "PressureLevel" } ] - }, - { - "name": "startSampling", - "description": "Start collecting native memory profile.", - "parameters": [ - { - "name": "samplingInterval", - "description": "Average number of bytes between samples.", - "optional": true, - "type": "integer" - }, - { - "name": "suppressRandomness", - "description": "Do not randomize intervals between samples.", - "optional": true, - "type": "boolean" - } - ] - }, - { - "name": "stopSampling", - "description": "Stop collecting native memory profile." - }, - { - "name": "getSamplingProfile", - "description": "Retrieve collected native memory profile.", - "returns": [ - { - "name": "profile", - "$ref": "SamplingProfile" - } - ] } ] },
diff --git a/third_party/WebKit/Source/core/inspector/browser_protocol.pdl b/third_party/WebKit/Source/core/inspector/browser_protocol.pdl index 2ce44ef..20af43d7 100644 --- a/third_party/WebKit/Source/core/inspector/browser_protocol.pdl +++ b/third_party/WebKit/Source/core/inspector/browser_protocol.pdl
@@ -3151,37 +3151,6 @@ # Memory pressure level of the notification. PressureLevel level - # Start collecting native memory profile. - command startSampling - parameters - # Average number of bytes between samples. - optional integer samplingInterval - # Do not randomize intervals between samples. - optional boolean suppressRandomness - - # Stop collecting native memory profile. - command stopSampling - - # Retrieve collected native memory profile. - command getSamplingProfile - returns - SamplingProfile profile - - # Heap profile sample. - type SamplingProfileNode extends object - properties - # Size of the sampled allocation. - number size - # Number of sampled allocations of that size. - number count - # Execution stack at the point of allocation. - array of string stack - - # Array of heap profile samples. - type SamplingProfile extends object - properties - array of SamplingProfileNode samples - # Network domain allows tracking network activities of the page. It exposes information about http, # file, data and other requests and responses, their headers, bodies, timing, etc. domain Network
diff --git a/third_party/WebKit/Source/core/inspector/inspector_protocol_config.json b/third_party/WebKit/Source/core/inspector/inspector_protocol_config.json index 0a1aa05..7cc7e78 100644 --- a/third_party/WebKit/Source/core/inspector/inspector_protocol_config.json +++ b/third_party/WebKit/Source/core/inspector/inspector_protocol_config.json
@@ -69,7 +69,7 @@ }, { "domain": "Memory", - "include": ["getDOMCounters", "prepareForLeakDetection", "startSampling", "stopSampling", "getSamplingProfile"], + "include": ["getDOMCounters", "prepareForLeakDetection"], "async": ["prepareForLeakDetection"] }, {
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlock.cpp b/third_party/WebKit/Source/core/layout/LayoutBlock.cpp index 0d245be..3d19660d 100644 --- a/third_party/WebKit/Source/core/layout/LayoutBlock.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutBlock.cpp
@@ -51,6 +51,7 @@ #include "core/layout/api/LineLayoutItem.h" #include "core/layout/line/InlineTextBox.h" #include "core/page/Page.h" +#include "core/page/scrolling/RootScrollerController.h" #include "core/paint/BlockPaintInvalidator.h" #include "core/paint/BlockPainter.h" #include "core/paint/ObjectPaintInvalidator.h" @@ -409,6 +410,10 @@ void LayoutBlock::UpdateAfterLayout() { InvalidateStickyConstraints(); + + if (RuntimeEnabledFeatures::ImplicitRootScrollerEnabled() && GetNode()) + GetDocument().GetRootScrollerController().ConsiderForImplicit(*GetNode()); + LayoutBox::UpdateAfterLayout(); }
diff --git a/third_party/WebKit/Source/core/layout/LayoutBox.cpp b/third_party/WebKit/Source/core/layout/LayoutBox.cpp index 2482b93..64ea6dd 100644 --- a/third_party/WebKit/Source/core/layout/LayoutBox.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutBox.cpp
@@ -58,7 +58,6 @@ #include "core/layout/shapes/ShapeOutsideInfo.h" #include "core/page/AutoscrollController.h" #include "core/page/Page.h" -#include "core/page/scrolling/RootScrollerController.h" #include "core/page/scrolling/RootScrollerUtil.h" #include "core/page/scrolling/ScrollingCoordinator.h" #include "core/page/scrolling/SnapCoordinator.h"
diff --git a/third_party/WebKit/Source/core/layout/LayoutIFrame.cpp b/third_party/WebKit/Source/core/layout/LayoutIFrame.cpp index 73abc66..f6f15609 100644 --- a/third_party/WebKit/Source/core/layout/LayoutIFrame.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutIFrame.cpp
@@ -26,6 +26,7 @@ #include "core/layout/LayoutIFrame.h" #include "core/layout/LayoutAnalyzer.h" +#include "core/page/scrolling/RootScrollerController.h" namespace blink { @@ -60,4 +61,11 @@ ClearNeedsLayout(); } +void LayoutIFrame::UpdateAfterLayout() { + if (RuntimeEnabledFeatures::ImplicitRootScrollerEnabled() && GetNode()) + GetDocument().GetRootScrollerController().ConsiderForImplicit(*GetNode()); + + LayoutEmbeddedContent::UpdateAfterLayout(); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/LayoutIFrame.h b/third_party/WebKit/Source/core/layout/LayoutIFrame.h index 820aabb..81d404a 100644 --- a/third_party/WebKit/Source/core/layout/LayoutIFrame.h +++ b/third_party/WebKit/Source/core/layout/LayoutIFrame.h
@@ -41,6 +41,7 @@ bool IsInlineBlockOrInlineTable() const override; void UpdateLayout() override; + void UpdateAfterLayout() override; bool IsOfType(LayoutObjectType type) const override { return type == kLayoutObjectLayoutIFrame ||
diff --git a/third_party/WebKit/Source/core/layout/LayoutInline.cpp b/third_party/WebKit/Source/core/layout/LayoutInline.cpp index d958b72..4698ad26 100644 --- a/third_party/WebKit/Source/core/layout/LayoutInline.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutInline.cpp
@@ -848,6 +848,14 @@ } LayoutPoint LayoutInline::FirstLineBoxTopLeft() const { + if (const NGPhysicalBoxFragment* box_fragment = + EnclosingBlockFlowFragmentOf(*this)) { + const auto& fragments = + NGInlineFragmentTraversal::SelfFragmentsOf(*box_fragment, this); + if (fragments.IsEmpty()) + return LayoutPoint(); + return fragments.front().offset_to_container_box.ToLayoutPoint(); + } if (InlineBox* first_box = FirstLineBoxIncludingCulling()) return first_box->Location(); return LayoutPoint();
diff --git a/third_party/WebKit/Source/core/layout/LayoutScrollbarPart.cpp b/third_party/WebKit/Source/core/layout/LayoutScrollbarPart.cpp index 1638a3b..edea234 100644 --- a/third_party/WebKit/Source/core/layout/LayoutScrollbarPart.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutScrollbarPart.cpp
@@ -146,11 +146,14 @@ SetWidth(LayoutUnit(std::max(min_width, std::min(max_width, w)))); // Buttons and track pieces can all have margins along the axis of the - // scrollbar. - SetMarginLeft( - MinimumValueForLength(Style()->MarginLeft(), LayoutUnit(visible_size))); - SetMarginRight( - MinimumValueForLength(Style()->MarginRight(), LayoutUnit(visible_size))); + // scrollbar. Values are rounded because scrollbar parts need to be rendered + // at device pixel boundaries. + SetMarginLeft(LayoutUnit( + MinimumValueForLength(Style()->MarginLeft(), LayoutUnit(visible_size)) + .Round())); + SetMarginRight(LayoutUnit( + MinimumValueForLength(Style()->MarginRight(), LayoutUnit(visible_size)) + .Round())); } void LayoutScrollbarPart::ComputeScrollbarHeight() { @@ -174,11 +177,14 @@ SetHeight(LayoutUnit(std::max(min_height, std::min(max_height, h)))); // Buttons and track pieces can all have margins along the axis of the - // scrollbar. - SetMarginTop( - MinimumValueForLength(Style()->MarginTop(), LayoutUnit(visible_size))); - SetMarginBottom( - MinimumValueForLength(Style()->MarginBottom(), LayoutUnit(visible_size))); + // scrollbar. Values are rounded because scrollbar parts need to be rendered + // at device pixel boundaries. + SetMarginTop(LayoutUnit( + MinimumValueForLength(Style()->MarginTop(), LayoutUnit(visible_size)) + .Round())); + SetMarginBottom(LayoutUnit( + MinimumValueForLength(Style()->MarginBottom(), LayoutUnit(visible_size)) + .Round())); } void LayoutScrollbarPart::ComputePreferredLogicalWidths() {
diff --git a/third_party/WebKit/Source/core/layout/ScrollbarsTest.cpp b/third_party/WebKit/Source/core/layout/ScrollbarsTest.cpp index 634ca6d6..574de644 100644 --- a/third_party/WebKit/Source/core/layout/ScrollbarsTest.cpp +++ b/third_party/WebKit/Source/core/layout/ScrollbarsTest.cpp
@@ -9,6 +9,7 @@ #include "core/frame/WebLocalFrameImpl.h" #include "core/input/EventHandler.h" #include "core/inspector/DevToolsEmulator.h" +#include "core/layout/LayoutScrollbarPart.h" #include "core/layout/LayoutView.h" #include "core/page/Page.h" #include "core/paint/PaintLayerScrollableArea.h" @@ -1658,6 +1659,95 @@ EXPECT_TRUE(layout_viewport->HorizontalScrollbar()); } +class ScrollbarTrackMarginsTest : public ScrollbarsTest { + public: + void PrepareTest(const String& track_style) { + WebView().Resize(WebSize(200, 200)); + + SimRequest request("https://example.com/test.html", "text/html"); + LoadURL("https://example.com/test.html"); + request.Complete(R"HTML( + <!DOCTYPE html> + <style> + ::-webkit-scrollbar { + width: 10px; + })HTML" + track_style + + R"HTML( + #d1 { + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + overflow-x:scroll; + overflow-y:scroll; + } + </style> + <div id='d1'/> + )HTML"); + + // No DCHECK failure. Issue 801123. + Compositor().BeginFrame(); + + Element* div = GetDocument().getElementById("d1"); + ASSERT_TRUE(div); + + ScrollableArea* div_scrollable = + ToLayoutBox(div->GetLayoutObject())->GetScrollableArea(); + + ASSERT_TRUE(div_scrollable->HorizontalScrollbar()); + LayoutScrollbar* horizontal_scrollbar = + ToLayoutScrollbar(div_scrollable->HorizontalScrollbar()); + horizontal_track_ = horizontal_scrollbar->GetPart(kTrackBGPart); + ASSERT_TRUE(horizontal_track_); + + ASSERT_TRUE(div_scrollable->VerticalScrollbar()); + LayoutScrollbar* vertical_scrollbar = + ToLayoutScrollbar(div_scrollable->VerticalScrollbar()); + vertical_track_ = vertical_scrollbar->GetPart(kTrackBGPart); + ASSERT_TRUE(vertical_track_); + } + + LayoutScrollbarPart* horizontal_track_ = nullptr; + LayoutScrollbarPart* vertical_track_ = nullptr; +}; + +INSTANTIATE_TEST_CASE_P(All, ScrollbarTrackMarginsTest, ::testing::Bool()); + +TEST_P(ScrollbarTrackMarginsTest, + CustomScrollbarFractionalMarginsWillNotCauseDCHECKFailure) { + PrepareTest(R"CSS( + ::-webkit-scrollbar-track { + margin-left: 10.2px; + margin-top: 20.4px; + margin-right: 30.6px; + margin-bottom: 40.8px; + })CSS"); + + EXPECT_EQ(10, horizontal_track_->MarginLeft()); + EXPECT_EQ(31, horizontal_track_->MarginRight()); + EXPECT_EQ(20, vertical_track_->MarginTop()); + EXPECT_EQ(41, vertical_track_->MarginBottom()); +} + +TEST_P(ScrollbarTrackMarginsTest, + CustomScrollbarScaledMarginsWillNotCauseDCHECKFailure) { + WebView().SetZoomFactorForDeviceScaleFactor(1.25f); + + PrepareTest(R"CSS( + ::-webkit-scrollbar-track { + margin-left: 11px; + margin-top: 21px; + margin-right: 31px; + margin-bottom: 41px; + })CSS"); + + EXPECT_EQ(14, horizontal_track_->MarginLeft()); + EXPECT_EQ(39, horizontal_track_->MarginRight()); + EXPECT_EQ(26, vertical_track_->MarginTop()); + EXPECT_EQ(51, vertical_track_->MarginBottom()); +} + } // namespace } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_box_state.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_box_state.cc index 137bd34..73ebbff 100644 --- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_box_state.cc +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_box_state.cc
@@ -119,6 +119,7 @@ // Compute box properties regardless of needs_box_fragment since close tag may // also set needs_box_fragment. + box->padding = item_result.padding; box->has_start_edge = item_result.has_edge; if (box->has_start_edge) { box->margin_inline_start = item_result.margins.inline_start; @@ -241,6 +242,7 @@ box_data_list_.push_back( BoxData{box->fragment_start, fragment_end, box->item, size}); BoxData& box_data = box_data_list_.back(); + box_data.padding = box->padding; if (box->has_start_edge) { box_data.has_line_left_edge = true; box_data.margin_line_left = box->margin_inline_start; @@ -441,6 +443,7 @@ size.inline_size += border_padding_line_left + border_padding_line_right; box.SetInlineSize(size.inline_size.ClampNegativeToZero()); box.SetBlockSize(size.block_size); + box.SetPadding(padding); for (unsigned i = fragment_start; i < fragment_end; i++) { NGLineBoxFragmentBuilder::Child& child = (*line_box)[i];
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_box_state.h b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_box_state.h index fa37027..8380241 100644 --- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_box_state.h +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_box_state.h
@@ -58,6 +58,7 @@ // is set. bool has_start_edge = false; bool has_end_edge = false; + NGBoxStrut padding; // |CreateBoxFragment()| needs margin, border+padding, and the sum of them. LayoutUnit margin_inline_start; LayoutUnit margin_inline_end; @@ -180,6 +181,7 @@ bool has_line_left_edge = false; bool has_line_right_edge = false; + NGBoxStrut padding; // |CreateBoxFragment()| needs margin, border+padding, and the sum of them. LayoutUnit margin_line_left; LayoutUnit margin_line_right;
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_item_result.h b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_item_result.h index e47ead6..0e90fa75 100644 --- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_item_result.h +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_item_result.h
@@ -47,8 +47,9 @@ // NGLayoutResult for atomic inline items. scoped_refptr<NGLayoutResult> layout_result; - // Margins for atomic inline items and open/close tags. + // Margins and padding for atomic inline items and open/close tags. NGBoxStrut margins; + NGBoxStrut padding; // Borders/padding for open tags. LayoutUnit borders_paddings_block_start;
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker.cc index e156753e..2e9df3c 100644 --- a/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker.cc +++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker.cc
@@ -574,6 +574,7 @@ DCHECK(item.Style()); item_result->margins = ComputeMarginsForVisualContainer(constraint_space_, *item.Style()); + item_result->padding = ComputePadding(constraint_space_, *item.Style()); item_result->inline_size += item_result->margins.InlineSum(); line_.position += item_result->inline_size; @@ -694,6 +695,7 @@ (style.HasMargin() && item_result->has_edge)) { NGBoxStrut borders = ComputeBorders(constraint_space_, style); NGBoxStrut paddings = ComputePadding(constraint_space_, style); + item_result->padding = paddings; item_result->borders_paddings_block_start = borders.block_start + paddings.block_start; item_result->borders_paddings_block_end =
diff --git a/third_party/WebKit/Source/core/layout/ng/layout_ng_block_flow.cc b/third_party/WebKit/Source/core/layout/ng/layout_ng_block_flow.cc index 8f37743..b3e3d92 100644 --- a/third_party/WebKit/Source/core/layout/ng/layout_ng_block_flow.cc +++ b/third_party/WebKit/Source/core/layout/ng/layout_ng_block_flow.cc
@@ -106,6 +106,8 @@ container_builder.SetInlineSize(containing_block_logical_width); container_builder.SetBlockSize(containing_block_logical_height); + container_builder.SetPadding( + ComputePadding(*constraint_space, *container_style)); // Determine static position.
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc index 6bc6fa3b..ff538d8 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
@@ -498,6 +498,7 @@ container_builder_.SetEndMarginStrut(end_margin_strut); container_builder_.SetIntrinsicBlockSize(intrinsic_block_size_); + container_builder_.SetPadding(ComputePadding(ConstraintSpace(), Style())); // We only finalize for fragmentation if the fragment has a BFC offset. This // may occur with a zero block size fragment. We need to know the BFC offset
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc index bac71ad..317dc35 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc
@@ -563,6 +563,7 @@ builder.SetIsOldLayoutRoot(); builder.SetInlineSize(box_size.inline_size); builder.SetBlockSize(box_size.block_size); + builder.SetPadding(ComputePadding(constraint_space, box_->StyleRef())); // For now we copy the exclusion space straight through, this is incorrect // but needed as not all elements which participate in a BFC are switched
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_column_layout_algorithm.cc b/third_party/WebKit/Source/core/layout/ng/ng_column_layout_algorithm.cc index 933b688..ea7f111 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_column_layout_algorithm.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_column_layout_algorithm.cc
@@ -187,6 +187,7 @@ } container_builder_.SetInlineSize(border_box_size.inline_size); container_builder_.SetBlockSize(border_box_size.block_size); + container_builder_.SetPadding(ComputePadding(ConstraintSpace(), Style())); return container_builder_.ToBoxFragment(); }
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc index 71c5f2d2..ac8759b 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc
@@ -51,6 +51,11 @@ return *this; } +NGFragmentBuilder& NGFragmentBuilder::SetPadding(const NGBoxStrut& padding) { + padding_ = padding; + return *this; +} + NGContainerFragmentBuilder& NGFragmentBuilder::AddChild( scoped_refptr<NGPhysicalFragment> child, const NGLogicalOffset& child_offset) { @@ -268,6 +273,8 @@ scoped_refptr<NGPhysicalBoxFragment> fragment = base::AdoptRef(new NGPhysicalBoxFragment( layout_object_, Style(), physical_size, children_, + padding_.ConvertToPhysical(GetWritingMode(), Direction()) + .SnapToDevicePixels(), contents_visual_rect, baselines_, BoxType(), is_old_layout_root_, border_edges_.ToPhysical(GetWritingMode()), std::move(break_token)));
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h index d25e6247..96a113c6 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h
@@ -6,6 +6,7 @@ #define NGFragmentBuilder_h #include "core/layout/ng/geometry/ng_border_edges.h" +#include "core/layout/ng/geometry/ng_box_strut.h" #include "core/layout/ng/geometry/ng_physical_offset_rect.h" #include "core/layout/ng/geometry/ng_physical_rect.h" #include "core/layout/ng/inline/ng_baseline.h" @@ -44,6 +45,7 @@ NGLogicalSize Size() const final { return {inline_size_, block_size_}; } NGFragmentBuilder& SetIntrinsicBlockSize(LayoutUnit); + NGFragmentBuilder& SetPadding(const NGBoxStrut&); using NGContainerFragmentBuilder::AddChild; @@ -185,6 +187,7 @@ LayoutObject* layout_object_; LayoutUnit intrinsic_block_size_; + NGBoxStrut padding_; NGPhysicalFragment::NGBoxType box_type_; bool is_old_layout_root_;
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_page_layout_algorithm.cc b/third_party/WebKit/Source/core/layout/ng/ng_page_layout_algorithm.cc index 476ad7f..262e2a6 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_page_layout_algorithm.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_page_layout_algorithm.cc
@@ -72,6 +72,7 @@ border_box_size.block_size = ComputeBlockSizeForFragment( ConstraintSpace(), Style(), intrinsic_block_size); container_builder_.SetBlockSize(border_box_size.block_size); + container_builder_.SetPadding(ComputePadding(ConstraintSpace(), Style())); NGOutOfFlowLayoutPart(&container_builder_, Node().IsAbsoluteContainer(), Node().IsFixedContainer(), Node().GetScrollbarSizes(),
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.cc b/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.cc index f9b2dbf..0e2c06e4 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.cc
@@ -14,6 +14,7 @@ const ComputedStyle& style, NGPhysicalSize size, Vector<scoped_refptr<NGPhysicalFragment>>& children, + const NGPixelSnappedPhysicalBoxStrut& padding, const NGPhysicalOffsetRect& contents_visual_rect, Vector<NGBaseline>& baselines, NGBoxType box_type, @@ -27,7 +28,8 @@ children, contents_visual_rect, std::move(break_token)), - baselines_(std::move(baselines)) { + baselines_(std::move(baselines)), + padding_(padding) { DCHECK(baselines.IsEmpty()); // Ensure move semantics is used. box_type_ = box_type; is_old_layout_root_ = is_old_layout_root; @@ -105,9 +107,9 @@ Vector<NGBaseline> baselines_copy(baselines_); scoped_refptr<NGPhysicalFragment> physical_fragment = base::AdoptRef(new NGPhysicalBoxFragment( - layout_object_, Style(), size_, children_copy, contents_visual_rect_, - baselines_copy, BoxType(), is_old_layout_root_, border_edge_, - break_token_)); + layout_object_, Style(), size_, children_copy, padding_, + contents_visual_rect_, baselines_copy, BoxType(), is_old_layout_root_, + border_edge_, break_token_)); return physical_fragment; }
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.h b/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.h index 8cd7064..501e4ad 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.h
@@ -6,6 +6,7 @@ #define NGPhysicalBoxFragment_h #include "core/CoreExport.h" +#include "core/layout/ng/geometry/ng_box_strut.h" #include "core/layout/ng/inline/ng_baseline.h" #include "core/layout/ng/ng_physical_container_fragment.h" @@ -19,6 +20,7 @@ const ComputedStyle& style, NGPhysicalSize size, Vector<scoped_refptr<NGPhysicalFragment>>& children, + const NGPixelSnappedPhysicalBoxStrut& padding, const NGPhysicalOffsetRect& contents_visual_rect, Vector<NGBaseline>& baselines, NGBoxType box_type, @@ -28,6 +30,8 @@ const NGBaseline* Baseline(const NGBaselineRequest&) const; + const NGPixelSnappedPhysicalBoxStrut& Padding() const { return padding_; } + bool HasSelfPaintingLayer() const; bool ChildrenInline() const; @@ -47,6 +51,7 @@ private: Vector<NGBaseline> baselines_; + NGPixelSnappedPhysicalBoxStrut padding_; }; DEFINE_TYPE_CASTS(NGPhysicalBoxFragment,
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceContainer.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceContainer.cpp index 71b6cd3..e9243c8 100644 --- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceContainer.cpp +++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceContainer.cpp
@@ -27,17 +27,22 @@ namespace blink { -static inline SVGTreeScopeResources& SvgTreeScopeResourcesFromElement( - Element* element) { - DCHECK(element); - return element->GetTreeScope().EnsureSVGTreeScopedResources(); +namespace { + +SVGTreeScopeResources::Resource* ResourceForContainer( + const LayoutSVGResourceContainer& resource_container) { + const SVGElement& element = *resource_container.GetElement(); + return element.GetTreeScope() + .EnsureSVGTreeScopedResources() + .ExistingResourceForId(element.GetIdAttribute()); } +} // namespace + LayoutSVGResourceContainer::LayoutSVGResourceContainer(SVGElement* node) : LayoutSVGHiddenContainer(node), is_in_layout_(false), invalidation_mask_(0), - registered_(false), is_invalidating_(false) {} LayoutSVGResourceContainer::~LayoutSVGResourceContainer() = default; @@ -68,45 +73,42 @@ void LayoutSVGResourceContainer::WillBeDestroyed() { LayoutSVGHiddenContainer::WillBeDestroyed(); - SvgTreeScopeResourcesFromElement(GetElement()) - .RemoveResource(GetElement()->GetIdAttribute(), this); - DCHECK(clients_.IsEmpty()); + // The resource is being torn down. If we have any clients, move those to be + // pending on the resource (if one exists.) + if (SVGTreeScopeResources::Resource* resource = ResourceForContainer(*this)) + MakeClientsPending(*resource); } void LayoutSVGResourceContainer::StyleDidChange( StyleDifference diff, const ComputedStyle* old_style) { LayoutSVGHiddenContainer::StyleDidChange(diff, old_style); - SvgTreeScopeResourcesFromElement(GetElement()) - .UpdateResource(GetElement()->GetIdAttribute(), this); + // The resource has (read: may have) been attached. Notify any pending + // clients that they can now try to add themselves as clients to the + // resource. + if (SVGTreeScopeResources::Resource* resource = ResourceForContainer(*this)) { + if (resource->Target() == GetElement()) + resource->NotifyResourceClients(); + } } -void LayoutSVGResourceContainer::DetachAllClients(const AtomicString& to_id) { +void LayoutSVGResourceContainer::MakeClientsPending( + SVGTreeScopeResources::Resource& resource) { RemoveAllClientsFromCache(); for (auto* client : clients_) { - // Unlink the resource from the client's SVGResources. (The actual - // removal will be signaled after processing all the clients.) + // Unlink the resource from the client's SVGResources. SVGResources* resources = SVGResourcesCache::CachedResourcesForLayoutObject(client); // Or else the client wouldn't be in the list in the first place. DCHECK(resources); resources->ResourceDestroyed(this); - // Add a pending resolution based on the id of the old resource. - Element* client_element = ToElement(client->GetNode()); - SvgTreeScopeResourcesFromElement(client_element) - .AddPendingResource(to_id, *client_element); + resource.AddWatch(ToSVGElement(*client->GetNode())); } clients_.clear(); } -void LayoutSVGResourceContainer::IdChanged(const AtomicString& old_id, - const AtomicString& new_id) { - SvgTreeScopeResourcesFromElement(GetElement()) - .UpdateResource(old_id, new_id, this); -} - void LayoutSVGResourceContainer::MarkAllClientsForInvalidation( InvalidationMode mode) { if (is_invalidating_) @@ -177,10 +179,11 @@ ClearInvalidationMask(); } -void LayoutSVGResourceContainer::RemoveClient(LayoutObject* client) { +bool LayoutSVGResourceContainer::RemoveClient(LayoutObject* client) { DCHECK(client); RemoveClientFromCache(client, false); clients_.erase(client); + return clients_.IsEmpty(); } void LayoutSVGResourceContainer::InvalidateCacheAndMarkForLayout(
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceContainer.h b/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceContainer.h index 86f9b41..052a2ca5 100644 --- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceContainer.h +++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceContainer.h
@@ -21,6 +21,7 @@ #define LayoutSVGResourceContainer_h #include "core/layout/svg/LayoutSVGHiddenContainer.h" +#include "core/svg/SVGTreeScopeResources.h" namespace blink { @@ -61,8 +62,10 @@ resource_type == kRadialGradientResourceType; } - void IdChanged(const AtomicString& old_id, const AtomicString& new_id); - void DetachAllClients(const AtomicString& to_id); + // Detach all clients from this resource, and add them as watches to the tree + // scope's resource entry (the argument.) + void MakeClientsPending(SVGTreeScopeResources::Resource&); + bool HasClients() const { return !clients_.IsEmpty(); } void InvalidateCacheAndMarkForLayout(SubtreeLayoutScope* = nullptr); @@ -94,23 +97,16 @@ bool is_in_layout_; private: - friend class SVGTreeScopeResources; - // The m_registered flag is updated by SVGTreeScopeResources, and indicates - // that this resource is the one that is resident in the id->resource map. - void SetRegistered(bool registered) { registered_ = registered; } - bool IsRegistered() const { return registered_; } - friend class SVGResourcesCache; void AddClient(LayoutObject*); - void RemoveClient(LayoutObject*); + bool RemoveClient(LayoutObject*); - // Track global (markAllClientsForInvalidation) invals to avoid redundant - // crawls. + // Track global (markAllClientsForInvalidation) invalidations to avoid + // redundant crawls. unsigned invalidation_mask_ : 8; - unsigned registered_ : 1; unsigned is_invalidating_ : 1; - // 22 padding bits available + // 23 padding bits available HashSet<LayoutObject*> clients_; };
diff --git a/third_party/WebKit/Source/core/layout/svg/SVGResources.cpp b/third_party/WebKit/Source/core/layout/svg/SVGResources.cpp index 5b0172de..ec442220 100644 --- a/third_party/WebKit/Source/core/layout/svg/SVGResources.cpp +++ b/third_party/WebKit/Source/core/layout/svg/SVGResources.cpp
@@ -157,12 +157,15 @@ ContainerType* AttachToResource(SVGTreeScopeResources& tree_scope_resources, const AtomicString& id, SVGElement& element) { - if (LayoutSVGResourceContainer* container = - tree_scope_resources.ResourceById(id)) { + SVGTreeScopeResources::Resource* resource = + tree_scope_resources.ResourceForId(id); + if (!resource) + return nullptr; + if (LayoutSVGResourceContainer* container = resource->ResourceContainer()) { if (IsResourceOfType<ContainerType>(container)) return static_cast<ContainerType*>(container); } - tree_scope_resources.AddPendingResource(id, element); + resource->AddWatch(element); return nullptr; } } @@ -279,6 +282,22 @@ : std::move(resources); } +void SVGResources::RemoveUnreferencedResources(const LayoutObject& object) { + SVGTreeScopeResources& tree_scope_resources = + ToSVGElement(*object.GetNode()) + .TreeScopeForIdResolution() + .EnsureSVGTreeScopedResources(); + tree_scope_resources.RemoveUnreferencedResources(); +} + +void SVGResources::RemoveWatchesForElement(Element& element) { + SECURITY_DCHECK(element.IsSVGElement()); + SVGElement& svg_element = ToSVGElement(element); + SVGTreeScopeResources& tree_scope_resources = + svg_element.TreeScopeForIdResolution().EnsureSVGTreeScopedResources(); + tree_scope_resources.RemoveWatchesForElement(svg_element); +} + void SVGResources::LayoutIfNeeded() { if (clipper_filter_masker_data_) { if (LayoutSVGResourceClipper* clipper =
diff --git a/third_party/WebKit/Source/core/layout/svg/SVGResources.h b/third_party/WebKit/Source/core/layout/svg/SVGResources.h index b8b275e..635c5515 100644 --- a/third_party/WebKit/Source/core/layout/svg/SVGResources.h +++ b/third_party/WebKit/Source/core/layout/svg/SVGResources.h
@@ -29,6 +29,7 @@ namespace blink { class ComputedStyle; +class Element; class LayoutObject; class LayoutSVGResourceClipper; class LayoutSVGResourceContainer; @@ -47,6 +48,10 @@ static std::unique_ptr<SVGResources> BuildResources(const LayoutObject*, const ComputedStyle&); + + static void RemoveWatchesForElement(Element&); + static void RemoveUnreferencedResources(const LayoutObject&); + void LayoutIfNeeded(); static bool SupportsMarkers(const SVGElement&);
diff --git a/third_party/WebKit/Source/core/layout/svg/SVGResourcesCache.cpp b/third_party/WebKit/Source/core/layout/svg/SVGResourcesCache.cpp index 9dd812a..ea821c63 100644 --- a/third_party/WebKit/Source/core/layout/svg/SVGResourcesCache.cpp +++ b/third_party/WebKit/Source/core/layout/svg/SVGResourcesCache.cpp
@@ -76,8 +76,13 @@ HashSet<LayoutSVGResourceContainer*> resource_set; resources->BuildSetOfResources(resource_set); + bool did_empty_client_set = false; for (auto* resource_container : resource_set) - resource_container->RemoveClient(object); + did_empty_client_set |= resource_container->RemoveClient(object); + + // Remove any registrations that became empty after the above. + if (did_empty_client_set) + SVGResources::RemoveUnreferencedResources(*object); } static inline SVGResourcesCache& ResourcesCache(Document& document) { @@ -156,6 +161,26 @@ layout_object, needs_layout); } +void SVGResourcesCache::ResourceReferenceChanged(LayoutObject& layout_object) { + DCHECK(layout_object.IsSVG()); + DCHECK(layout_object.GetNode()); + DCHECK(layout_object.GetNode()->IsSVGElement()); + + if (!layout_object.Parent()) + return; + + // Only LayoutObjects that can actually have resources should be pending and + // hence be able to call this method. + DCHECK(LayoutObjectCanHaveResources(&layout_object)); + + SVGResourcesCache& cache = ResourcesCache(layout_object.GetDocument()); + cache.RemoveResourcesFromLayoutObject(&layout_object); + cache.AddResourcesFromLayoutObject(&layout_object, layout_object.StyleRef()); + + LayoutSVGResourceContainer::MarkForLayoutAndParentResourceInvalidation( + &layout_object, true); +} + void SVGResourcesCache::ClientWasAddedToTree(LayoutObject* layout_object, const ComputedStyle& new_style) { if (!layout_object->GetNode())
diff --git a/third_party/WebKit/Source/core/layout/svg/SVGResourcesCache.h b/third_party/WebKit/Source/core/layout/svg/SVGResourcesCache.h index ca5f5ef..d462dd5 100644 --- a/third_party/WebKit/Source/core/layout/svg/SVGResourcesCache.h +++ b/third_party/WebKit/Source/core/layout/svg/SVGResourcesCache.h
@@ -30,7 +30,6 @@ class LayoutObject; class ComputedStyle; -class LayoutSVGResourceContainer; class SVGResources; class SVGResourcesCache { @@ -61,6 +60,10 @@ StyleDifference, const ComputedStyle& new_style); + // Called when the target element of a resource referenced by the + // LayoutObject may have changed. + static void ResourceReferenceChanged(LayoutObject&); + class TemporaryStyleScope { STACK_ALLOCATED();
diff --git a/third_party/WebKit/Source/core/page/scrolling/RootScrollerController.cpp b/third_party/WebKit/Source/core/page/scrolling/RootScrollerController.cpp index b802b35..8fceeb55 100644 --- a/third_party/WebKit/Source/core/page/scrolling/RootScrollerController.cpp +++ b/third_party/WebKit/Source/core/page/scrolling/RootScrollerController.cpp
@@ -8,10 +8,12 @@ #include "core/dom/Document.h" #include "core/dom/Element.h" #include "core/frame/LocalFrameView.h" +#include "core/fullscreen/DocumentFullscreen.h" #include "core/html/HTMLFrameOwnerElement.h" #include "core/layout/LayoutBox.h" #include "core/layout/LayoutEmbeddedContent.h" #include "core/layout/LayoutView.h" +#include "core/page/ChromeClient.h" #include "core/page/Page.h" #include "core/page/scrolling/RootScrollerUtil.h" #include "core/page/scrolling/TopDocumentRootScrollerController.h" @@ -46,7 +48,7 @@ LayoutRect bounding_box(quads[0].BoundingBox()); return bounding_box.Location() == LayoutPoint::Zero() && - bounding_box.Size() == top_document.GetLayoutView()->Size(); + bounding_box.Size() == top_document.GetLayoutView()->GetLayoutSize(); } } // namespace @@ -59,12 +61,15 @@ RootScrollerController::RootScrollerController(Document& document) : document_(&document), effective_root_scroller_(&document), - document_has_document_element_(false) {} + document_has_document_element_(false), + needs_apply_properties_(false) {} void RootScrollerController::Trace(blink::Visitor* visitor) { visitor->Trace(document_); visitor->Trace(root_scroller_); visitor->Trace(effective_root_scroller_); + visitor->Trace(implicit_candidates_); + visitor->Trace(implicit_root_scroller_); } void RootScrollerController::Set(Element* new_root_scroller) { @@ -104,13 +109,31 @@ } } +void RootScrollerController::DidUpdateIFrameFrameView( + HTMLFrameOwnerElement& element) { + if (&element != effective_root_scroller_.Get()) + return; + + // Make sure we do a layout so we try to recalculate the effective root + // scroller. Ensure properties are applied even if the effective root + // scroller doesn't change. + needs_apply_properties_ = true; + document_->GetFrame()->View()->SetNeedsLayout(); +} + void RootScrollerController::RecomputeEffectiveRootScroller() { - bool root_scroller_valid = - root_scroller_ && IsValidRootScroller(*root_scroller_); + ProcessImplicitCandidates(); Node* new_effective_root_scroller = document_; - if (root_scroller_valid) - new_effective_root_scroller = root_scroller_; + + if (!DocumentFullscreen::fullscreenElement(*document_)) { + bool root_scroller_valid = + root_scroller_ && IsValidRootScroller(*root_scroller_); + if (root_scroller_valid) + new_effective_root_scroller = root_scroller_; + else if (implicit_root_scroller_) + new_effective_root_scroller = implicit_root_scroller_; + } // TODO(bokan): This is a terrible hack but required because the viewport // apply scroll works on Elements rather than Nodes. If we're going from @@ -123,8 +146,12 @@ document_has_document_element_ = document_->documentElement(); if (old_has_document_element || !document_has_document_element_) { - if (effective_root_scroller_ == new_effective_root_scroller) + if (effective_root_scroller_ == new_effective_root_scroller) { + if (needs_apply_properties_) + ApplyRootScrollerProperties(*effective_root_scroller_); + return; + } } Node* old_effective_root_scroller = effective_root_scroller_; @@ -144,20 +171,51 @@ if (!element.GetLayoutObject()) return false; + // Ignore anything inside a FlowThread (multi-col, paginated, etc.). + if (element.GetLayoutObject()->IsInsideFlowThread()) + return false; + if (!element.GetLayoutObject()->HasOverflowClip() && !element.IsFrameOwnerElement()) return false; + if (element.IsFrameOwnerElement() && + !ToHTMLFrameOwnerElement(&element)->OwnedEmbeddedContentView()) + return false; + if (!FillsViewport(element)) return false; return true; } -void RootScrollerController::ApplyRootScrollerProperties(Node& node) const { +bool RootScrollerController::IsValidImplicit(const Element& element) const { + // Valid implicit root scroller are a subset of valid root scrollers. + if (!IsValidRootScroller(element)) + return false; + + // Valid iframes can always be implicitly promoted. + if (element.IsFrameOwnerElement()) + return true; + + const ComputedStyle* style = element.GetLayoutObject()->Style(); + if (!style) + return false; + + // Regular Elements must have overflow: auto or scroll. + return style->OverflowX() == EOverflow::kAuto || + style->OverflowX() == EOverflow::kScroll || + style->OverflowY() == EOverflow::kAuto || + style->OverflowY() == EOverflow::kScroll; +} + +void RootScrollerController::ApplyRootScrollerProperties(Node& node) { DCHECK(document_->GetFrame()); DCHECK(document_->GetFrame()->View()); + if (&node == effective_root_scroller_) + needs_apply_properties_ = false; + // If the node has been removed from the Document, we shouldn't be touching // anything related to the Frame- or Layout- hierarchies. if (!node.IsInTreeScope()) @@ -169,7 +227,7 @@ if (frame_owner->ContentFrame()->IsLocalFrame()) { LocalFrameView* frame_view = - ToLocalFrame(frame_owner->ContentFrame())->View(); + ToLocalFrameView(frame_owner->OwnedEmbeddedContentView()); bool is_root_scroller = &EffectiveRootScroller() == &node; @@ -207,6 +265,41 @@ child_view->SetLayoutSize(document_->GetFrame()->View()->GetLayoutSize()); } +void RootScrollerController::ProcessImplicitCandidates() { + if (!RuntimeEnabledFeatures::ImplicitRootScrollerEnabled()) + return; + + Element* highest_z_element = nullptr; + bool highest_is_ambiguous = false; + + HeapHashSet<WeakMember<Element>> copy(implicit_candidates_); + for (auto& element : copy) { + if (!IsValidImplicit(*element)) { + implicit_candidates_.erase(element); + continue; + } + + if (!highest_z_element) { + highest_z_element = element; + } else { + int element_z = element->GetLayoutObject()->Style()->ZIndex(); + int highest_z = highest_z_element->GetLayoutObject()->Style()->ZIndex(); + + if (element_z > highest_z) { + highest_z_element = element; + highest_is_ambiguous = false; + } else if (element_z == highest_z) { + highest_is_ambiguous = true; + } + } + } + + if (highest_is_ambiguous) + implicit_root_scroller_ = nullptr; + else + implicit_root_scroller_ = highest_z_element; +} + PaintLayer* RootScrollerController::RootScrollerPaintLayer() const { return RootScrollerUtil::PaintLayerForRootScroller(effective_root_scroller_); } @@ -227,4 +320,19 @@ page->GlobalRootScrollerController().DidChangeRootScroller(); } +void RootScrollerController::ConsiderForImplicit(Node& node) { + DCHECK(RuntimeEnabledFeatures::ImplicitRootScrollerEnabled()); + + if (!node.IsElementNode()) + return; + + if (!IsValidImplicit(ToElement(node))) + return; + + if (document_->GetPage()->GetChromeClient().IsPopup()) + return; + + implicit_candidates_.insert(&ToElement(node)); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/core/page/scrolling/RootScrollerController.h b/third_party/WebKit/Source/core/page/scrolling/RootScrollerController.h index 1989f67a..c8d68522 100644 --- a/third_party/WebKit/Source/core/page/scrolling/RootScrollerController.h +++ b/third_party/WebKit/Source/core/page/scrolling/RootScrollerController.h
@@ -74,6 +74,11 @@ // rely on DidUpdateLayout. void DidResizeFrameView(); + // Called when an iframe in this document has an updated FrameView (e.g. + // FrameView removed, swapped, etc.) so that we can recompute the effective + // root scroller and set the appropriate properties on the view. + void DidUpdateIFrameFrameView(HTMLFrameOwnerElement&); + // Returns the PaintLayer associated with the currently effective root // scroller. PaintLayer* RootScrollerPaintLayer() const; @@ -87,6 +92,14 @@ void ElementRemoved(const Element&); + // In the "implicit root scroller" mode, we might promote an element to + // become the effective root scroller even if the page doesn't set it as so + // to improve the user experience. In this mode, as elements layout they'll + // call this method and, if they meet the root scroller restrictions, will be + // added to the implicit candidate set. After layout is done we'll go + // through that set and select the best candidate. + void ConsiderForImplicit(Node&); + private: RootScrollerController(Document&); @@ -98,12 +111,21 @@ // effective root scroller. bool IsValidRootScroller(const Element&) const; + // Determines whether the given element meets the criteria to be implicitly + // set as the root scroller (in addition to being a valid root scroller). + bool IsValidImplicit(const Element&) const; + // Set certain properties to the effective root scroller. Called when a Node // becomes or unbecomes the effective root scroller. - void ApplyRootScrollerProperties(Node&) const; + void ApplyRootScrollerProperties(Node&); void UpdateIFrameGeometryAndLayoutSize(HTMLFrameOwnerElement&) const; + // Called after layout, runs through implicit candidates, removing ones that + // are no longer meet the root scroller restrictions. Of the remaining ones, + // will choose the best and set it as the implicit_root_scroller_. + void ProcessImplicitCandidates(); + // The owning Document whose root scroller this object manages. WeakMember<Document> document_; @@ -119,7 +141,19 @@ // RootScrollerController. Member<Node> effective_root_scroller_; + // Candidate Elements that we should examine after layout to determine which + // should be root scroller. This is used when "implicit root scroller" is + // enabled, where a valid Element can become the root scroller without being + // explicitly set using document.setRootScroller. + HeapHashSet<WeakMember<Element>> implicit_candidates_; + + WeakMember<Element> implicit_root_scroller_; + bool document_has_document_element_; + + // This flag is used to force applicationn of rootScroller properties even if + // the effective rootScroller doesn't change. + bool needs_apply_properties_; }; } // namespace blink
diff --git a/third_party/WebKit/Source/core/page/scrolling/RootScrollerTest.cpp b/third_party/WebKit/Source/core/page/scrolling/RootScrollerTest.cpp index 8fa70b8..461080f3 100644 --- a/third_party/WebKit/Source/core/page/scrolling/RootScrollerTest.cpp +++ b/third_party/WebKit/Source/core/page/scrolling/RootScrollerTest.cpp
@@ -49,10 +49,12 @@ class RootScrollerTest : public ::testing::Test, public ::testing::WithParamInterface<bool>, private ScopedRootLayerScrollingForTest, + private ScopedImplicitRootScrollerForTest, private ScopedSetRootScrollerForTest { public: RootScrollerTest() : ScopedRootLayerScrollingForTest(GetParam()), + ScopedImplicitRootScrollerForTest(false), ScopedSetRootScrollerForTest(true), base_url_("http://www.test.com/") { RegisterMockedHttpURLLoad("overflow-scrolling.html"); @@ -1177,9 +1179,12 @@ class RootScrollerSimTest : public ::testing::WithParamInterface<bool>, private ScopedRootLayerScrollingForTest, + private ScopedImplicitRootScrollerForTest, public SimTest { public: - RootScrollerSimTest() : ScopedRootLayerScrollingForTest(GetParam()) {} + RootScrollerSimTest() + : ScopedRootLayerScrollingForTest(GetParam()), + ScopedImplicitRootScrollerForTest(false) {} }; INSTANTIATE_TEST_CASE_P(All, RootScrollerSimTest, ::testing::Bool()); @@ -1243,6 +1248,152 @@ EXPECT_EQ(120, frame->DomWindow()->visualViewport()->pageTop()); } +// Tests basic implicit root scroller mode with a <div>. +TEST_P(RootScrollerSimTest, ImplicitRootScroller) { + ScopedSetRootScrollerForTest disable_root_scroller(false); + ScopedImplicitRootScrollerForTest enable_implicit(true); + + WebView().Resize(WebSize(800, 600)); + SimRequest request("https://example.com/test.html", "text/html"); + LoadURL("https://example.com/test.html"); + request.Complete(R"HTML( + <!DOCTYPE html> + <style> + ::-webkit-scrollbar { + width: 0px; + height: 0px; + } + body, html { + width: 100%; + height: 100%; + margin: 0px; + } + #spacer { + width: 1000px; + height: 1000px; + } + #container { + width: 100%; + height: 100%; + } + </style> + <div id="container"> + <div id="spacer"></div> + </div> + )HTML"); + Compositor().BeginFrame(); + + ASSERT_EQ(&GetDocument(), + GetDocument().GetRootScrollerController().EffectiveRootScroller()); + Element* container = GetDocument().getElementById("container"); + + // overflow: auto and overflow: scroll should cause a valid element to be + // promoted to root scroller. Otherwise, they shouldn't, even if they're + // otherwise a valid root scroller element. + std::vector<std::tuple<String, String, Node*>> test_cases = { + {"overflow", "hidden", &GetDocument()}, + {"overflow", "auto", container}, + {"overflow", "scroll", container}, + {"overflow", "visible", &GetDocument()}, + // Overflow: hidden in one axis forces the other axis to auto so it should + // be promoted. + {"overflow-x", "hidden", container}, + {"overflow-x", "auto", container}, + {"overflow-x", "scroll", container}, + {"overflow-x", "visible", &GetDocument()}, + {"overflow-y", "hidden", container}, + {"overflow-y", "auto", container}, + {"overflow-y", "scroll", container}, + {"overflow-y", "visible", &GetDocument()}}; + + for (auto test_case : test_cases) { + String& style = std::get<0>(test_case); + String& style_val = std::get<1>(test_case); + Node* expected_root_scroller = std::get<2>(test_case); + + container->style()->setProperty(&GetDocument(), style, style_val, String(), + ASSERT_NO_EXCEPTION); + Compositor().BeginFrame(); + ASSERT_EQ( + expected_root_scroller, + GetDocument().GetRootScrollerController().EffectiveRootScroller()); + container->style()->setProperty(&GetDocument(), std::get<0>(test_case), + String(), String(), ASSERT_NO_EXCEPTION); + Compositor().BeginFrame(); + ASSERT_EQ( + &GetDocument(), + GetDocument().GetRootScrollerController().EffectiveRootScroller()); + } + + // Now remove the overflowing element and rerun the tests. There should be no + // difference based on the fact that the scroller has overflow or not. + Element* spacer = GetDocument().getElementById("spacer"); + spacer->remove(); + + for (auto test_case : test_cases) { + String& style = std::get<0>(test_case); + String& style_val = std::get<1>(test_case); + Node* expected_root_scroller = std::get<2>(test_case); + + container->style()->setProperty(&GetDocument(), style, style_val, String(), + ASSERT_NO_EXCEPTION); + Compositor().BeginFrame(); + ASSERT_EQ( + expected_root_scroller, + GetDocument().GetRootScrollerController().EffectiveRootScroller()); + container->style()->setProperty(&GetDocument(), std::get<0>(test_case), + String(), String(), ASSERT_NO_EXCEPTION); + Compositor().BeginFrame(); + ASSERT_EQ( + &GetDocument(), + GetDocument().GetRootScrollerController().EffectiveRootScroller()); + } +} + +// Tests implicit root scroller mode for iframes. +TEST_P(RootScrollerSimTest, ImplicitRootScrollerIframe) { + ScopedSetRootScrollerForTest disable_root_scroller(false); + ScopedImplicitRootScrollerForTest enable_implicit(true); + + WebView().Resize(WebSize(800, 600)); + SimRequest request("https://example.com/test.html", "text/html"); + LoadURL("https://example.com/test.html"); + request.Complete(R"HTML( + <!DOCTYPE html> + <style> + ::-webkit-scrollbar { + width: 0px; + height: 0px; + } + body, html { + width: 100%; + height: 100%; + margin: 0px; + } + iframe { + width: 100%; + height: 100%; + border: 0; + } + </style> + <iframe id="container" + srcdoc="<!DOCTYPE html><style>html {height: 300%;}</style>"> + </iframe> + )HTML"); + Compositor().BeginFrame(); + + Element* container = GetDocument().getElementById("container"); + ASSERT_EQ(container, + GetDocument().GetRootScrollerController().EffectiveRootScroller()); + + container->style()->setProperty(&GetDocument(), "height", "95%", String(), + ASSERT_NO_EXCEPTION); + Compositor().BeginFrame(); + + ASSERT_EQ(&GetDocument(), + GetDocument().GetRootScrollerController().EffectiveRootScroller()); +} + class RootScrollerHitTest : public RootScrollerTest { public: void CheckHitTestAtBottomOfScreen() {
diff --git a/third_party/WebKit/Source/core/page/scrolling/RootScrollerUtil.cpp b/third_party/WebKit/Source/core/page/scrolling/RootScrollerUtil.cpp index 9d0039d..e90b3d9 100644 --- a/third_party/WebKit/Source/core/page/scrolling/RootScrollerUtil.cpp +++ b/third_party/WebKit/Source/core/page/scrolling/RootScrollerUtil.cpp
@@ -105,6 +105,13 @@ return &layer == root_scroller_layer; } +bool IsGlobal(const Element* element) { + return element->GetDocument() + .GetPage() + ->GlobalRootScrollerController() + .GlobalRootScroller() == element; +} + } // namespace RootScrollerUtil } // namespace blink
diff --git a/third_party/WebKit/Source/core/page/scrolling/RootScrollerUtil.h b/third_party/WebKit/Source/core/page/scrolling/RootScrollerUtil.h index c35766a..53ee86d6 100644 --- a/third_party/WebKit/Source/core/page/scrolling/RootScrollerUtil.h +++ b/third_party/WebKit/Source/core/page/scrolling/RootScrollerUtil.h
@@ -7,6 +7,7 @@ namespace blink { +class Element; class LayoutBox; class Node; class PaintLayer; @@ -32,6 +33,7 @@ bool IsGlobal(const LayoutBox&); bool IsGlobal(const PaintLayer&); +bool IsGlobal(const Element*); } // namespace RootScrollerUtil
diff --git a/third_party/WebKit/Source/core/page/scrolling/ScrollCustomizationCallbacks.cpp b/third_party/WebKit/Source/core/page/scrolling/ScrollCustomizationCallbacks.cpp index 591894f..d46d3f4 100644 --- a/third_party/WebKit/Source/core/page/scrolling/ScrollCustomizationCallbacks.cpp +++ b/third_party/WebKit/Source/core/page/scrolling/ScrollCustomizationCallbacks.cpp
@@ -40,4 +40,15 @@ return it->value.Get(); } +bool ScrollCustomizationCallbacks::InScrollPhase(Element* element) const { + return in_scrolling_phase_.Contains(element) && + in_scrolling_phase_.at(element); +} + +void ScrollCustomizationCallbacks::SetInScrollPhase(Element* element, + bool value) { + DCHECK(element); + in_scrolling_phase_.Set(element, value); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/core/page/scrolling/ScrollCustomizationCallbacks.h b/third_party/WebKit/Source/core/page/scrolling/ScrollCustomizationCallbacks.h index 7a6bc643f..ced35257 100644 --- a/third_party/WebKit/Source/core/page/scrolling/ScrollCustomizationCallbacks.h +++ b/third_party/WebKit/Source/core/page/scrolling/ScrollCustomizationCallbacks.h
@@ -24,10 +24,13 @@ void SetApplyScroll(Element*, ScrollStateCallback*); void RemoveApplyScroll(Element*); ScrollStateCallback* GetApplyScroll(Element*); + bool InScrollPhase(Element*) const; + void SetInScrollPhase(Element*, bool); void Trace(blink::Visitor* visitor) { visitor->Trace(apply_scroll_callbacks_); visitor->Trace(distribute_scroll_callbacks_); + visitor->Trace(in_scrolling_phase_); }; private: @@ -35,6 +38,8 @@ HeapHashMap<WeakMember<Element>, Member<ScrollStateCallback>>; ScrollStateCallbackList apply_scroll_callbacks_; ScrollStateCallbackList distribute_scroll_callbacks_; + HeapHashMap<WeakMember<Element>, bool> in_scrolling_phase_; + DISALLOW_COPY_AND_ASSIGN(ScrollCustomizationCallbacks); };
diff --git a/third_party/WebKit/Source/core/page/scrolling/ScrollState.h b/third_party/WebKit/Source/core/page/scrolling/ScrollState.h index 5367640..93eb4b2d4 100644 --- a/third_party/WebKit/Source/core/page/scrolling/ScrollState.h +++ b/third_party/WebKit/Source/core/page/scrolling/ScrollState.h
@@ -63,6 +63,14 @@ // True if this scroll is the result of the user interacting directly with // the screen, e.g., via touch. bool isDirectManipulation() const { return data_->is_direct_manipulation; } + // When gesture begins it equals deltaXHint(). Otherwise, it returns deltaX(). + double effectiveDeltaX() const { + return data_->is_beginning ? data_->delta_x_hint : data_->delta_x; + } + // When gesture begins it equals deltaYHint(). Otherwise, it returns deltaY(). + double effectiveDeltaY() const { + return data_->is_beginning ? data_->delta_y_hint : data_->delta_y; + } // Non web exposed methods. void ConsumeDeltaNative(double x, double y);
diff --git a/third_party/WebKit/Source/core/page/scrolling/TopDocumentRootScrollerController.cpp b/third_party/WebKit/Source/core/page/scrolling/TopDocumentRootScrollerController.cpp index a51ef7e..43e36ba 100644 --- a/third_party/WebKit/Source/core/page/scrolling/TopDocumentRootScrollerController.cpp +++ b/third_party/WebKit/Source/core/page/scrolling/TopDocumentRootScrollerController.cpp
@@ -107,7 +107,13 @@ return element; } -void SetNeedsCompositingUpdateOnAncestors(ScrollableArea* area) { +void SetNeedsCompositingUpdateOnAncestors(Element* element) { + if (!element || !element->GetDocument().IsActive()) + return; + + ScrollableArea* area = + RootScrollerUtil::ScrollableAreaForRootScroller(element); + if (!area || !area->Layer()) return; @@ -117,7 +123,6 @@ continue; LayoutView* layout_view = ToLocalFrame(frame)->View()->GetLayoutView(); - if (RuntimeEnabledFeatures::RootLayerScrollingEnabled()) { PaintLayer* frame_root_layer = layout_view->Layer(); DCHECK(frame_root_layer); @@ -153,8 +158,7 @@ // scrolling the element so it will apply scroll to the element itself. target->setApplyScroll(viewport_apply_scroll_, "disable-native-scroll"); - ScrollableArea* old_root_scroller_area = - RootScrollerUtil::ScrollableAreaForRootScroller(global_root_scroller_); + Element* old_root_scroller = global_root_scroller_; global_root_scroller_ = target; @@ -165,11 +169,14 @@ // in RootFrameViewport. viewport_apply_scroll_->SetScroller(target_scroller); - SetNeedsCompositingUpdateOnAncestors(old_root_scroller_area); - SetNeedsCompositingUpdateOnAncestors(target_scroller); + SetNeedsCompositingUpdateOnAncestors(old_root_scroller); + SetNeedsCompositingUpdateOnAncestors(target); - if (old_root_scroller_area) - old_root_scroller_area->DidChangeGlobalRootScroller(); + if (ScrollableArea* area = + RootScrollerUtil::ScrollableAreaForRootScroller(old_root_scroller)) { + if (old_root_scroller->GetDocument().IsActive()) + area->DidChangeGlobalRootScroller(); + } target_scroller->DidChangeGlobalRootScroller(); }
diff --git a/third_party/WebKit/Source/core/paint/ng/ng_box_fragment_painter.cc b/third_party/WebKit/Source/core/paint/ng/ng_box_fragment_painter.cc index c92e6520..ed571a5 100644 --- a/third_party/WebKit/Source/core/paint/ng/ng_box_fragment_painter.cc +++ b/third_party/WebKit/Source/core/paint/ng/ng_box_fragment_painter.cc
@@ -50,7 +50,8 @@ box.Style(), box.GetLayoutObject()->GeneratingNode(), BoxStrutToLayoutRectOutsets(box.PhysicalFragment().BorderWidths()), - LayoutRectOutsets()), + BoxStrutToLayoutRectOutsets( + ToNGPhysicalBoxFragment(box.PhysicalFragment()).Padding())), box_fragment_(box), border_edges_( NGBorderEdges::FromPhysical(box.PhysicalFragment().BorderEdges(),
diff --git a/third_party/WebKit/Source/core/svg/SVGClipPathElement.h b/third_party/WebKit/Source/core/svg/SVGClipPathElement.h index 4d4792d2..3ba1bfe0 100644 --- a/third_party/WebKit/Source/core/svg/SVGClipPathElement.h +++ b/third_party/WebKit/Source/core/svg/SVGClipPathElement.h
@@ -46,8 +46,6 @@ private: explicit SVGClipPathElement(Document&); - bool NeedsPendingResourceHandling() const override { return false; } - void SvgAttributeChanged(const QualifiedName&) override; void ChildrenChanged(const ChildrenChange&) override;
diff --git a/third_party/WebKit/Source/core/svg/SVGElement.cpp b/third_party/WebKit/Source/core/svg/SVGElement.cpp index 5142774..c76781d5 100644 --- a/third_party/WebKit/Source/core/svg/SVGElement.cpp +++ b/third_party/WebKit/Source/core/svg/SVGElement.cpp
@@ -49,7 +49,6 @@ #include "core/svg/SVGGraphicsElement.h" #include "core/svg/SVGSVGElement.h" #include "core/svg/SVGTitleElement.h" -#include "core/svg/SVGTreeScopeResources.h" #include "core/svg/SVGUseElement.h" #include "core/svg/properties/SVGProperty.h" #include "core/svg_names.h" @@ -111,13 +110,6 @@ SvgRareData()->SetNeedsOverrideComputedStyleUpdate(); } -void SVGElement::BuildPendingResourcesIfNeeded() { - if (!NeedsPendingResourceHandling() || !isConnected() || InUseShadowTree()) - return; - GetTreeScope().EnsureSVGTreeScopedResources().NotifyResourceAvailable( - GetIdAttribute()); -} - SVGElementRareData* SVGElement::EnsureSVGRareData() { if (!svg_rare_data_) svg_rare_data_ = new SVGElementRareData(); @@ -393,7 +385,6 @@ ContainerNode* root_parent) { Element::InsertedInto(root_parent); UpdateRelativeLengthsInformation(); - BuildPendingResourcesIfNeeded(); const AtomicString& nonce_value = FastGetAttribute(nonceAttr); if (!nonce_value.IsEmpty()) { @@ -403,7 +394,6 @@ setAttribute(nonceAttr, g_empty_atom); } } - return kInsertionDone; } @@ -962,16 +952,6 @@ if (params.name == HTMLNames::idAttr) { RebuildAllIncomingReferences(); - - LayoutObject* object = GetLayoutObject(); - // Notify resources about id changes, this is important as we cache - // resources by id in SVGDocumentExtensions - if (object && object->IsSVGResourceContainer()) { - ToLayoutSVGResourceContainer(object)->IdChanged(params.old_value, - params.new_value); - } - if (isConnected()) - BuildPendingResourcesIfNeeded(); InvalidateInstances(); return; }
diff --git a/third_party/WebKit/Source/core/svg/SVGElement.h b/third_party/WebKit/Source/core/svg/SVGElement.h index 1b54285c..1189d73f 100644 --- a/third_party/WebKit/Source/core/svg/SVGElement.h +++ b/third_party/WebKit/Source/core/svg/SVGElement.h
@@ -88,7 +88,6 @@ kAncestorScope // Used by SVGSVGElement::get{Enclosure|Intersection}List() }; virtual AffineTransform LocalCoordinateSpaceTransform(CTMScope) const; - virtual bool NeedsPendingResourceHandling() const { return true; } bool InstanceUpdatesBlocked() const; void SetInstanceUpdatesBlocked(bool); @@ -273,8 +272,6 @@ } void WillRecalcStyle(StyleRecalcChange) override; - void BuildPendingResourcesIfNeeded(); - HeapHashSet<WeakMember<SVGElement>> elements_with_relative_lengths_; typedef HeapHashMap<QualifiedName, Member<SVGAnimatedPropertyBase>>
diff --git a/third_party/WebKit/Source/core/svg/SVGFilterElement.h b/third_party/WebKit/Source/core/svg/SVGFilterElement.h index 33b152e..c2e7f2b2 100644 --- a/third_party/WebKit/Source/core/svg/SVGFilterElement.h +++ b/third_party/WebKit/Source/core/svg/SVGFilterElement.h
@@ -67,8 +67,6 @@ private: explicit SVGFilterElement(Document&); - bool NeedsPendingResourceHandling() const override { return false; } - void SvgAttributeChanged(const QualifiedName&) override; void ChildrenChanged(const ChildrenChange&) override;
diff --git a/third_party/WebKit/Source/core/svg/SVGGradientElement.h b/third_party/WebKit/Source/core/svg/SVGGradientElement.h index 921971bd..6858372 100644 --- a/third_party/WebKit/Source/core/svg/SVGGradientElement.h +++ b/third_party/WebKit/Source/core/svg/SVGGradientElement.h
@@ -72,8 +72,6 @@ void SvgAttributeChanged(const QualifiedName&) override; private: - bool NeedsPendingResourceHandling() const final { return false; } - void CollectStyleForPresentationAttribute( const QualifiedName&, const AtomicString&,
diff --git a/third_party/WebKit/Source/core/svg/SVGMarkerElement.h b/third_party/WebKit/Source/core/svg/SVGMarkerElement.h index 4ae4380..b6f6f7c3 100644 --- a/third_party/WebKit/Source/core/svg/SVGMarkerElement.h +++ b/third_party/WebKit/Source/core/svg/SVGMarkerElement.h
@@ -82,8 +82,6 @@ private: explicit SVGMarkerElement(Document&); - bool NeedsPendingResourceHandling() const override { return false; } - void SvgAttributeChanged(const QualifiedName&) override; void ChildrenChanged(const ChildrenChange&) override;
diff --git a/third_party/WebKit/Source/core/svg/SVGMaskElement.h b/third_party/WebKit/Source/core/svg/SVGMaskElement.h index d24e46a..6b38ca7e 100644 --- a/third_party/WebKit/Source/core/svg/SVGMaskElement.h +++ b/third_party/WebKit/Source/core/svg/SVGMaskElement.h
@@ -53,7 +53,6 @@ explicit SVGMaskElement(Document&); bool IsValid() const override { return SVGTests::IsValid(); } - bool NeedsPendingResourceHandling() const override { return false; } void CollectStyleForPresentationAttribute( const QualifiedName&,
diff --git a/third_party/WebKit/Source/core/svg/SVGPatternElement.h b/third_party/WebKit/Source/core/svg/SVGPatternElement.h index 6a6d0ba..1cd2a8e 100644 --- a/third_party/WebKit/Source/core/svg/SVGPatternElement.h +++ b/third_party/WebKit/Source/core/svg/SVGPatternElement.h
@@ -80,7 +80,6 @@ explicit SVGPatternElement(Document&); bool IsValid() const override { return SVGTests::IsValid(); } - bool NeedsPendingResourceHandling() const override { return false; } void CollectStyleForPresentationAttribute( const QualifiedName&,
diff --git a/third_party/WebKit/Source/core/svg/SVGTreeScopeResources.cpp b/third_party/WebKit/Source/core/svg/SVGTreeScopeResources.cpp index 0f780af..f1e5389 100644 --- a/third_party/WebKit/Source/core/svg/SVGTreeScopeResources.cpp +++ b/third_party/WebKit/Source/core/svg/SVGTreeScopeResources.cpp
@@ -7,226 +7,133 @@ #include "core/dom/Element.h" #include "core/dom/TreeScope.h" #include "core/layout/svg/LayoutSVGResourceContainer.h" +#include "core/layout/svg/SVGResources.h" #include "core/layout/svg/SVGResourcesCache.h" -#include "core/svg/SVGUseElement.h" #include "platform/wtf/text/AtomicString.h" namespace blink { +SVGTreeScopeResources::Resource::Resource(TreeScope& tree_scope, + const AtomicString& id) + : IdTargetObserver(tree_scope.GetIdTargetObserverRegistry(), id), + tree_scope_(tree_scope), + target_(tree_scope.getElementById(id)) {} + +SVGTreeScopeResources::Resource::~Resource() = default; + +void SVGTreeScopeResources::Resource::Trace(Visitor* visitor) { + visitor->Trace(tree_scope_); + visitor->Trace(target_); + visitor->Trace(pending_clients_); + IdTargetObserver::Trace(visitor); +} + +void SVGTreeScopeResources::Resource::AddWatch(SVGElement& element) { + pending_clients_.insert(&element); + element.SetHasPendingResources(); +} + +void SVGTreeScopeResources::Resource::RemoveWatch(SVGElement& element) { + pending_clients_.erase(&element); +} + +bool SVGTreeScopeResources::Resource::IsEmpty() const { + LayoutSVGResourceContainer* container = ResourceContainer(); + return (!container || !container->HasClients()) && pending_clients_.IsEmpty(); +} + +void SVGTreeScopeResources::Resource::NotifyResourceClients() { + HeapHashSet<Member<SVGElement>> pending_clients; + pending_clients.swap(pending_clients_); + + for (SVGElement* client_element : pending_clients) { + if (LayoutObject* layout_object = client_element->GetLayoutObject()) + SVGResourcesCache::ResourceReferenceChanged(*layout_object); + } +} + +LayoutSVGResourceContainer* SVGTreeScopeResources::Resource::ResourceContainer() + const { + if (!target_) + return nullptr; + LayoutObject* layout_object = target_->GetLayoutObject(); + if (!layout_object || !layout_object->IsSVGResourceContainer()) + return nullptr; + return ToLayoutSVGResourceContainer(layout_object); +} + +void SVGTreeScopeResources::Resource::IdTargetChanged() { + Element* new_target = tree_scope_->getElementById(Id()); + if (new_target == target_) + return; + // Detach clients from the old resource, moving them to the pending list + // and then notify pending clients. + if (LayoutSVGResourceContainer* old_resource = ResourceContainer()) + old_resource->MakeClientsPending(*this); + target_ = new_target; + NotifyResourceClients(); +} + SVGTreeScopeResources::SVGTreeScopeResources(TreeScope* tree_scope) : tree_scope_(tree_scope) {} SVGTreeScopeResources::~SVGTreeScopeResources() = default; -static LayoutSVGResourceContainer* LookupResource(TreeScope& tree_scope, - const AtomicString& id) { - Element* element = tree_scope.getElementById(id); - if (!element) +SVGTreeScopeResources::Resource* SVGTreeScopeResources::ResourceForId( + const AtomicString& id) { + if (id.IsEmpty()) return nullptr; - LayoutObject* layout_object = element->GetLayoutObject(); - if (!layout_object || !layout_object->IsSVGResourceContainer()) - return nullptr; - return ToLayoutSVGResourceContainer(layout_object); + auto& entry = resources_.insert(id, nullptr).stored_value->value; + if (!entry) + entry = new Resource(*tree_scope_, id); + return entry; } -void SVGTreeScopeResources::UpdateResource( - const AtomicString& id, - LayoutSVGResourceContainer* resource) { - DCHECK(resource); - if (resource->IsRegistered() || id.IsEmpty()) - return; - // Lookup the current resource. (Could differ from what's in the map if an - // element was just added/removed.) - LayoutSVGResourceContainer* current_resource = - LookupResource(*tree_scope_, id); - // Lookup the currently registered resource. - auto it = resources_.find(id); - if (it != resources_.end()) { - // Is the local map up-to-date already? - if (it->value == current_resource) - return; - UnregisterResource(it); - } - if (current_resource) - RegisterResource(id, current_resource); -} - -void SVGTreeScopeResources::UpdateResource( - const AtomicString& old_id, - const AtomicString& new_id, - LayoutSVGResourceContainer* resource) { - RemoveResource(old_id, resource); - UpdateResource(new_id, resource); -} - -void SVGTreeScopeResources::RemoveResource( - const AtomicString& id, - LayoutSVGResourceContainer* resource) { - DCHECK(resource); - if (!resource->IsRegistered() || id.IsEmpty()) - return; - auto it = resources_.find(id); - // If this is not the currently registered resource for this id, then do - // nothing. - if (it == resources_.end() || it->value != resource) - return; - UnregisterResource(it); - // If the layout tree is being torn down, then don't attempt to update the - // map, since that layout object is likely to be stale already. - if (resource->DocumentBeingDestroyed()) - return; - // Another resource could now be current. Perform a lookup and potentially - // update the map. - LayoutSVGResourceContainer* current_resource = - LookupResource(*tree_scope_, id); - if (!current_resource) - return; - // Since this is a removal, don't allow re-adding the resource. - if (current_resource == resource) - return; - RegisterResource(id, current_resource); -} - -void SVGTreeScopeResources::RegisterResource( - const AtomicString& id, - LayoutSVGResourceContainer* resource) { - DCHECK(!id.IsEmpty()); - DCHECK(resource); - DCHECK(!resource->IsRegistered()); - - resources_.Set(id, resource); - resource->SetRegistered(true); - - NotifyPendingClients(id); -} - -void SVGTreeScopeResources::UnregisterResource(ResourceMap::iterator it) { - LayoutSVGResourceContainer* resource = it->value; - DCHECK(resource); - DCHECK(resource->IsRegistered()); - - resource->DetachAllClients(it->key); - - resource->SetRegistered(false); - resources_.erase(it); -} - -LayoutSVGResourceContainer* SVGTreeScopeResources::ResourceById( +SVGTreeScopeResources::Resource* SVGTreeScopeResources::ExistingResourceForId( const AtomicString& id) const { if (id.IsEmpty()) return nullptr; return resources_.at(id); } -void SVGTreeScopeResources::AddPendingResource(const AtomicString& id, - Element& element) { - DCHECK(element.isConnected()); - - if (id.IsEmpty()) +void SVGTreeScopeResources::RemoveUnreferencedResources() { + if (resources_.IsEmpty()) return; - auto result = pending_resources_.insert(id, nullptr); - if (result.is_new_entry) - result.stored_value->value = new SVGPendingElements; - result.stored_value->value->insert(&element); - - element.SetHasPendingResources(); -} - -bool SVGTreeScopeResources::IsElementPendingResource( - Element& element, - const AtomicString& id) const { - if (id.IsEmpty()) - return false; - const SVGPendingElements* pending_elements = pending_resources_.at(id); - return pending_elements && pending_elements->Contains(&element); -} - -void SVGTreeScopeResources::ClearHasPendingResourcesIfPossible( - Element& element) { - // This algorithm takes time proportional to the number of pending resources - // and need not. - // If performance becomes an issue we can keep a counted set of elements and - // answer the question efficiently. - for (const auto& entry : pending_resources_) { - SVGPendingElements* elements = entry.value.Get(); - DCHECK(elements); - if (elements->Contains(&element)) - return; + // Remove resources that are no longer referenced. + Vector<AtomicString> to_be_removed; + for (const auto& entry : resources_) { + Resource* resource = entry.value.Get(); + DCHECK(resource); + if (resource->IsEmpty()) { + resource->Unregister(); + to_be_removed.push_back(entry.key); + } } - element.ClearHasPendingResources(); + resources_.RemoveAll(to_be_removed); } -void SVGTreeScopeResources::RemoveElementFromPendingResources( - Element& element) { - if (pending_resources_.IsEmpty() || !element.HasPendingResources()) +void SVGTreeScopeResources::RemoveWatchesForElement(SVGElement& element) { + if (resources_.IsEmpty() || !element.HasPendingResources()) return; // Remove the element from pending resources. Vector<AtomicString> to_be_removed; - for (const auto& entry : pending_resources_) { - SVGPendingElements* elements = entry.value.Get(); - DCHECK(elements); - DCHECK(!elements->IsEmpty()); - - elements->erase(&element); - if (elements->IsEmpty()) + for (const auto& entry : resources_) { + Resource* resource = entry.value.Get(); + DCHECK(resource); + resource->RemoveWatch(element); + if (resource->IsEmpty()) { + resource->Unregister(); to_be_removed.push_back(entry.key); + } } - pending_resources_.RemoveAll(to_be_removed); + resources_.RemoveAll(to_be_removed); - ClearHasPendingResourcesIfPossible(element); -} - -void SVGTreeScopeResources::NotifyPendingClients(const AtomicString& id) { - DCHECK(!id.IsEmpty()); - SVGPendingElements* pending_elements = pending_resources_.Take(id); - if (!pending_elements) - return; - // Update cached resources of pending clients. - for (Element* client_element : *pending_elements) { - DCHECK(client_element->HasPendingResources()); - ClearHasPendingResourcesIfPossible(*client_element); - - LayoutObject* layout_object = client_element->GetLayoutObject(); - if (!layout_object) - continue; - DCHECK(layout_object->IsSVG()); - - StyleDifference diff; - diff.SetNeedsFullLayout(); - SVGResourcesCache::ClientStyleChanged(layout_object, diff, - layout_object->StyleRef()); - layout_object->SetNeedsLayoutAndFullPaintInvalidation( - LayoutInvalidationReason::kSvgResourceInvalidated); - } -} - -void SVGTreeScopeResources::NotifyResourceAvailable(const AtomicString& id) { - if (id.IsEmpty()) - return; - // Get pending elements for this id. - SVGPendingElements* pending_elements = pending_resources_.Take(id); - if (!pending_elements) - return; - // Rebuild pending resources for each client of a pending resource that is - // being removed. - for (Element* client_element : *pending_elements) { - DCHECK(client_element->HasPendingResources()); - if (!client_element->HasPendingResources()) - continue; - // TODO(fs): Ideally we'd always resolve pending resources async instead of - // inside insertedInto and svgAttributeChanged. For now we only do it for - // <use> since that would stamp out DOM. - if (auto* use = ToSVGUseElementOrNull(client_element)) - use->InvalidateShadowTree(); - else - client_element->BuildPendingResource(); - - ClearHasPendingResourcesIfPossible(*client_element); - } + element.ClearHasPendingResources(); } void SVGTreeScopeResources::Trace(blink::Visitor* visitor) { - visitor->Trace(pending_resources_); + visitor->Trace(resources_); visitor->Trace(tree_scope_); } -} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/svg/SVGTreeScopeResources.h b/third_party/WebKit/Source/core/svg/SVGTreeScopeResources.h index 3152958..7a2171f 100644 --- a/third_party/WebKit/Source/core/svg/SVGTreeScopeResources.h +++ b/third_party/WebKit/Source/core/svg/SVGTreeScopeResources.h
@@ -6,6 +6,7 @@ #define SVGTreeScopeResources_h #include "base/macros.h" +#include "core/dom/IdTargetObserver.h" #include "platform/heap/Handle.h" #include "platform/wtf/Forward.h" #include "platform/wtf/HashMap.h" @@ -15,8 +16,9 @@ namespace blink { class Element; -class TreeScope; class LayoutSVGResourceContainer; +class SVGElement; +class TreeScope; // This class keeps track of SVG resources and pending references to such for a // TreeScope. It's per-TreeScope because that matches the lookup scope of an @@ -27,36 +29,40 @@ explicit SVGTreeScopeResources(TreeScope*); ~SVGTreeScopeResources(); - void UpdateResource(const AtomicString& id, LayoutSVGResourceContainer*); - void UpdateResource(const AtomicString& old_id, - const AtomicString& new_id, - LayoutSVGResourceContainer*); - void RemoveResource(const AtomicString& id, LayoutSVGResourceContainer*); - LayoutSVGResourceContainer* ResourceById(const AtomicString& id) const; + class Resource : public IdTargetObserver { + public: + Resource(TreeScope&, const AtomicString& id); + ~Resource() override; - // Pending resources are such which are referenced by any object in the SVG - // document, but do NOT exist yet. For instance, dynamically built gradients - // / patterns / clippers... - void AddPendingResource(const AtomicString& id, Element&); - bool IsElementPendingResource(Element&, const AtomicString& id) const; - void NotifyResourceAvailable(const AtomicString& id); - void RemoveElementFromPendingResources(Element&); + Element* Target() const { return target_; } + LayoutSVGResourceContainer* ResourceContainer() const; + + void AddWatch(SVGElement&); + void RemoveWatch(SVGElement&); + + bool IsEmpty() const; + + void Trace(blink::Visitor*); + + void NotifyResourceClients(); + + private: + void IdTargetChanged() override; + + Member<TreeScope> tree_scope_; + Member<Element> target_; + HeapHashSet<Member<SVGElement>> pending_clients_; + }; + Resource* ResourceForId(const AtomicString& id); + Resource* ExistingResourceForId(const AtomicString& id) const; + + void RemoveUnreferencedResources(); + void RemoveWatchesForElement(SVGElement&); void Trace(blink::Visitor*); private: - void ClearHasPendingResourcesIfPossible(Element&); - - using SVGPendingElements = HeapHashSet<Member<Element>>; - using ResourceMap = HashMap<AtomicString, LayoutSVGResourceContainer*>; - - void RegisterResource(const AtomicString& id, LayoutSVGResourceContainer*); - void UnregisterResource(ResourceMap::iterator); - void NotifyPendingClients(const AtomicString& id); - - ResourceMap resources_; - // Resources that are pending. - HeapHashMap<AtomicString, Member<SVGPendingElements>> pending_resources_; + HeapHashMap<AtomicString, Member<Resource>> resources_; Member<TreeScope> tree_scope_; DISALLOW_COPY_AND_ASSIGN(SVGTreeScopeResources);
diff --git a/third_party/WebKit/Source/core/svg/properties/SVGPropertyTearOff.h b/third_party/WebKit/Source/core/svg/properties/SVGPropertyTearOff.h index 7b8f8dd0..28ce517 100644 --- a/third_party/WebKit/Source/core/svg/properties/SVGPropertyTearOff.h +++ b/third_party/WebKit/Source/core/svg/properties/SVGPropertyTearOff.h
@@ -68,7 +68,7 @@ context_element_ = context_element; // Requires SVGPropertyTearOffBase to be the left-most class in the // inheritance hierarchy. - ScriptWrappableVisitor::WriteBarrier(context_element_.Get()); + ScriptWrappableMarkingVisitor::WriteBarrier(context_element_.Get()); attribute_name_ = attribute_name; }
diff --git a/third_party/WebKit/Source/core/testing/Internals.cpp b/third_party/WebKit/Source/core/testing/Internals.cpp index 968faed5..447c306 100644 --- a/third_party/WebKit/Source/core/testing/Internals.cpp +++ b/third_party/WebKit/Source/core/testing/Internals.cpp
@@ -114,6 +114,7 @@ #include "core/page/FocusController.h" #include "core/page/Page.h" #include "core/page/PrintContext.h" +#include "core/page/scrolling/RootScrollerController.h" #include "core/page/scrolling/ScrollState.h" #include "core/paint/PaintLayer.h" #include "core/paint/compositing/CompositedLayerMapping.h" @@ -749,6 +750,13 @@ document_->GetPage()->GetChromeClient().SetBrowserControlsShownRatio(ratio); } +Node* Internals::effectiveRootScroller(Document* document) { + if (!document) + document = document_; + + return &document->GetRootScrollerController().EffectiveRootScroller(); +} + ShadowRoot* Internals::shadowRoot(Element* host) { // FIXME: Internals::shadowRoot() in tests should be converted to // youngestShadowRoot() or oldestShadowRoot().
diff --git a/third_party/WebKit/Source/core/testing/Internals.h b/third_party/WebKit/Source/core/testing/Internals.h index 08f8527..0277c953 100644 --- a/third_party/WebKit/Source/core/testing/Internals.h +++ b/third_party/WebKit/Source/core/testing/Internals.h
@@ -110,6 +110,8 @@ bool shrinks_layout); void setBrowserControlsShownRatio(float); + Node* effectiveRootScroller(Document*); + ShadowRoot* createUserAgentShadowRoot(Element* host); ShadowRoot* shadowRoot(Element* host);
diff --git a/third_party/WebKit/Source/core/testing/Internals.idl b/third_party/WebKit/Source/core/testing/Internals.idl index a8c55ed..a05ada7f 100644 --- a/third_party/WebKit/Source/core/testing/Internals.idl +++ b/third_party/WebKit/Source/core/testing/Internals.idl
@@ -56,6 +56,8 @@ void setBrowserControlsState(float top_height, float bottom_height, boolean shrinksLayout); void setBrowserControlsShownRatio(float ratio); + Node effectiveRootScroller(Document document); + [RaisesException] DOMString shadowRootType(Node root); [RaisesException] boolean hasShadowInsertionPoint(Node root); [RaisesException] boolean hasContentElement(Node root);
diff --git a/third_party/WebKit/Source/core/workers/DedicatedWorkerTest.cpp b/third_party/WebKit/Source/core/workers/DedicatedWorkerTest.cpp index fcd96ed..9bea88a1 100644 --- a/third_party/WebKit/Source/core/workers/DedicatedWorkerTest.cpp +++ b/third_party/WebKit/Source/core/workers/DedicatedWorkerTest.cpp
@@ -30,7 +30,8 @@ DedicatedWorkerThreadForTest(DedicatedWorkerObjectProxy& worker_object_proxy) : DedicatedWorkerThread(nullptr /* ThreadableLoadingContext */, worker_object_proxy) { - worker_backing_thread_ = WorkerBackingThread::CreateForTest("Test thread"); + worker_backing_thread_ = WorkerBackingThread::CreateForTest( + WebThreadCreationParams("Test thread")); } WorkerOrWorkletGlobalScope* CreateWorkerGlobalScope(
diff --git a/third_party/WebKit/Source/core/workers/DedicatedWorkerThread.cpp b/third_party/WebKit/Source/core/workers/DedicatedWorkerThread.cpp index 639d9c08..ecd5eda 100644 --- a/third_party/WebKit/Source/core/workers/DedicatedWorkerThread.cpp +++ b/third_party/WebKit/Source/core/workers/DedicatedWorkerThread.cpp
@@ -51,8 +51,8 @@ ThreadableLoadingContext* loading_context, DedicatedWorkerObjectProxy& worker_object_proxy) : WorkerThread(loading_context, worker_object_proxy), - worker_backing_thread_( - WorkerBackingThread::Create("DedicatedWorker Thread")), + worker_backing_thread_(WorkerBackingThread::Create( + WebThreadCreationParams("DedicatedWorker Thread"))), worker_object_proxy_(worker_object_proxy) {} DedicatedWorkerThread::~DedicatedWorkerThread() = default;
diff --git a/third_party/WebKit/Source/core/workers/SharedWorkerThread.cpp b/third_party/WebKit/Source/core/workers/SharedWorkerThread.cpp index f1962ee..7635fb1 100644 --- a/third_party/WebKit/Source/core/workers/SharedWorkerThread.cpp +++ b/third_party/WebKit/Source/core/workers/SharedWorkerThread.cpp
@@ -43,8 +43,8 @@ ThreadableLoadingContext* loading_context, WorkerReportingProxy& worker_reporting_proxy) : WorkerThread(loading_context, worker_reporting_proxy), - worker_backing_thread_( - WorkerBackingThread::Create("SharedWorker Thread")), + worker_backing_thread_(WorkerBackingThread::Create( + WebThreadCreationParams("SharedWorker Thread"))), name_(name.IsolatedCopy()) {} SharedWorkerThread::~SharedWorkerThread() = default;
diff --git a/third_party/WebKit/Source/core/workers/ThreadedWorkletTest.cpp b/third_party/WebKit/Source/core/workers/ThreadedWorkletTest.cpp index 14ef0deef..b782298 100644 --- a/third_party/WebKit/Source/core/workers/ThreadedWorkletTest.cpp +++ b/third_party/WebKit/Source/core/workers/ThreadedWorkletTest.cpp
@@ -69,7 +69,7 @@ static void EnsureSharedBackingThread() { DCHECK(IsMainThread()); WorkletThreadHolder<ThreadedWorkletThreadForTest>::CreateForTest( - "ThreadedWorkletThreadForTest"); + WebThreadCreationParams("ThreadedWorkletThreadForTest")); } static void ClearSharedBackingThread() {
diff --git a/third_party/WebKit/Source/core/workers/WorkerBackingThread.cpp b/third_party/WebKit/Source/core/workers/WorkerBackingThread.cpp index 82562c6..9519c79 100644 --- a/third_party/WebKit/Source/core/workers/WorkerBackingThread.cpp +++ b/third_party/WebKit/Source/core/workers/WorkerBackingThread.cpp
@@ -56,9 +56,9 @@ Isolates().erase(isolate); } -WorkerBackingThread::WorkerBackingThread(const char* name, +WorkerBackingThread::WorkerBackingThread(const WebThreadCreationParams& params, bool should_call_gc_on_shutdown) - : backing_thread_(WebThreadSupportingGC::Create(name)), + : backing_thread_(WebThreadSupportingGC::Create(params)), is_owning_thread_(true), should_call_gc_on_shutdown_(should_call_gc_on_shutdown) {} @@ -84,8 +84,8 @@ ThreadState::Current()->RegisterTraceDOMWrappers( isolate_, V8GCController::TraceDOMWrappers, - ScriptWrappableVisitor::InvalidateDeadObjectsInMarkingDeque, - ScriptWrappableVisitor::PerformCleanup); + ScriptWrappableMarkingVisitor::InvalidateDeadObjectsInMarkingDeque, + ScriptWrappableMarkingVisitor::PerformCleanup); if (RuntimeEnabledFeatures::V8IdleTasksEnabled()) V8PerIsolateData::EnableIdleTasks( isolate_, WTF::WrapUnique(new V8IdleTaskRunner(
diff --git a/third_party/WebKit/Source/core/workers/WorkerBackingThread.h b/third_party/WebKit/Source/core/workers/WorkerBackingThread.h index 17c2776..7e36d18 100644 --- a/third_party/WebKit/Source/core/workers/WorkerBackingThread.h +++ b/third_party/WebKit/Source/core/workers/WorkerBackingThread.h
@@ -26,8 +26,9 @@ // ShutdownOnBackingThread() when it no longer needs the thread. class CORE_EXPORT WorkerBackingThread final { public: - static std::unique_ptr<WorkerBackingThread> Create(const char* name) { - return WTF::WrapUnique(new WorkerBackingThread(name, false)); + static std::unique_ptr<WorkerBackingThread> Create( + const WebThreadCreationParams& params) { + return WTF::WrapUnique(new WorkerBackingThread(params, false)); } static std::unique_ptr<WorkerBackingThread> Create(WebThread* thread) { return WTF::WrapUnique(new WorkerBackingThread(thread, false)); @@ -35,8 +36,9 @@ // These are needed to suppress leak reports. See // https://crbug.com/590802 and https://crbug.com/v8/1428. - static std::unique_ptr<WorkerBackingThread> CreateForTest(const char* name) { - return WTF::WrapUnique(new WorkerBackingThread(name, true)); + static std::unique_ptr<WorkerBackingThread> CreateForTest( + const WebThreadCreationParams& params) { + return WTF::WrapUnique(new WorkerBackingThread(params, true)); } static std::unique_ptr<WorkerBackingThread> CreateForTest(WebThread* thread) { return WTF::WrapUnique(new WorkerBackingThread(thread, true)); @@ -64,7 +66,8 @@ static void SetRAILModeOnWorkerThreadIsolates(v8::RAILMode); private: - WorkerBackingThread(const char* name, bool should_call_gc_on_shutdown); + WorkerBackingThread(const WebThreadCreationParams&, + bool should_call_gc_on_shutdown); WorkerBackingThread(WebThread*, bool should_call_gc_on_s_hutdown); std::unique_ptr<WebThreadSupportingGC> backing_thread_;
diff --git a/third_party/WebKit/Source/core/workers/WorkerThreadTestHelper.h b/third_party/WebKit/Source/core/workers/WorkerThreadTestHelper.h index 45b01831..c232522 100644 --- a/third_party/WebKit/Source/core/workers/WorkerThreadTestHelper.h +++ b/third_party/WebKit/Source/core/workers/WorkerThreadTestHelper.h
@@ -80,8 +80,8 @@ WorkerThreadForTest(ThreadableLoadingContext* loading_context, WorkerReportingProxy& mock_worker_reporting_proxy) : WorkerThread(loading_context, mock_worker_reporting_proxy), - worker_backing_thread_( - WorkerBackingThread::CreateForTest("Test thread")) {} + worker_backing_thread_(WorkerBackingThread::CreateForTest( + WebThreadCreationParams("Test thread"))) {} ~WorkerThreadForTest() override = default;
diff --git a/third_party/WebKit/Source/core/workers/WorkletThreadHolder.h b/third_party/WebKit/Source/core/workers/WorkletThreadHolder.h index bdcc79b..2833f079 100644 --- a/third_party/WebKit/Source/core/workers/WorkletThreadHolder.h +++ b/third_party/WebKit/Source/core/workers/WorkletThreadHolder.h
@@ -32,7 +32,7 @@ return; thread_holder_instance_ = new WorkletThreadHolder<DerivedWorkletThread>; thread_holder_instance_->Initialize( - WorkerBackingThread::Create(thread_name)); + WorkerBackingThread::Create(WebThreadCreationParams(thread_name))); } static void EnsureInstance(WebThread* thread) { @@ -44,12 +44,12 @@ thread_holder_instance_->Initialize(WorkerBackingThread::Create(thread)); } - static void CreateForTest(const char* thread_name) { + static void CreateForTest(const WebThreadCreationParams& params) { MutexLocker locker(HolderInstanceMutex()); DCHECK(!thread_holder_instance_); thread_holder_instance_ = new WorkletThreadHolder<DerivedWorkletThread>; thread_holder_instance_->Initialize( - WorkerBackingThread::CreateForTest(thread_name)); + WorkerBackingThread::CreateForTest(params)); } static void CreateForTest(WebThread* thread) {
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/CSSMetadata.js b/third_party/WebKit/Source/devtools/front_end/sdk/CSSMetadata.js index dc8d335..9b1666a3 100644 --- a/third_party/WebKit/Source/devtools/front_end/sdk/CSSMetadata.js +++ b/third_party/WebKit/Source/devtools/front_end/sdk/CSSMetadata.js
@@ -984,6 +984,18 @@ 'ry': {values: ['auto']}, 'scale': {values: ['none']}, 'scroll-behavior': {values: ['auto', 'smooth']}, + 'scroll-customization': { + values: [ + 'none', + 'auto', + 'pan-x', + 'pan-y', + 'pan-left', + 'pan-right', + 'pan-up', + 'pan-down', + ] + }, 'shape-outside': {values: ['none', 'border-box', 'content-box', 'padding-box', 'margin-box']}, 'shape-rendering': {values: ['auto', 'optimizespeed', 'geometricprecision', 'crispedges']}, 'stroke': {values: ['none']},
diff --git a/third_party/WebKit/Source/modules/animationworklet/AnimationWorkletThreadTest.cpp b/third_party/WebKit/Source/modules/animationworklet/AnimationWorkletThreadTest.cpp index 79325f0..725f0811 100644 --- a/third_party/WebKit/Source/modules/animationworklet/AnimationWorkletThreadTest.cpp +++ b/third_party/WebKit/Source/modules/animationworklet/AnimationWorkletThreadTest.cpp
@@ -39,7 +39,8 @@ class AnimationWorkletTestPlatform : public TestingPlatformSupport { public: AnimationWorkletTestPlatform() - : thread_(old_platform_->CreateThread("Compositor")) {} + : thread_(old_platform_->CreateThread( + WebThreadCreationParams("Compositor"))) {} WebThread* CompositorThread() const override { return thread_.get(); }
diff --git a/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.cpp b/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.cpp index e221195..5f4750a 100644 --- a/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.cpp +++ b/third_party/WebKit/Source/modules/media_controls/MediaControlsImpl.cpp
@@ -595,7 +595,7 @@ if (MediaElement().IsHTMLVideoElement() && !VideoElement().HasAvailableVideoFrame() && VideoElement().PosterImageURL().IsEmpty() && - state != ControlsState::kScrubbing) { + state <= ControlsState::kLoadingMetadata) { builder.Append(" "); builder.Append(kShowDefaultPosterCSSClass); }
diff --git a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlInputElement.cpp b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlInputElement.cpp index 42cffce..1d6ba06 100644 --- a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlInputElement.cpp +++ b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlInputElement.cpp
@@ -6,6 +6,8 @@ #include "core/dom/DOMTokenList.h" #include "core/dom/events/Event.h" +#include "core/html/HTMLDivElement.h" +#include "core/html/HTMLSpanElement.h" #include "core/html/forms/HTMLLabelElement.h" #include "core/html/media/HTMLMediaElement.h" #include "modules/media_controls/MediaControlsImpl.h" @@ -20,6 +22,9 @@ // The default size of an overflow button in pixels. constexpr int kDefaultButtonSize = 36; +const char kOverflowContainerWithSubtitleCSSClass[] = "with-subtitle"; +const char kOverflowSubtitleCSSClass[] = "subtitle"; + } // namespace namespace blink { @@ -52,8 +57,9 @@ // We don't want the button visible within the overflow menu. button->SetInlineStyleProperty(CSSPropertyDisplay, CSSValueNone); - overflow_menu_text_ = - Text::Create(GetDocument(), button->GetOverflowMenuString()); + overflow_menu_text_ = HTMLSpanElement::Create(GetDocument()); + overflow_menu_text_->setInnerText(button->GetOverflowMenuString(), + ASSERT_NO_EXCEPTION); HTMLLabelElement* element = HTMLLabelElement::Create(GetDocument()); element->SetShadowPseudoId( @@ -61,7 +67,15 @@ // Appending a button to a label element ensures that clicks on the label // are passed down to the button, performing the action we'd expect. element->AppendChild(button); - element->AppendChild(overflow_menu_text_); + + if (MediaControlsImpl::IsModern()) { + overflow_menu_container_ = HTMLDivElement::Create(GetDocument()); + overflow_menu_container_->AppendChild(overflow_menu_text_); + UpdateOverflowSubtitleElement(button->GetOverflowMenuSubtitleString()); + element->AppendChild(overflow_menu_container_); + } else { + element->AppendChild(overflow_menu_text_); + } // Initialize the internal states of the main element and the overflow one. button->is_overflow_element_ = true; @@ -76,6 +90,39 @@ return element; } +void MediaControlInputElement::UpdateOverflowSubtitleElement(String text) { + DCHECK(overflow_menu_container_); + + if (!text) { + // If setting the text to null, we want to remove the element. + RemoveOverflowSubtitleElement(); + return; + } + + if (overflow_menu_subtitle_) { + // If element exists, just update the text. + overflow_menu_subtitle_->setInnerText(text, ASSERT_NO_EXCEPTION); + } else { + // Otherwise, create a new element. + overflow_menu_subtitle_ = HTMLSpanElement::Create(GetDocument()); + overflow_menu_subtitle_->setInnerText(text, ASSERT_NO_EXCEPTION); + overflow_menu_subtitle_->setAttribute("class", kOverflowSubtitleCSSClass); + + overflow_menu_container_->AppendChild(overflow_menu_subtitle_); + overflow_menu_container_->setAttribute( + "class", kOverflowContainerWithSubtitleCSSClass); + } +} + +void MediaControlInputElement::RemoveOverflowSubtitleElement() { + if (!overflow_menu_subtitle_) + return; + + overflow_menu_container_->RemoveChild(overflow_menu_subtitle_); + overflow_menu_container_->removeAttribute("class"); + overflow_menu_subtitle_ = nullptr; +} + void MediaControlInputElement::SetOverflowElementIsWanted(bool wanted) { if (!overflow_element_) return; @@ -105,7 +152,11 @@ return; DCHECK(overflow_element_); - overflow_menu_text_->ReplaceWholeText(GetOverflowMenuString()); + overflow_menu_text_->setInnerText(GetOverflowMenuString(), + ASSERT_NO_EXCEPTION); + + if (MediaControlsImpl::IsModern()) + UpdateOverflowSubtitleElement(GetOverflowMenuSubtitleString()); } MediaControlInputElement::MediaControlInputElement( @@ -184,6 +235,10 @@ return MediaElement().GetLocale().QueryString(GetOverflowStringName()); } +String MediaControlInputElement::GetOverflowMenuSubtitleString() const { + return String(); +} + void MediaControlInputElement::RecordCTREvent(CTREvent event) { String histogram_name("Media.Controls.CTR."); histogram_name.append(GetNameForHistograms()); @@ -219,7 +274,9 @@ HTMLInputElement::Trace(visitor); MediaControlElementBase::Trace(visitor); visitor->Trace(overflow_element_); + visitor->Trace(overflow_menu_container_); visitor->Trace(overflow_menu_text_); + visitor->Trace(overflow_menu_subtitle_); } } // namespace blink
diff --git a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlInputElement.h b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlInputElement.h index 83214ef..c3be0de 100644 --- a/third_party/WebKit/Source/modules/media_controls/elements/MediaControlInputElement.h +++ b/third_party/WebKit/Source/modules/media_controls/elements/MediaControlInputElement.h
@@ -82,6 +82,17 @@ // the overflow menu. String GetOverflowMenuString() const; + // Returns a subtitle for the overflow menu text, or a null String if there + // should not be a subtitle. + virtual String GetOverflowMenuSubtitleString() const; + + // Create/update subtitle text on the overflow element. If a null String is + // given, the subtitle element is removed. + void UpdateOverflowSubtitleElement(String text); + + // Remove the subtitle text from the overflow element. + void RemoveOverflowSubtitleElement(); + // Used for histograms, do not reorder. enum class CTREvent { kDisplayed = 0, @@ -96,8 +107,14 @@ // Setting this pointer is optional so it may be null. Member<MediaControlInputElement> overflow_element_; + // Contains the overflow text and its subtitle (if exists). + Member<HTMLDivElement> overflow_menu_container_; + // The text representation of the button within the overflow menu. - Member<Text> overflow_menu_text_; + Member<HTMLSpanElement> overflow_menu_text_; + + // The subtitle of the text within the overflow menu. + Member<HTMLSpanElement> overflow_menu_subtitle_; // Keeps track if the button was created for the purpose of the overflow menu. bool is_overflow_element_ = false;
diff --git a/third_party/WebKit/Source/modules/media_controls/resources/modernMediaControls.css b/third_party/WebKit/Source/modules/media_controls/resources/modernMediaControls.css index f59a6ec..85641ea 100644 --- a/third_party/WebKit/Source/modules/media_controls/resources/modernMediaControls.css +++ b/third_party/WebKit/Source/modules/media_controls/resources/modernMediaControls.css
@@ -411,6 +411,23 @@ margin-right: 6px; } +label[pseudo="-internal-media-controls-overflow-menu-list-item"] div { + display: inline-grid; + margin: 16px 0 16px 0; +} + +label[pseudo="-internal-media-controls-overflow-menu-list-item"] div.with-subtitle { + margin: 8px 0 8px 0; +} + +label[pseudo="-internal-media-controls-overflow-menu-list-item"] div span { + line-height: normal; +} + +label[pseudo="-internal-media-controls-overflow-menu-list-item"] div span.subtitle { + color: rgba(0,0,0,0.54); +} + audio::-internal-media-controls-text-track-list-header:hover, video::-internal-media-controls-text-track-list-header:hover, audio::-internal-media-controls-overflow-menu-list-item:hover,
diff --git a/third_party/WebKit/Source/modules/mediastream/URLMediaStream.cpp b/third_party/WebKit/Source/modules/mediastream/URLMediaStream.cpp index 1f1ceab..925eab3 100644 --- a/third_party/WebKit/Source/modules/mediastream/URLMediaStream.cpp +++ b/third_party/WebKit/Source/modules/mediastream/URLMediaStream.cpp
@@ -31,7 +31,7 @@ #include "modules/mediastream/URLMediaStream.h" #include "core/dom/ExecutionContext.h" -#include "core/frame/UseCounter.h" +#include "core/frame/Deprecation.h" #include "core/url/DOMURL.h" #include "modules/mediastream/MediaStream.h" #include "platform/bindings/ScriptState.h" @@ -47,7 +47,8 @@ DCHECK(execution_context); DCHECK(stream); - UseCounter::Count(execution_context, WebFeature::kCreateObjectURLMediaStream); + Deprecation::CountDeprecation(execution_context, + WebFeature::kCreateObjectURLMediaStream); return DOMURL::CreatePublicURL(execution_context, stream); }
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerThread.cpp b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerThread.cpp index 2abaee5..4b4cc98 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerThread.cpp +++ b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerThread.cpp
@@ -47,8 +47,8 @@ installed_scripts_manager) : WorkerThread(loading_context, *global_scope_proxy), global_scope_proxy_(global_scope_proxy), - worker_backing_thread_( - WorkerBackingThread::Create("ServiceWorker Thread")), + worker_backing_thread_(WorkerBackingThread::Create( + WebThreadCreationParams("ServiceWorker Thread"))), installed_scripts_manager_(std::move(installed_scripts_manager)) {} ServiceWorkerThread::~ServiceWorkerThread() {
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioContextTest.cpp b/third_party/WebKit/Source/modules/webaudio/AudioContextTest.cpp index ef2fbc3..874f49e1b 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioContextTest.cpp +++ b/third_party/WebKit/Source/modules/webaudio/AudioContextTest.cpp
@@ -72,8 +72,9 @@ AudioHardwareSampleRate(), buffer_size); } - std::unique_ptr<WebThread> CreateThread(const char* name) override { - return old_platform_->CreateThread(name); + std::unique_ptr<WebThread> CreateThread( + const WebThreadCreationParams& params) override { + return old_platform_->CreateThread(params); } double AudioHardwareSampleRate() override { return 44100; }
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioNode.cpp b/third_party/WebKit/Source/modules/webaudio/AudioNode.cpp index 36e355c..95aed6e 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioNode.cpp +++ b/third_party/WebKit/Source/modules/webaudio/AudioNode.cpp
@@ -64,6 +64,15 @@ } #endif InstanceCounters::IncrementCounter(InstanceCounters::kAudioHandlerCounter); + +#if DEBUG_AUDIONODE_REFERENCES + fprintf( + stderr, + "[%16p]: %16p: %2d: AudioHandler::AudioHandler() %d [%d] total: %u\n", + Context(), this, GetNodeType(), connection_ref_count_, + node_count_[GetNodeType()], + InstanceCounters::CounterValue(InstanceCounters::kAudioHandlerCounter)); +#endif } AudioHandler::~AudioHandler() { @@ -73,9 +82,13 @@ InstanceCounters::DecrementCounter(InstanceCounters::kAudioHandlerCounter); #if DEBUG_AUDIONODE_REFERENCES --node_count_[GetNodeType()]; - fprintf(stderr, "[%16p]: %16p: %2d: AudioHandler::~AudioHandler() %d [%d]\n", - Context(), this, GetNodeType(), connection_ref_count_, - node_count_[GetNodeType()]); + fprintf( + stderr, + "[%16p]: %16p: %2d: AudioHandler::~AudioHandler() %d [%d] remaining: " + "%u\n", + Context(), this, GetNodeType(), connection_ref_count_, + node_count_[GetNodeType()], + InstanceCounters::CounterValue(InstanceCounters::kAudioHandlerCounter)); #endif } @@ -545,9 +558,26 @@ #endif BaseAudioContext::GraphAutoLocker locker(context()); Handler().Dispose(); - if (context()->ContextState() == BaseAudioContext::kRunning) { - context()->GetDeferredTaskHandler().AddRenderingOrphanHandler( - std::move(handler_)); + + if (context()->HasRealtimeConstraint()) { + // Add the handler to the orphan list if the context is not + // closed. (Nothing will clean up the orphan list if the context + // is closed.) These will get cleaned up in the post render task + // if audio thread is running or when the context is colleced (in + // the worst case). + if (context()->ContextState() != BaseAudioContext::kClosed) { + context()->GetDeferredTaskHandler().AddRenderingOrphanHandler( + std::move(handler_)); + } + } else { + // For an offline context, only need to save the handler when the + // context is running. The change in the context state is + // synchronous with the main thread (even though the offline + // thread is not synchronized to the main thread). + if (context()->ContextState() == BaseAudioContext::kRunning) { + context()->GetDeferredTaskHandler().AddRenderingOrphanHandler( + std::move(handler_)); + } } }
diff --git a/third_party/WebKit/Source/modules/webaudio/BaseAudioContextTest.cpp b/third_party/WebKit/Source/modules/webaudio/BaseAudioContextTest.cpp index ca36e23..44f2dbf 100644 --- a/third_party/WebKit/Source/modules/webaudio/BaseAudioContextTest.cpp +++ b/third_party/WebKit/Source/modules/webaudio/BaseAudioContextTest.cpp
@@ -85,9 +85,10 @@ AudioHardwareSampleRate(), AudioHardwareBufferSize()); } - std::unique_ptr<WebThread> CreateThread(const char* name) override { + std::unique_ptr<WebThread> CreateThread( + const WebThreadCreationParams& params) override { // return base::WrapUnique(old_platform_->CurrentThread()); - return old_platform_->CreateThread(name); + return old_platform_->CreateThread(params); } double AudioHardwareSampleRate() override { return 44100; }
diff --git a/third_party/WebKit/Source/modules/webaudio/OfflineAudioDestinationNode.cpp b/third_party/WebKit/Source/modules/webaudio/OfflineAudioDestinationNode.cpp index fa5bc38..5e469ba 100644 --- a/third_party/WebKit/Source/modules/webaudio/OfflineAudioDestinationNode.cpp +++ b/third_party/WebKit/Source/modules/webaudio/OfflineAudioDestinationNode.cpp
@@ -149,8 +149,8 @@ if (Context()->audioWorklet() && Context()->audioWorklet()->IsReady()) { worklet_backing_thread_ = Context()->audioWorklet()->GetBackingThread(); } else { - render_thread_ = - Platform::Current()->CreateThread("offline audio renderer"); + render_thread_ = Platform::Current()->CreateThread( + WebThreadCreationParams("offline audio renderer")); } render_target_ = render_target;
diff --git a/third_party/WebKit/Source/modules/webdatabase/DatabaseThread.cpp b/third_party/WebKit/Source/modules/webdatabase/DatabaseThread.cpp index fb7a066..fbf4df14 100644 --- a/third_party/WebKit/Source/modules/webdatabase/DatabaseThread.cpp +++ b/third_party/WebKit/Source/modules/webdatabase/DatabaseThread.cpp
@@ -59,7 +59,8 @@ DCHECK(IsMainThread()); if (thread_) return; - thread_ = WebThreadSupportingGC::Create("WebCore: Database"); + thread_ = WebThreadSupportingGC::Create( + WebThreadCreationParams("WebCore: Database")); thread_->PostTask(FROM_HERE, CrossThreadBind(&DatabaseThread::SetupDatabaseThread, WrapCrossThreadPersistent(this)));
diff --git a/third_party/WebKit/Source/platform/BUILD.gn b/third_party/WebKit/Source/platform/BUILD.gn index 6ec3dd05..62dc3e9 100644 --- a/third_party/WebKit/Source/platform/BUILD.gn +++ b/third_party/WebKit/Source/platform/BUILD.gn
@@ -1289,8 +1289,6 @@ "mediastream/MediaStreamSource.h", "mediastream/MediaStreamWebAudioSource.cpp", "mediastream/MediaStreamWebAudioSource.h", - "memory_profiler/SamplingNativeHeapProfiler.cpp", - "memory_profiler/SamplingNativeHeapProfiler.h", "mhtml/ArchiveResource.cpp", "mhtml/ArchiveResource.h", "mhtml/MHTMLArchive.cpp", @@ -1332,6 +1330,8 @@ "scroll/ScrollAnimatorBase.h", "scroll/ScrollAnimatorCompositorCoordinator.cpp", "scroll/ScrollAnimatorCompositorCoordinator.h", + "scroll/ScrollCustomization.cpp", + "scroll/ScrollCustomization.h", "scroll/ScrollSnapData.h", "scroll/ScrollStateData.h", "scroll/ScrollTypes.h", @@ -1531,7 +1531,6 @@ "//third_party/WebKit/Source/platform/scheduler", ] deps = [ - "//base/allocator:features", "//components/viz/service", "//device/base/synchronization", "//device/vr:mojo_bindings_blink",
diff --git a/third_party/WebKit/Source/platform/WebThread.cpp b/third_party/WebKit/Source/platform/WebThread.cpp index da63a2a..b5dd34cb 100644 --- a/third_party/WebKit/Source/platform/WebThread.cpp +++ b/third_party/WebKit/Source/platform/WebThread.cpp
@@ -17,6 +17,9 @@ namespace blink { +WebThreadCreationParams::WebThreadCreationParams(const char* name) + : name(name) {} + #if defined(OS_WIN) static_assert(sizeof(blink::PlatformThreadId) >= sizeof(DWORD), "size of platform thread id is too small");
diff --git a/third_party/WebKit/Source/platform/WebThreadSupportingGC.cpp b/third_party/WebKit/Source/platform/WebThreadSupportingGC.cpp index 551296f..f5ad0f1 100644 --- a/third_party/WebKit/Source/platform/WebThreadSupportingGC.cpp +++ b/third_party/WebKit/Source/platform/WebThreadSupportingGC.cpp
@@ -14,20 +14,22 @@ namespace blink { std::unique_ptr<WebThreadSupportingGC> WebThreadSupportingGC::Create( - const char* name) { - return WTF::WrapUnique(new WebThreadSupportingGC(name, nullptr)); + const WebThreadCreationParams& params) { + return WTF::WrapUnique(new WebThreadSupportingGC(params, nullptr)); } std::unique_ptr<WebThreadSupportingGC> WebThreadSupportingGC::CreateForThread( WebThread* thread) { - return WTF::WrapUnique(new WebThreadSupportingGC(nullptr, thread)); + return WTF::WrapUnique( + new WebThreadSupportingGC(WebThreadCreationParams(nullptr), thread)); } -WebThreadSupportingGC::WebThreadSupportingGC(const char* name, - WebThread* thread) +WebThreadSupportingGC::WebThreadSupportingGC( + const WebThreadCreationParams& params, + WebThread* thread) : thread_(thread) { DCHECK(IsMainThread()); - DCHECK(!name || !thread); + DCHECK(!params.name || !thread); #if DCHECK_IS_ON() // We call this regardless of whether an existing thread is given or not, // as it means that blink is going to run with more than one thread. @@ -35,7 +37,7 @@ #endif if (!thread_) { // If |thread| is not given, create a new one and own it. - owning_thread_ = Platform::Current()->CreateThread(name); + owning_thread_ = Platform::Current()->CreateThread(params); thread_ = owning_thread_.get(); } MemoryCoordinator::RegisterThread(thread_);
diff --git a/third_party/WebKit/Source/platform/WebThreadSupportingGC.h b/third_party/WebKit/Source/platform/WebThreadSupportingGC.h index 2008f1a0..8abe45d 100644 --- a/third_party/WebKit/Source/platform/WebThreadSupportingGC.h +++ b/third_party/WebKit/Source/platform/WebThreadSupportingGC.h
@@ -30,7 +30,8 @@ WTF_MAKE_NONCOPYABLE(WebThreadSupportingGC); public: - static std::unique_ptr<WebThreadSupportingGC> Create(const char* name); + static std::unique_ptr<WebThreadSupportingGC> Create( + const WebThreadCreationParams&); static std::unique_ptr<WebThreadSupportingGC> CreateForThread(WebThread*); ~WebThreadSupportingGC(); @@ -77,7 +78,7 @@ } private: - WebThreadSupportingGC(const char* name, WebThread*); + WebThreadSupportingGC(const WebThreadCreationParams&, WebThread*); std::unique_ptr<GCTaskRunner> gc_task_runner_;
diff --git a/third_party/WebKit/Source/platform/audio/HRTFDatabaseLoader.cpp b/third_party/WebKit/Source/platform/audio/HRTFDatabaseLoader.cpp index f1e0fdc1..cbd61f5 100644 --- a/third_party/WebKit/Source/platform/audio/HRTFDatabaseLoader.cpp +++ b/third_party/WebKit/Source/platform/audio/HRTFDatabaseLoader.cpp
@@ -95,7 +95,8 @@ DCHECK(!thread_); // Start the asynchronous database loading process. - thread_ = Platform::Current()->CreateThread("HRTF database loader"); + thread_ = Platform::Current()->CreateThread( + WebThreadCreationParams("HRTF database loader")); // TODO(alexclarke): Should this be posted as a loading task? PostCrossThreadTask(*thread_->GetWebTaskRunner(), FROM_HERE, CrossThreadBind(&HRTFDatabaseLoader::LoadTask,
diff --git a/third_party/WebKit/Source/platform/audio/PushPullFIFOMultithreadTest.cpp b/third_party/WebKit/Source/platform/audio/PushPullFIFOMultithreadTest.cpp index 00f87d1..21f576f 100644 --- a/third_party/WebKit/Source/platform/audio/PushPullFIFOMultithreadTest.cpp +++ b/third_party/WebKit/Source/platform/audio/PushPullFIFOMultithreadTest.cpp
@@ -29,7 +29,8 @@ FIFOClient(PushPullFIFO* fifo, size_t bus_length, size_t jitter_range_ms) : fifo_(fifo), bus_(AudioBus::Create(fifo->NumberOfChannels(), bus_length)), - client_thread_(Platform::Current()->CreateThread("client thread")), + client_thread_(Platform::Current()->CreateThread( + WebThreadCreationParams("client thread"))), done_event_(std::make_unique<WaitableEvent>()), jitter_range_ms_(jitter_range_ms) {}
diff --git a/third_party/WebKit/Source/platform/audio/ReverbConvolver.cpp b/third_party/WebKit/Source/platform/audio/ReverbConvolver.cpp index a3c0108..b170391 100644 --- a/third_party/WebKit/Source/platform/audio/ReverbConvolver.cpp +++ b/third_party/WebKit/Source/platform/audio/ReverbConvolver.cpp
@@ -139,7 +139,7 @@ // be real-time, but higher than the default... if (use_background_threads && background_stages_.size() > 0) { background_thread_ = Platform::Current()->CreateThread( - "Reverb convolution background thread"); + WebThreadCreationParams("Reverb convolution background thread")); } }
diff --git a/third_party/WebKit/Source/platform/bindings/ActiveScriptWrappableBase.cpp b/third_party/WebKit/Source/platform/bindings/ActiveScriptWrappableBase.cpp index 3ba11d1..eca3ad1d 100644 --- a/third_party/WebKit/Source/platform/bindings/ActiveScriptWrappableBase.cpp +++ b/third_party/WebKit/Source/platform/bindings/ActiveScriptWrappableBase.cpp
@@ -21,7 +21,7 @@ void ActiveScriptWrappableBase::TraceActiveScriptWrappables( v8::Isolate* isolate, - ScriptWrappableVisitor* visitor) { + ScriptWrappableMarkingVisitor* visitor) { V8PerIsolateData* isolate_data = V8PerIsolateData::From(isolate); const auto* active_script_wrappables = isolate_data->ActiveScriptWrappables(); if (!active_script_wrappables)
diff --git a/third_party/WebKit/Source/platform/bindings/ActiveScriptWrappableBase.h b/third_party/WebKit/Source/platform/bindings/ActiveScriptWrappableBase.h index 7ac63c0e..5853b5e 100644 --- a/third_party/WebKit/Source/platform/bindings/ActiveScriptWrappableBase.h +++ b/third_party/WebKit/Source/platform/bindings/ActiveScriptWrappableBase.h
@@ -16,7 +16,7 @@ namespace blink { class ScriptWrappable; -class ScriptWrappableVisitor; +class ScriptWrappableMarkingVisitor; /** * Classes deriving from ActiveScriptWrappable will be registered in a @@ -30,7 +30,7 @@ ActiveScriptWrappableBase(); static void TraceActiveScriptWrappables(v8::Isolate*, - ScriptWrappableVisitor*); + ScriptWrappableMarkingVisitor*); protected: virtual bool IsContextDestroyed() const = 0;
diff --git a/third_party/WebKit/Source/platform/bindings/DOMDataStore.h b/third_party/WebKit/Source/platform/bindings/DOMDataStore.h index e519368..6755e914 100644 --- a/third_party/WebKit/Source/platform/bindings/DOMDataStore.h +++ b/third_party/WebKit/Source/platform/bindings/DOMDataStore.h
@@ -137,8 +137,8 @@ return object->SetWrapper(isolate, wrapper_type_info, wrapper); bool updated = wrapper_map_->Set(object, wrapper_type_info, wrapper); if (updated) { - ScriptWrappableVisitor::WriteBarrier(isolate, &wrapper_map_.value(), - object); + ScriptWrappableMarkingVisitor::WriteBarrier( + isolate, &wrapper_map_.value(), object); } return updated; }
diff --git a/third_party/WebKit/Source/platform/bindings/ScriptWrappableVisitor.cpp b/third_party/WebKit/Source/platform/bindings/ScriptWrappableVisitor.cpp index 2292cbc6..49dc867c 100644 --- a/third_party/WebKit/Source/platform/bindings/ScriptWrappableVisitor.cpp +++ b/third_party/WebKit/Source/platform/bindings/ScriptWrappableVisitor.cpp
@@ -24,9 +24,9 @@ namespace blink { -ScriptWrappableVisitor::~ScriptWrappableVisitor() = default; +ScriptWrappableMarkingVisitor::~ScriptWrappableMarkingVisitor() = default; -void ScriptWrappableVisitor::TracePrologue() { +void ScriptWrappableMarkingVisitor::TracePrologue() { // This CHECK ensures that wrapper tracing is not started from scopes // that forbid GC execution, e.g., constructors. CHECK(ThreadState::Current()); @@ -42,18 +42,18 @@ ThreadState::Current()->SetWrapperTracingInProgress(true); } -void ScriptWrappableVisitor::EnterFinalPause() { +void ScriptWrappableMarkingVisitor::EnterFinalPause() { CHECK(ThreadState::Current()); CHECK(!ThreadState::Current()->IsWrapperTracingForbidden()); ActiveScriptWrappableBase::TraceActiveScriptWrappables(isolate_, this); } -void ScriptWrappableVisitor::TraceEpilogue() { +void ScriptWrappableMarkingVisitor::TraceEpilogue() { CHECK(ThreadState::Current()); CHECK(!ThreadState::Current()->IsWrapperTracingForbidden()); DCHECK(marking_deque_.IsEmpty()); #if DCHECK_IS_ON() - ScriptWrappableVisitorVerifier verifier(isolate_, &verifier_deque_); + ScriptWrappableVisitorVerifier verifier(&verifier_deque_); verifier.Verify(); #endif @@ -63,7 +63,7 @@ ScheduleIdleLazyCleanup(); } -void ScriptWrappableVisitor::AbortTracing() { +void ScriptWrappableMarkingVisitor::AbortTracing() { CHECK(ThreadState::Current()); should_cleanup_ = true; tracing_in_progress_ = false; @@ -71,12 +71,12 @@ PerformCleanup(); } -size_t ScriptWrappableVisitor::NumberOfWrappersToTrace() { +size_t ScriptWrappableMarkingVisitor::NumberOfWrappersToTrace() { CHECK(ThreadState::Current()); return marking_deque_.size(); } -void ScriptWrappableVisitor::PerformCleanup() { +void ScriptWrappableMarkingVisitor::PerformCleanup() { if (!should_cleanup_) return; @@ -95,7 +95,7 @@ should_cleanup_ = false; } -void ScriptWrappableVisitor::ScheduleIdleLazyCleanup() { +void ScriptWrappableMarkingVisitor::ScheduleIdleLazyCleanup() { WebThread* const thread = Platform::Current()->CurrentThread(); // Thread might already be gone, or some threads (e.g. PPAPI) don't have a // scheduler. @@ -106,19 +106,20 @@ return; Platform::Current()->CurrentThread()->Scheduler()->PostIdleTask( - FROM_HERE, WTF::Bind(&ScriptWrappableVisitor::PerformLazyCleanup, + FROM_HERE, WTF::Bind(&ScriptWrappableMarkingVisitor::PerformLazyCleanup, WTF::Unretained(this))); idle_cleanup_task_scheduled_ = true; } -void ScriptWrappableVisitor::PerformLazyCleanup(double deadline_seconds) { +void ScriptWrappableMarkingVisitor::PerformLazyCleanup( + double deadline_seconds) { idle_cleanup_task_scheduled_ = false; if (!should_cleanup_) return; TRACE_EVENT1("blink_gc,devtools.timeline", - "ScriptWrappableVisitor::performLazyCleanup", + "ScriptWrappableMarkingVisitor::performLazyCleanup", "idleDeltaInSeconds", deadline_seconds - CurrentTimeTicksInSeconds()); @@ -152,7 +153,7 @@ should_cleanup_ = false; } -void ScriptWrappableVisitor::RegisterV8Reference( +void ScriptWrappableMarkingVisitor::RegisterV8Reference( const std::pair<void*, void*>& internal_fields) { if (!tracing_in_progress_) { return; @@ -173,7 +174,7 @@ wrapper_type_info->TraceWrappers(this, script_wrappable); } -void ScriptWrappableVisitor::RegisterV8References( +void ScriptWrappableMarkingVisitor::RegisterV8References( const std::vector<std::pair<void*, void*>>& internal_fields_of_potential_wrappers) { CHECK(ThreadState::Current()); @@ -184,7 +185,7 @@ } } -bool ScriptWrappableVisitor::AdvanceTracing( +bool ScriptWrappableMarkingVisitor::AdvanceTracing( double deadline_in_ms, v8::EmbedderHeapTracer::AdvanceTracingActions actions) { // Do not drain the marking deque in a state where we can generally not @@ -205,7 +206,8 @@ return true; } -void ScriptWrappableVisitor::MarkWrapperHeader(HeapObjectHeader* header) const { +void ScriptWrappableMarkingVisitor::MarkWrapperHeader( + HeapObjectHeader* header) const { DCHECK(!header->IsWrapperHeaderMarked()); // Verify that no compactable & movable objects are slated for // lazy unmarking. @@ -215,10 +217,10 @@ headers_to_unmark_.push_back(header); } -void ScriptWrappableVisitor::WriteBarrier( +void ScriptWrappableMarkingVisitor::WriteBarrier( v8::Isolate* isolate, const TraceWrapperV8Reference<v8::Value>& dst_object) { - ScriptWrappableVisitor* visitor = CurrentVisitor(isolate); + ScriptWrappableMarkingVisitor* visitor = CurrentVisitor(isolate); if (dst_object.IsEmpty() || !visitor->WrapperTracingInProgress()) return; @@ -227,11 +229,11 @@ visitor->TraceWrappers(dst_object); } -void ScriptWrappableVisitor::WriteBarrier( +void ScriptWrappableMarkingVisitor::WriteBarrier( v8::Isolate* isolate, DOMWrapperMap<ScriptWrappable>* wrapper_map, ScriptWrappable* key) { - ScriptWrappableVisitor* visitor = CurrentVisitor(isolate); + ScriptWrappableMarkingVisitor* visitor = CurrentVisitor(isolate); if (!visitor->WrapperTracingInProgress()) return; // Conservatively assume that the source object key is marked. @@ -244,7 +246,7 @@ Visit(wrapper_map, key); } -void ScriptWrappableVisitor::Visit( +void ScriptWrappableMarkingVisitor::Visit( const TraceWrapperV8Reference<v8::Value>& traced_wrapper) const { // The write barrier may try to mark a wrapper because cleanup is still // delayed. Bail out in this case. We also allow unconditional marking which @@ -254,7 +256,7 @@ traced_wrapper.Get().RegisterExternalReference(isolate_); } -void ScriptWrappableVisitor::Visit( +void ScriptWrappableMarkingVisitor::Visit( const WrapperDescriptor& wrapper_descriptor) const { HeapObjectHeader* header = wrapper_descriptor.heap_object_header_callback( wrapper_descriptor.traceable); @@ -271,8 +273,9 @@ #endif } -void ScriptWrappableVisitor::Visit(DOMWrapperMap<ScriptWrappable>* wrapper_map, - const ScriptWrappable* key) const { +void ScriptWrappableMarkingVisitor::Visit( + DOMWrapperMap<ScriptWrappable>* wrapper_map, + const ScriptWrappable* key) const { wrapper_map->MarkWrapper(const_cast<ScriptWrappable*>(key)); } @@ -286,7 +289,7 @@ wrapper_base->TraceWrappers(this); } -void ScriptWrappableVisitor::InvalidateDeadObjectsInMarkingDeque() { +void ScriptWrappableMarkingVisitor::InvalidateDeadObjectsInMarkingDeque() { for (auto it = marking_deque_.begin(); it != marking_deque_.end(); ++it) { auto& marking_data = *it; if (marking_data.ShouldBeInvalidated()) { @@ -308,24 +311,24 @@ } } -void ScriptWrappableVisitor::InvalidateDeadObjectsInMarkingDeque( +void ScriptWrappableMarkingVisitor::InvalidateDeadObjectsInMarkingDeque( v8::Isolate* isolate) { - ScriptWrappableVisitor* script_wrappable_visitor = - V8PerIsolateData::From(isolate)->GetScriptWrappableVisitor(); + ScriptWrappableMarkingVisitor* script_wrappable_visitor = + V8PerIsolateData::From(isolate)->GetScriptWrappableMarkingVisitor(); if (script_wrappable_visitor) script_wrappable_visitor->InvalidateDeadObjectsInMarkingDeque(); } -void ScriptWrappableVisitor::PerformCleanup(v8::Isolate* isolate) { - ScriptWrappableVisitor* script_wrappable_visitor = - V8PerIsolateData::From(isolate)->GetScriptWrappableVisitor(); +void ScriptWrappableMarkingVisitor::PerformCleanup(v8::Isolate* isolate) { + ScriptWrappableMarkingVisitor* script_wrappable_visitor = + V8PerIsolateData::From(isolate)->GetScriptWrappableMarkingVisitor(); if (script_wrappable_visitor) script_wrappable_visitor->PerformCleanup(); } -ScriptWrappableVisitor* ScriptWrappableVisitor::CurrentVisitor( +ScriptWrappableMarkingVisitor* ScriptWrappableMarkingVisitor::CurrentVisitor( v8::Isolate* isolate) { - return V8PerIsolateData::From(isolate)->GetScriptWrappableVisitor(); + return V8PerIsolateData::From(isolate)->GetScriptWrappableMarkingVisitor(); } } // namespace blink
diff --git a/third_party/WebKit/Source/platform/bindings/ScriptWrappableVisitor.h b/third_party/WebKit/Source/platform/bindings/ScriptWrappableVisitor.h index a388901..45f32a0 100644 --- a/third_party/WebKit/Source/platform/bindings/ScriptWrappableVisitor.h +++ b/third_party/WebKit/Source/platform/bindings/ScriptWrappableVisitor.h
@@ -96,14 +96,115 @@ const void* raw_object_pointer_; }; +// Abstract visitor for wrapper references in a ScriptWrappable. +// Usage: +// - Define a derived class that overrides Visit(..) methods. +// - Create an instance of the derived class: visitor. +// - Call visitor.DispatchTraceWrappers(traceable). +// DispatchTraceWrappers will invoke Visit() method for all +// wrapper references in traceable. +class PLATFORM_EXPORT ScriptWrappableVisitor { + public: + // Trace all wrappers of |tracable|. + // + // If you cannot use TraceWrapperMember & the corresponding TraceWrappers() + // for some reason (e.g., unions using raw pointers), see + // |TraceWrappersWithManualWriteBarrier()| below. + template <typename T> + void TraceWrappers(const TraceWrapperMember<T>& traceable) const { + static_assert(sizeof(T), "T must be fully defined"); + Visit(traceable.Get()); + } + + // Enable partial tracing of objects. This is used when tracing interior + // objects without their own header. + template <typename T> + void TraceWrappers(const T& traceable) const { + static_assert(sizeof(T), "T must be fully defined"); + traceable.TraceWrappers(this); + } + + // Only called from automatically generated bindings code. + template <typename T> + void TraceWrappersFromGeneratedCode(const T* traceable) const { + Visit(traceable); + } + + // Require all users of manual write barriers to make this explicit in their + // |TraceWrappers| definition. Be sure to add + // |ScriptWrappableMarkingVisitor::WriteBarrier(new_value)| after all + // assignments to the field. Otherwise, the objects may be collected + // prematurely. + template <typename T> + void TraceWrappersWithManualWriteBarrier(const T* traceable) const { + Visit(traceable); + } + + template <typename V8Type> + void TraceWrappers(const TraceWrapperV8Reference<V8Type>& v8reference) const { + Visit(v8reference.template Cast<v8::Value>()); + } + + // Trace wrappers in non-main worlds. + void TraceWrappers(DOMWrapperMap<ScriptWrappable>*, + const ScriptWrappable* key) const; + + virtual void DispatchTraceWrappers(const TraceWrapperBase*) const; + template <typename T> + void DispatchTraceWrappers(const Supplement<T>* traceable) const { + const TraceWrapperBaseForSupplement* base = traceable; + DispatchTraceWrappersForSupplement(base); + } + // Catch all handlers needed because of mixins except for Supplement<T>. + void DispatchTraceWrappers(const void*) const { CHECK(false); } + + protected: + // The visitor interface. Derived visitors should override this + // function to visit V8 references and ScriptWrappables. + virtual void Visit(const TraceWrapperV8Reference<v8::Value>&) const = 0; + virtual void Visit(const WrapperDescriptor&) const = 0; + virtual void Visit(DOMWrapperMap<ScriptWrappable>*, + const ScriptWrappable* key) const = 0; + + template <typename T> + static WrapperDescriptor WrapperDescriptorFor(const T* traceable) { + return {traceable, TraceTrait<T>::TraceMarkedWrapper, + TraceTrait<T>::GetHeapObjectHeader, + ScriptWrappableVisitor::MissedWriteBarrier<T>}; + } + + private: + template <typename T> + static NOINLINE void MissedWriteBarrier() { + NOTREACHED(); + } + + // Helper method to invoke the virtual Visit method with wrapper descriptor. + template <typename T> + void Visit(const T* traceable) const { + static_assert(sizeof(T), "T must be fully defined"); + if (!traceable) + return; + Visit(WrapperDescriptorFor(traceable)); + } + + // Supplement-specific implementation of DispatchTraceWrappers. The suffix of + // "ForSupplement" is necessary not to make this member function a candidate + // of overload resolutions. + void DispatchTraceWrappersForSupplement( + const TraceWrapperBaseForSupplement*) const; +}; + // ScriptWrappableVisitor is used to trace through Blink's heap to find all // reachable wrappers. V8 calls this visitor during its garbage collection, // see v8::EmbedderHeapTracer. -class PLATFORM_EXPORT ScriptWrappableVisitor : public v8::EmbedderHeapTracer { - DISALLOW_IMPLICIT_CONSTRUCTORS(ScriptWrappableVisitor); +class PLATFORM_EXPORT ScriptWrappableMarkingVisitor + : public v8::EmbedderHeapTracer, + public ScriptWrappableVisitor { + DISALLOW_IMPLICIT_CONSTRUCTORS(ScriptWrappableMarkingVisitor); public: - static ScriptWrappableVisitor* CurrentVisitor(v8::Isolate*); + static ScriptWrappableMarkingVisitor* CurrentVisitor(v8::Isolate*); bool WrapperTracingInProgress() const { return tracing_in_progress_; } @@ -140,7 +241,8 @@ if (TraceTrait<T>::GetHeapObjectHeader(dst_object)->IsWrapperHeaderMarked()) return; - CurrentVisitor(thread_state->GetIsolate())->Visit(dst_object); + CurrentVisitor(thread_state->GetIsolate()) + ->Visit(WrapperDescriptorFor(dst_object)); } static void WriteBarrier(v8::Isolate*, @@ -150,60 +252,8 @@ DOMWrapperMap<ScriptWrappable>*, ScriptWrappable* key); - ScriptWrappableVisitor(v8::Isolate* isolate) : isolate_(isolate){}; - ~ScriptWrappableVisitor() override; - - // Trace all wrappers of |t|. - // - // If you cannot use TraceWrapperMember & the corresponding TraceWrappers() - // for some reason (e.g., unions using raw pointers), see - // |TraceWrappersWithManualWriteBarrier()| below. - // TODO(ulan): extract TraceWrappers* methods to a general visitor interface. - template <typename T> - void TraceWrappers(const TraceWrapperMember<T>& traceable) const { - Visit(traceable.Get()); - } - - // Enable partial tracing of objects. This is used when tracing interior - // objects without their own header. - template <typename T> - void TraceWrappers(const T& traceable) const { - static_assert(sizeof(T), "T must be fully defined"); - traceable.TraceWrappers(this); - } - - // Only called from automatically generated bindings code. - template <typename T> - void TraceWrappersFromGeneratedCode(const T* traceable) const { - Visit(traceable); - } - - // Require all users of manual write barriers to make this explicit in their - // |TraceWrappers| definition. Be sure to add - // |ScriptWrappableVisitor::WriteBarrier(new_value)| after all assignments to - // the field. Otherwise, the objects may be collected prematurely. - template <typename T> - void TraceWrappersWithManualWriteBarrier(const T* traceable) const { - Visit(traceable); - } - - template <typename V8Type> - void TraceWrappers(const TraceWrapperV8Reference<V8Type>& v8reference) const { - Visit(v8reference.template Cast<v8::Value>()); - } - - // Trace a wrapper in a non-main world. - void TraceWrappers(DOMWrapperMap<ScriptWrappable>*, - const ScriptWrappable* key) const; - - virtual void DispatchTraceWrappers(const TraceWrapperBase*) const; - template <typename T> - void DispatchTraceWrappers(const Supplement<T>* traceable) const { - const TraceWrapperBaseForSupplement* base = traceable; - DispatchTraceWrappersForSupplement(base); - } - // Catch all handlers needed because of mixins except for Supplement<T>. - void DispatchTraceWrappers(const void*) const { CHECK(false); } + ScriptWrappableMarkingVisitor(v8::Isolate* isolate) : isolate_(isolate){}; + ~ScriptWrappableMarkingVisitor() override; // v8::EmbedderHeapTracer interface. @@ -219,43 +269,17 @@ size_t NumberOfWrappersToTrace() override; protected: - // The visitor interface. Derived visitors should override this - // function to visit V8 references and ScriptWrappables. - // TODO(ulan): extract Visit methods to a general visitor interface. - virtual void Visit(const TraceWrapperV8Reference<v8::Value>&) const; - virtual void Visit(const WrapperDescriptor&) const; - virtual void Visit(DOMWrapperMap<ScriptWrappable>*, - const ScriptWrappable* key) const; + // ScriptWrappableVisitor interface. + void Visit(const TraceWrapperV8Reference<v8::Value>&) const override; + void Visit(const WrapperDescriptor&) const override; + void Visit(DOMWrapperMap<ScriptWrappable>*, + const ScriptWrappable* key) const override; v8::Isolate* isolate() const { return isolate_; } private: - template <typename T> - static NOINLINE void MissedWriteBarrier() { - NOTREACHED(); - } - - // Helper method to invoke the virtual Visit method with wrapper descriptor. - template <typename T> - void Visit(const T* traceable) const { - static_assert(sizeof(T), "T must be fully defined"); - if (!traceable) - return; - WrapperDescriptor wrapper_descriptor = { - traceable, TraceTrait<T>::TraceMarkedWrapper, - TraceTrait<T>::GetHeapObjectHeader, - ScriptWrappableVisitor::MissedWriteBarrier<T>}; - Visit(wrapper_descriptor); - } - void MarkWrapperHeader(HeapObjectHeader*) const; - // Supplement-specific implementation of DispatchTraceWrappers. The suffix of - // "ForSupplement" is necessary not to make this member function a candidate - // of overload resolutions. - void DispatchTraceWrappersForSupplement( - const TraceWrapperBaseForSupplement*) const; - // Schedule an idle task to perform a lazy (incremental) clean up of // wrappers. void ScheduleIdleLazyCleanup(); @@ -317,22 +341,22 @@ mutable WTF::Vector<HeapObjectHeader*> headers_to_unmark_; v8::Isolate* isolate_; - FRIEND_TEST_ALL_PREFIXES(ScriptWrappableVisitorTest, MixinTracing); - FRIEND_TEST_ALL_PREFIXES(ScriptWrappableVisitorTest, + FRIEND_TEST_ALL_PREFIXES(ScriptWrappableMarkingVisitorTest, MixinTracing); + FRIEND_TEST_ALL_PREFIXES(ScriptWrappableMarkingVisitorTest, OilpanClearsMarkingDequeWhenObjectDied); - FRIEND_TEST_ALL_PREFIXES(ScriptWrappableVisitorTest, - ScriptWrappableVisitorTracesWrappers); - FRIEND_TEST_ALL_PREFIXES(ScriptWrappableVisitorTest, + FRIEND_TEST_ALL_PREFIXES(ScriptWrappableMarkingVisitorTest, + ScriptWrappableMarkingVisitorTracesWrappers); + FRIEND_TEST_ALL_PREFIXES(ScriptWrappableMarkingVisitorTest, OilpanClearsHeadersWhenObjectDied); FRIEND_TEST_ALL_PREFIXES( - ScriptWrappableVisitorTest, + ScriptWrappableMarkingVisitorTest, MarkedObjectDoesNothingOnWriteBarrierHitWhenDependencyIsMarkedToo); FRIEND_TEST_ALL_PREFIXES( - ScriptWrappableVisitorTest, + ScriptWrappableMarkingVisitorTest, MarkedObjectMarksDependencyOnWriteBarrierHitWhenNotMarked); - FRIEND_TEST_ALL_PREFIXES(ScriptWrappableVisitorTest, + FRIEND_TEST_ALL_PREFIXES(ScriptWrappableMarkingVisitorTest, WriteBarrierOnHeapVectorSwap1); - FRIEND_TEST_ALL_PREFIXES(ScriptWrappableVisitorTest, + FRIEND_TEST_ALL_PREFIXES(ScriptWrappableMarkingVisitorTest, WriteBarrierOnHeapVectorSwap2); };
diff --git a/third_party/WebKit/Source/platform/bindings/ScriptWrappableVisitorVerifier.h b/third_party/WebKit/Source/platform/bindings/ScriptWrappableVisitorVerifier.h index 849f4ef..164cd59 100644 --- a/third_party/WebKit/Source/platform/bindings/ScriptWrappableVisitorVerifier.h +++ b/third_party/WebKit/Source/platform/bindings/ScriptWrappableVisitorVerifier.h
@@ -15,9 +15,8 @@ // For each object in the deque the verifier checks that all children of // the object are marked. ScriptWrappableVisitorVerifier( - v8::Isolate* isolate, const WTF::Deque<WrapperMarkingData>* verifier_deque) - : ScriptWrappableVisitor(isolate), verifier_deque_(verifier_deque) {} + : verifier_deque_(verifier_deque) {} void Verify() { for (auto& marking_data : *verifier_deque_) {
diff --git a/third_party/WebKit/Source/platform/bindings/TraceWrapperMember.h b/third_party/WebKit/Source/platform/bindings/TraceWrapperMember.h index 9e91304..fe361d80 100644 --- a/third_party/WebKit/Source/platform/bindings/TraceWrapperMember.h +++ b/third_party/WebKit/Source/platform/bindings/TraceWrapperMember.h
@@ -31,7 +31,7 @@ TraceWrapperMember(T* raw) : Member<T>(raw) { // We have to use a write barrier here because of in-place construction // in containers, such as HeapVector::push_back. - ScriptWrappableVisitor::WriteBarrier(raw); + ScriptWrappableMarkingVisitor::WriteBarrier(raw); } TraceWrapperMember(WTF::HashTableDeletedValueType x) : Member<T>(x) {} @@ -41,21 +41,21 @@ TraceWrapperMember& operator=(const TraceWrapperMember& other) { Member<T>::operator=(other); DCHECK_EQ(other.Get(), this->Get()); - ScriptWrappableVisitor::WriteBarrier(this->Get()); + ScriptWrappableMarkingVisitor::WriteBarrier(this->Get()); return *this; } TraceWrapperMember& operator=(const Member<T>& other) { Member<T>::operator=(other); DCHECK_EQ(other.Get(), this->Get()); - ScriptWrappableVisitor::WriteBarrier(this->Get()); + ScriptWrappableMarkingVisitor::WriteBarrier(this->Get()); return *this; } TraceWrapperMember& operator=(T* other) { Member<T>::operator=(other); DCHECK_EQ(other, this->Get()); - ScriptWrappableVisitor::WriteBarrier(this->Get()); + ScriptWrappableMarkingVisitor::WriteBarrier(this->Get()); return *this; } @@ -81,10 +81,10 @@ // If incremental marking is enabled we need to emit the write barrier since // the swap was performed on HeapVector<Member<T>>. for (auto item : a) { - ScriptWrappableVisitor::WriteBarrier(item.Get()); + ScriptWrappableMarkingVisitor::WriteBarrier(item.Get()); } for (auto item : b) { - ScriptWrappableVisitor::WriteBarrier(item.Get()); + ScriptWrappableMarkingVisitor::WriteBarrier(item.Get()); } } } @@ -102,7 +102,7 @@ // If incremental marking is enabled we need to emit the write barrier since // the swap was performed on HeapVector<Member<T>>. for (auto item : a) { - ScriptWrappableVisitor::WriteBarrier(item.Get()); + ScriptWrappableMarkingVisitor::WriteBarrier(item.Get()); } } }
diff --git a/third_party/WebKit/Source/platform/bindings/TraceWrapperV8Reference.h b/third_party/WebKit/Source/platform/bindings/TraceWrapperV8Reference.h index 94468ba2..6811605c 100644 --- a/third_party/WebKit/Source/platform/bindings/TraceWrapperV8Reference.h +++ b/third_party/WebKit/Source/platform/bindings/TraceWrapperV8Reference.h
@@ -69,7 +69,8 @@ private: inline void InternalSet(v8::Isolate* isolate, v8::Local<T> handle) { handle_.Reset(isolate, handle); - ScriptWrappableVisitor::WriteBarrier(isolate, UnsafeCast<v8::Value>()); + ScriptWrappableMarkingVisitor::WriteBarrier(isolate, + UnsafeCast<v8::Value>()); } v8::Persistent<T> handle_;
diff --git a/third_party/WebKit/Source/platform/bindings/V8DOMWrapper.h b/third_party/WebKit/Source/platform/bindings/V8DOMWrapper.h index 7dc2123..3fa24b5 100644 --- a/third_party/WebKit/Source/platform/bindings/V8DOMWrapper.h +++ b/third_party/WebKit/Source/platform/bindings/V8DOMWrapper.h
@@ -97,7 +97,7 @@ // so the visitor can make sure to trace the association (in case it is // currently tracing). Because of some optimizations, V8 will not // necessarily detect wrappers created during its incremental marking. - per_isolate_data->GetScriptWrappableVisitor()->RegisterV8Reference( + per_isolate_data->GetScriptWrappableMarkingVisitor()->RegisterV8Reference( std::make_pair(const_cast<WrapperTypeInfo*>(wrapper_type_info), script_wrappable)); }
diff --git a/third_party/WebKit/Source/platform/bindings/V8PerIsolateData.cpp b/third_party/WebKit/Source/platform/bindings/V8PerIsolateData.cpp index 0604a54..0a08ed0 100644 --- a/third_party/WebKit/Source/platform/bindings/V8PerIsolateData.cpp +++ b/third_party/WebKit/Source/platform/bindings/V8PerIsolateData.cpp
@@ -358,10 +358,10 @@ void V8PerIsolateData::TemporaryScriptWrappableVisitorScope:: SwapWithV8PerIsolateDataVisitor( - std::unique_ptr<ScriptWrappableVisitor>& visitor) { - ScriptWrappableVisitor* current = CurrentVisitor(); + std::unique_ptr<ScriptWrappableMarkingVisitor>& visitor) { + ScriptWrappableMarkingVisitor* current = CurrentVisitor(); if (current) - ScriptWrappableVisitor::PerformCleanup(isolate_); + ScriptWrappableMarkingVisitor::PerformCleanup(isolate_); V8PerIsolateData::From(isolate_)->script_wrappable_visitor_.swap( saved_visitor_);
diff --git a/third_party/WebKit/Source/platform/bindings/V8PerIsolateData.h b/third_party/WebKit/Source/platform/bindings/V8PerIsolateData.h index 58f1170..96097de 100644 --- a/third_party/WebKit/Source/platform/bindings/V8PerIsolateData.h +++ b/third_party/WebKit/Source/platform/bindings/V8PerIsolateData.h
@@ -205,7 +205,7 @@ public: TemporaryScriptWrappableVisitorScope( v8::Isolate* isolate, - std::unique_ptr<ScriptWrappableVisitor> visitor) + std::unique_ptr<ScriptWrappableMarkingVisitor> visitor) : isolate_(isolate), saved_visitor_(std::move(visitor)) { SwapWithV8PerIsolateDataVisitor(saved_visitor_); } @@ -213,23 +213,24 @@ SwapWithV8PerIsolateDataVisitor(saved_visitor_); } - inline ScriptWrappableVisitor* CurrentVisitor() { - return V8PerIsolateData::From(isolate_)->GetScriptWrappableVisitor(); + inline ScriptWrappableMarkingVisitor* CurrentVisitor() { + return V8PerIsolateData::From(isolate_) + ->GetScriptWrappableMarkingVisitor(); } private: void SwapWithV8PerIsolateDataVisitor( - std::unique_ptr<ScriptWrappableVisitor>&); + std::unique_ptr<ScriptWrappableMarkingVisitor>&); v8::Isolate* isolate_; - std::unique_ptr<ScriptWrappableVisitor> saved_visitor_; + std::unique_ptr<ScriptWrappableMarkingVisitor> saved_visitor_; }; - void SetScriptWrappableVisitor( - std::unique_ptr<ScriptWrappableVisitor> visitor) { + void SetScriptWrappableMarkingVisitor( + std::unique_ptr<ScriptWrappableMarkingVisitor> visitor) { script_wrappable_visitor_ = std::move(visitor); } - ScriptWrappableVisitor* GetScriptWrappableVisitor() { + ScriptWrappableMarkingVisitor* GetScriptWrappableMarkingVisitor() { return script_wrappable_visitor_.get(); } @@ -300,7 +301,7 @@ std::unique_ptr<Data> thread_debugger_; Persistent<ActiveScriptWrappableSet> active_script_wrappables_; - std::unique_ptr<ScriptWrappableVisitor> script_wrappable_visitor_; + std::unique_ptr<ScriptWrappableMarkingVisitor> script_wrappable_visitor_; RuntimeCallStats runtime_call_stats_; };
diff --git a/third_party/WebKit/Source/platform/exported/Platform.cpp b/third_party/WebKit/Source/platform/exported/Platform.cpp index 366f5b9..5ff71d1 100644 --- a/third_party/WebKit/Source/platform/exported/Platform.cpp +++ b/third_party/WebKit/Source/platform/exported/Platform.cpp
@@ -163,7 +163,8 @@ // Pre-create the File thread so multiple threads can call FileTaskRunner() in // a non racy way later. - g_platform->file_thread_ = g_platform->CreateThread("File"); + g_platform->file_thread_ = + g_platform->CreateThread(WebThreadCreationParams("File")); if (BlinkResourceCoordinatorBase::IsEnabled()) RendererResourceCoordinator::Initialize(); @@ -220,7 +221,8 @@ return nullptr; } -std::unique_ptr<WebThread> Platform::CreateThread(const char* name) { +std::unique_ptr<WebThread> Platform::CreateThread( + const WebThreadCreationParams& params) { return nullptr; }
diff --git a/third_party/WebKit/Source/platform/graphics/DeferredImageDecoderTest.cpp b/third_party/WebKit/Source/platform/graphics/DeferredImageDecoderTest.cpp index 68fa72c..4a17a56 100644 --- a/third_party/WebKit/Source/platform/graphics/DeferredImageDecoderTest.cpp +++ b/third_party/WebKit/Source/platform/graphics/DeferredImageDecoderTest.cpp
@@ -225,8 +225,8 @@ EXPECT_EQ(0, decode_request_count_); // Create a thread to rasterize PaintRecord. - std::unique_ptr<WebThread> thread = - Platform::Current()->CreateThread("RasterThread"); + std::unique_ptr<WebThread> thread = Platform::Current()->CreateThread( + WebThreadCreationParams("RasterThread")); PostCrossThreadTask( *thread->GetWebTaskRunner(), FROM_HERE, CrossThreadBind(&RasterizeMain, CrossThreadUnretained(canvas_.get()),
diff --git a/third_party/WebKit/Source/platform/graphics/ImageFrameGeneratorTest.cpp b/third_party/WebKit/Source/platform/graphics/ImageFrameGeneratorTest.cpp index d1e1aed..cfba57067 100644 --- a/third_party/WebKit/Source/platform/graphics/ImageFrameGeneratorTest.cpp +++ b/third_party/WebKit/Source/platform/graphics/ImageFrameGeneratorTest.cpp
@@ -256,8 +256,8 @@ // LocalFrame can now be decoded completely. SetFrameStatus(ImageFrame::kFrameComplete); AddNewData(); - std::unique_ptr<WebThread> thread = - Platform::Current()->CreateThread("DecodeThread"); + std::unique_ptr<WebThread> thread = Platform::Current()->CreateThread( + WebThreadCreationParams("DecodeThread")); PostCrossThreadTask( *thread->GetWebTaskRunner(), FROM_HERE, CrossThreadBind(&DecodeThreadMain, WTF::RetainedRef(generator_),
diff --git a/third_party/WebKit/Source/platform/graphics/SurfaceLayerBridge.cpp b/third_party/WebKit/Source/platform/graphics/SurfaceLayerBridge.cpp index 9e19081a..b0a2130c 100644 --- a/third_party/WebKit/Source/platform/graphics/SurfaceLayerBridge.cpp +++ b/third_party/WebKit/Source/platform/graphics/SurfaceLayerBridge.cpp
@@ -8,10 +8,8 @@ #include "cc/layers/layer.h" #include "cc/layers/solid_color_layer.h" #include "cc/layers/surface_layer.h" -#include "components/viz/common/surfaces/sequence_surface_reference_factory.h" #include "components/viz/common/surfaces/surface_id.h" #include "components/viz/common/surfaces/surface_info.h" -#include "components/viz/common/surfaces/surface_sequence.h" #include "media/base/media_switches.h" #include "platform/mojo/MojoHelper.h" #include "platform/wtf/Functional.h" @@ -25,46 +23,13 @@ namespace blink { -namespace { -class SequenceSurfaceReferenceFactoryImpl - : public viz::SequenceSurfaceReferenceFactory { - public: - SequenceSurfaceReferenceFactoryImpl(base::WeakPtr<SurfaceLayerBridge> bridge) - : bridge_(bridge) {} - - private: - ~SequenceSurfaceReferenceFactoryImpl() override = default; - - // cc::SequenceSurfaceReferenceFactory implementation: - void RequireSequence(const viz::SurfaceId& id, - const viz::SurfaceSequence& sequence) const override { - DCHECK(bridge_); - bridge_->RequireCallback(id, sequence); - } - - void SatisfySequence(const viz::SurfaceSequence& sequence) const override { - if (bridge_) - bridge_->SatisfyCallback(sequence); - } - - base::WeakPtr<SurfaceLayerBridge> bridge_; - - DISALLOW_COPY_AND_ASSIGN(SequenceSurfaceReferenceFactoryImpl); -}; - -} // namespace - SurfaceLayerBridge::SurfaceLayerBridge(WebLayerTreeView* layer_tree_view, WebSurfaceLayerBridgeObserver* observer) - : weak_factory_(this), - observer_(observer), + : observer_(observer), binding_(this), frame_sink_id_(Platform::Current()->GenerateFrameSinkId()), parent_frame_sink_id_(layer_tree_view ? layer_tree_view->GetFrameSinkId() : viz::FrameSinkId()) { - ref_factory_ = - new SequenceSurfaceReferenceFactoryImpl(weak_factory_.GetWeakPtr()); - DCHECK(!service_.is_bound()); mojom::blink::OffscreenCanvasProviderPtr provider; Platform::Current()->GetInterfaceProvider()->GetInterface( @@ -83,15 +48,6 @@ observer_ = nullptr; } -void SurfaceLayerBridge::SatisfyCallback(const viz::SurfaceSequence& sequence) { - service_->Satisfy(sequence); -} - -void SurfaceLayerBridge::RequireCallback(const viz::SurfaceId& surface_id, - const viz::SurfaceSequence& sequence) { - service_->Require(surface_id, sequence); -} - void SurfaceLayerBridge::CreateSolidColorLayer() { cc_layer_ = cc::SolidColorLayer::Create(); cc_layer_->SetBackgroundColor(SK_ColorTRANSPARENT); @@ -114,8 +70,7 @@ web_layer_->RemoveFromParent(); } - scoped_refptr<cc::SurfaceLayer> surface_layer = - cc::SurfaceLayer::Create(ref_factory_); + scoped_refptr<cc::SurfaceLayer> surface_layer = cc::SurfaceLayer::Create(); surface_layer->SetPrimarySurfaceId(surface_info.id(), base::nullopt); surface_layer->SetFallbackSurfaceId(surface_info.id()); surface_layer->SetStretchContentToFillBounds(true);
diff --git a/third_party/WebKit/Source/platform/graphics/SurfaceLayerBridge.h b/third_party/WebKit/Source/platform/graphics/SurfaceLayerBridge.h index 0361ef34..00340d75 100644 --- a/third_party/WebKit/Source/platform/graphics/SurfaceLayerBridge.h +++ b/third_party/WebKit/Source/platform/graphics/SurfaceLayerBridge.h
@@ -7,9 +7,7 @@ #include <memory> #include "base/memory/scoped_refptr.h" -#include "base/memory/weak_ptr.h" #include "components/viz/common/surfaces/surface_id.h" -#include "components/viz/common/surfaces/surface_reference_factory.h" #include "mojo/public/cpp/bindings/binding.h" #include "platform/PlatformExport.h" #include "public/platform/WebSurfaceLayerBridge.h" @@ -41,8 +39,6 @@ // Implementation of blink::mojom::blink::OffscreenCanvasSurfaceClient void OnFirstSurfaceActivation(const viz::SurfaceInfo&) override; - void SatisfyCallback(const viz::SurfaceSequence&); - void RequireCallback(const viz::SurfaceId&, const viz::SurfaceSequence&); // Implementation of WebSurfaceLayerBridge. WebLayer* GetWebLayer() const override { return web_layer_.get(); } @@ -57,9 +53,6 @@ scoped_refptr<cc::Layer> cc_layer_; std::unique_ptr<WebLayer> web_layer_; - scoped_refptr<viz::SurfaceReferenceFactory> ref_factory_; - base::WeakPtrFactory<SurfaceLayerBridge> weak_factory_; - WebSurfaceLayerBridgeObserver* observer_; mojo::Binding<blink::mojom::blink::OffscreenCanvasSurfaceClient> binding_;
diff --git a/third_party/WebKit/Source/platform/heap/HeapTest.cpp b/third_party/WebKit/Source/platform/heap/HeapTest.cpp index 0101c35..8909ac8 100644 --- a/third_party/WebKit/Source/platform/heap/HeapTest.cpp +++ b/third_party/WebKit/Source/platform/heap/HeapTest.cpp
@@ -479,8 +479,8 @@ static void Test(ThreadedTesterBase* tester) { Vector<std::unique_ptr<WebThread>, kNumberOfThreads> threads; for (int i = 0; i < kNumberOfThreads; i++) { - threads.push_back( - Platform::Current()->CreateThread("blink gc testing thread")); + threads.push_back(Platform::Current()->CreateThread( + WebThreadCreationParams("blink gc testing thread"))); PostCrossThreadTask( *threads.back()->GetWebTaskRunner(), FROM_HERE, CrossThreadBind(ThreadFunc, CrossThreadUnretained(tester))); @@ -5467,7 +5467,8 @@ MutexLocker locker(MainThreadMutex()); std::unique_ptr<WebThread> worker_thread = - Platform::Current()->CreateThread("Test Worker Thread"); + Platform::Current()->CreateThread( + WebThreadCreationParams("Test Worker Thread")); PostCrossThreadTask(*worker_thread->GetWebTaskRunner(), FROM_HERE, CrossThreadBind(WorkerThreadMain)); @@ -5566,7 +5567,8 @@ MutexLocker locker(MainThreadMutex()); std::unique_ptr<WebThread> worker_thread = - Platform::Current()->CreateThread("Test Worker Thread"); + Platform::Current()->CreateThread( + WebThreadCreationParams("Test Worker Thread")); PostCrossThreadTask( *worker_thread->GetWebTaskRunner(), FROM_HERE, CrossThreadBind(&MemberSameThreadCheckTester::WorkerThreadMain, @@ -5609,7 +5611,8 @@ MutexLocker locker(MainThreadMutex()); std::unique_ptr<WebThread> worker_thread = - Platform::Current()->CreateThread("Test Worker Thread"); + Platform::Current()->CreateThread( + WebThreadCreationParams("Test Worker Thread")); PostCrossThreadTask( *worker_thread->GetWebTaskRunner(), FROM_HERE, CrossThreadBind(&PersistentSameThreadCheckTester::WorkerThreadMain, @@ -5652,7 +5655,8 @@ MutexLocker locker(MainThreadMutex()); std::unique_ptr<WebThread> worker_thread = - Platform::Current()->CreateThread("Test Worker Thread"); + Platform::Current()->CreateThread( + WebThreadCreationParams("Test Worker Thread")); Persistent<MainThreadObject> main_thread_object = new MainThreadObject(); PostCrossThreadTask( *worker_thread->GetWebTaskRunner(), FROM_HERE, @@ -6450,8 +6454,8 @@ // Step 1: Initiate a worker thread, and wait for |object| to get allocated on // the worker thread. MutexLocker main_thread_mutex_locker(MainThreadMutex()); - std::unique_ptr<WebThread> worker_thread = - Platform::Current()->CreateThread("Test Worker Thread"); + std::unique_ptr<WebThread> worker_thread = Platform::Current()->CreateThread( + WebThreadCreationParams("Test Worker Thread")); DestructorLockingObject* object = nullptr; PostCrossThreadTask( *worker_thread->GetWebTaskRunner(), FROM_HERE,
diff --git a/third_party/WebKit/Source/platform/loader/fetch/ResourceResponseTest.cpp b/third_party/WebKit/Source/platform/loader/fetch/ResourceResponseTest.cpp index caf0f866..12eace9 100644 --- a/third_party/WebKit/Source/platform/loader/fetch/ResourceResponseTest.cpp +++ b/third_party/WebKit/Source/platform/loader/fetch/ResourceResponseTest.cpp
@@ -76,8 +76,8 @@ ResourceResponse response(CreateTestResponse()); RunHeaderRelatedTest(response); - std::unique_ptr<WebThread> thread = - Platform::Current()->CreateThread("WorkerThread"); + std::unique_ptr<WebThread> thread = Platform::Current()->CreateThread( + WebThreadCreationParams("WorkerThread")); PostCrossThreadTask(*thread->GetWebTaskRunner(), FROM_HERE, CrossThreadBind(&RunInThread)); thread.reset();
diff --git a/third_party/WebKit/Source/platform/memory_profiler/DEPS b/third_party/WebKit/Source/platform/memory_profiler/DEPS deleted file mode 100644 index 70be7bf..0000000 --- a/third_party/WebKit/Source/platform/memory_profiler/DEPS +++ /dev/null
@@ -1,4 +0,0 @@ -include_rules = [ - "+base", -] -
diff --git a/third_party/WebKit/Source/platform/memory_profiler/OWNERS b/third_party/WebKit/Source/platform/memory_profiler/OWNERS deleted file mode 100644 index 87c96616..0000000 --- a/third_party/WebKit/Source/platform/memory_profiler/OWNERS +++ /dev/null
@@ -1 +0,0 @@ -alph@chromium.org
diff --git a/third_party/WebKit/Source/platform/memory_profiler/SamplingNativeHeapProfiler.cpp b/third_party/WebKit/Source/platform/memory_profiler/SamplingNativeHeapProfiler.cpp deleted file mode 100644 index f3f3cb5..0000000 --- a/third_party/WebKit/Source/platform/memory_profiler/SamplingNativeHeapProfiler.cpp +++ /dev/null
@@ -1,331 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "platform/memory_profiler/SamplingNativeHeapProfiler.h" - -#include <cmath> - -#include "base/allocator/allocator_shim.h" -#include "base/allocator/features.h" -#include "base/atomicops.h" -#include "base/bits.h" -#include "base/debug/alias.h" -#include "base/debug/stack_trace.h" -#include "base/memory/singleton.h" -#include "base/rand_util.h" -#include "build/build_config.h" - -namespace blink { - -using base::allocator::AllocatorDispatch; -using base::subtle::Atomic32; -using base::subtle::AtomicWord; - -namespace { - -const unsigned kMagicSignature = 0x14690ca5; -const unsigned kDefaultAlignment = 16; -const unsigned kSkipAllocatorFrames = 4; - -Atomic32 g_running; -Atomic32 g_deterministic; -AtomicWord g_cumulative_counter = 0; -AtomicWord g_threshold; -AtomicWord g_sampling_interval = 128 * 1024; - -static void* AllocFn(const AllocatorDispatch* self, - size_t size, - void* context) { - SamplingNativeHeapProfiler::Sample sample; - if (LIKELY(!base::subtle::NoBarrier_Load(&g_running) || - !SamplingNativeHeapProfiler::CreateAllocSample(size, &sample))) { - return self->next->alloc_function(self->next, size, context); - } - void* address = - self->next->alloc_function(self->next, size + kDefaultAlignment, context); - return SamplingNativeHeapProfiler::GetInstance()->RecordAlloc( - sample, address, kDefaultAlignment, kSkipAllocatorFrames); -} - -static void* AllocZeroInitializedFn(const AllocatorDispatch* self, - size_t n, - size_t size, - void* context) { - SamplingNativeHeapProfiler::Sample sample; - if (LIKELY( - !base::subtle::NoBarrier_Load(&g_running) || - !SamplingNativeHeapProfiler::CreateAllocSample(n * size, &sample))) { - return self->next->alloc_zero_initialized_function(self->next, n, size, - context); - } - void* address = self->next->alloc_zero_initialized_function( - self->next, 1, n * size + kDefaultAlignment, context); - return SamplingNativeHeapProfiler::GetInstance()->RecordAlloc( - sample, address, kDefaultAlignment, kSkipAllocatorFrames); -} - -static void* AllocAlignedFn(const AllocatorDispatch* self, - size_t alignment, - size_t size, - void* context) { - SamplingNativeHeapProfiler::Sample sample; - if (LIKELY(!base::subtle::NoBarrier_Load(&g_running) || - !SamplingNativeHeapProfiler::CreateAllocSample(size, &sample))) { - return self->next->alloc_aligned_function(self->next, alignment, size, - context); - } - size_t offset = base::bits::Align(sizeof(kMagicSignature), alignment); - void* address = self->next->alloc_aligned_function(self->next, alignment, - size + offset, context); - return SamplingNativeHeapProfiler::GetInstance()->RecordAlloc( - sample, address, offset, kSkipAllocatorFrames); -} - -static void* ReallocFn(const AllocatorDispatch* self, - void* address, - size_t size, - void* context) { - // Note: size == 0 actually performs free. - SamplingNativeHeapProfiler::Sample sample; - bool will_sample = - base::subtle::NoBarrier_Load(&g_running) && - SamplingNativeHeapProfiler::CreateAllocSample(size, &sample); - char* client_address = reinterpret_cast<char*>(address); - if (UNLIKELY(address && - reinterpret_cast<unsigned*>(address)[-1] == kMagicSignature)) { - address = SamplingNativeHeapProfiler::GetInstance()->RecordFree(address); - } - intptr_t prev_offset = client_address - reinterpret_cast<char*>(address); - bool was_sampled = prev_offset; - if (LIKELY(!was_sampled && !will_sample)) - return self->next->realloc_function(self->next, address, size, context); - size_t size_to_allocate = will_sample ? size + kDefaultAlignment : size; - address = self->next->realloc_function(self->next, address, size_to_allocate, - context); - if (will_sample) { - return SamplingNativeHeapProfiler::GetInstance()->RecordAlloc( - sample, address, kDefaultAlignment, kSkipAllocatorFrames, - client_address && prev_offset != kDefaultAlignment); - } - DCHECK(was_sampled && !will_sample); - memmove(address, reinterpret_cast<char*>(address) + prev_offset, size); - return address; -} - -static void FreeFn(const AllocatorDispatch* self, - void* address, - void* context) { - if (UNLIKELY(address && - reinterpret_cast<unsigned*>(address)[-1] == kMagicSignature)) { - address = SamplingNativeHeapProfiler::GetInstance()->RecordFree(address); - } - self->next->free_function(self->next, address, context); -} - -static size_t GetSizeEstimateFn(const AllocatorDispatch* self, - void* address, - void* context) { - size_t ret = - self->next->get_size_estimate_function(self->next, address, context); - return ret; -} - -static unsigned BatchMallocFn(const AllocatorDispatch* self, - size_t size, - void** results, - unsigned num_requested, - void* context) { - CHECK(false) << "Not implemented."; - return 0; -} - -static void BatchFreeFn(const AllocatorDispatch* self, - void** to_be_freed, - unsigned num_to_be_freed, - void* context) { - CHECK(false) << "Not implemented."; -} - -static void FreeDefiniteSizeFn(const AllocatorDispatch* self, - void* ptr, - size_t size, - void* context) { - CHECK(false) << "Not implemented."; -} - -AllocatorDispatch g_allocator_dispatch = {&AllocFn, - &AllocZeroInitializedFn, - &AllocAlignedFn, - &ReallocFn, - &FreeFn, - &GetSizeEstimateFn, - &BatchMallocFn, - &BatchFreeFn, - &FreeDefiniteSizeFn, - nullptr}; - -} // namespace - -// static -void SamplingNativeHeapProfiler::InstallAllocatorHooksOnce() { - static bool hook_installed = InstallAllocatorHooks(); - base::debug::Alias(&hook_installed); -} - -// static -bool SamplingNativeHeapProfiler::InstallAllocatorHooks() { -#if BUILDFLAG(USE_ALLOCATOR_SHIM) - base::allocator::InsertAllocatorDispatch(&g_allocator_dispatch); -#else - base::debug::Alias(&g_allocator_dispatch); - CHECK(false) - << "Can't enable native sampling heap profiler without the shim."; -#endif // BUILDFLAG(USE_ALLOCATOR_SHIM) - return true; -} - -void SamplingNativeHeapProfiler::Start() { - InstallAllocatorHooksOnce(); - base::subtle::Release_Store(&g_threshold, g_sampling_interval); - base::subtle::Release_Store(&g_running, true); -} - -void SamplingNativeHeapProfiler::Stop() { - base::subtle::Release_Store(&g_running, false); -} - -void SamplingNativeHeapProfiler::SetSamplingInterval( - unsigned sampling_interval) { - // TODO(alph): Update the threshold. Make sure not to leave it in a state - // when the threshold is already crossed. - base::subtle::Release_Store(&g_sampling_interval, sampling_interval); -} - -// static -intptr_t SamplingNativeHeapProfiler::GetNextSampleInterval(uint64_t interval) { - if (base::subtle::NoBarrier_Load(&g_deterministic)) - return static_cast<intptr_t>(interval); - // We sample with a Poisson process, with constant average sampling - // interval. This follows the exponential probability distribution with - // parameter λ = 1/interval where |interval| is the average number of bytes - // between samples. - // Let u be a uniformly distributed random number between 0 and 1, then - // next_sample = -ln(u) / λ - double uniform = base::RandDouble(); - double value = -log(uniform) * interval; - intptr_t min_value = sizeof(intptr_t); - // We limit the upper bound of a sample interval to make sure we don't have - // huge gaps in the sampling stream. Probability of the upper bound gets hit - // is exp(-20) ~ 2e-9, so it should not skew the distibution. - intptr_t max_value = interval * 20; - if (UNLIKELY(value < min_value)) - return min_value; - if (UNLIKELY(value > max_value)) - return max_value; - return static_cast<intptr_t>(value); -} - -// static -bool SamplingNativeHeapProfiler::CreateAllocSample(size_t size, - Sample* sample) { - // Lock-free algorithm that adds the allocation size to the cumulative - // counter. When the counter reaches threshold, it picks a single thread - // that will record the sample and reset the counter. - // The thread that records the sample returns true, others return false. - AtomicWord threshold = base::subtle::NoBarrier_Load(&g_threshold); - AtomicWord accumulated = base::subtle::NoBarrier_AtomicIncrement( - &g_cumulative_counter, static_cast<AtomicWord>(size)); - if (LIKELY(accumulated < threshold)) - return false; - - // Return if it was another thread that in fact crossed the threshold. - // That other thread is responsible for recording the sample. - if (UNLIKELY(accumulated >= threshold + static_cast<AtomicWord>(size))) - return false; - - intptr_t next_interval = - GetNextSampleInterval(base::subtle::NoBarrier_Load(&g_sampling_interval)); - base::subtle::Release_Store(&g_threshold, next_interval); - accumulated = - base::subtle::NoBarrier_AtomicExchange(&g_cumulative_counter, 0); - - DCHECK_NE(size, 0u); - sample->size = size; - sample->count = std::max<size_t>(1, (accumulated + size / 2) / size); - return true; -} - -void SamplingNativeHeapProfiler::RecordStackTrace(Sample* sample, - unsigned skip_frames) { - // TODO(alph): Consider using debug::TraceStackFramePointers. It should be - // somewhat faster than base::debug::StackTrace. - base::debug::StackTrace trace; - size_t count; - void* const* addresses = const_cast<void* const*>(trace.Addresses(&count)); - // Skip SamplingNativeHeapProfiler frames. - sample->stack.insert( - sample->stack.end(), &addresses[skip_frames], - &addresses[std::max(count, static_cast<size_t>(skip_frames))]); -} - -void* SamplingNativeHeapProfiler::RecordAlloc(Sample& sample, - void* address, - unsigned offset, - unsigned skip_frames, - bool preserve_data) { - // TODO(alph): It's better to use a recursive mutex and move the check - // inside the critical section. This way we won't skip the sample generation - // on one thread if another thread is recording a sample. - if (entered_.Get()) - return address; - base::AutoLock lock(mutex_); - entered_.Set(true); - sample.offset = offset; - void* client_address = reinterpret_cast<char*>(address) + offset; - if (preserve_data) - memmove(client_address, address, sample.size); - RecordStackTrace(&sample, skip_frames); - samples_.insert(std::make_pair(client_address, sample)); - if (offset) - reinterpret_cast<unsigned*>(client_address)[-1] = kMagicSignature; - entered_.Set(false); - return client_address; -} - -void* SamplingNativeHeapProfiler::RecordFree(void* address) { - base::AutoLock lock(mutex_); - auto& samples = GetInstance()->samples_; - auto it = samples.find(address); - if (it == samples.end()) - return address; - void* address_to_free = reinterpret_cast<char*>(address) - it->second.offset; - samples.erase(it); - if (it->second.offset) - reinterpret_cast<unsigned*>(address)[-1] = 0; - return address_to_free; -} - -// static -SamplingNativeHeapProfiler* SamplingNativeHeapProfiler::GetInstance() { - return base::Singleton<SamplingNativeHeapProfiler>::get(); -} - -// static -void SamplingNativeHeapProfiler::SuppressRandomnessForTest() { - base::subtle::Release_Store(&g_deterministic, true); -} - -std::vector<SamplingNativeHeapProfiler::Sample> -SamplingNativeHeapProfiler::GetSamples() { - base::AutoLock lock(mutex_); - CHECK(!entered_.Get()); - entered_.Set(true); - std::vector<Sample> samples; - for (auto it = samples_.begin(); it != samples_.end(); ++it) - samples.push_back(it->second); - entered_.Set(false); - return samples; -} - -} // namespace blink
diff --git a/third_party/WebKit/Source/platform/memory_profiler/SamplingNativeHeapProfiler.h b/third_party/WebKit/Source/platform/memory_profiler/SamplingNativeHeapProfiler.h deleted file mode 100644 index 21ad80e..0000000 --- a/third_party/WebKit/Source/platform/memory_profiler/SamplingNativeHeapProfiler.h +++ /dev/null
@@ -1,70 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef SamplingNativeHeapProfiler_h -#define SamplingNativeHeapProfiler_h - -#include <unordered_map> -#include <vector> - -#include "base/atomicops.h" -#include "base/macros.h" -#include "base/synchronization/lock.h" -#include "base/threading/thread_local.h" -#include "platform/PlatformExport.h" - -namespace base { -template <typename T> -struct DefaultSingletonTraits; -} - -namespace blink { - -class PLATFORM_EXPORT SamplingNativeHeapProfiler { - public: - struct Sample { - size_t size; - size_t count; - unsigned offset; - std::vector<void*> stack; - }; - - SamplingNativeHeapProfiler() = default; - - void Start(); - void Stop(); - void SetSamplingInterval(unsigned sampling_interval); - void SuppressRandomnessForTest(); - - std::vector<Sample> GetSamples(); - - static SamplingNativeHeapProfiler* GetInstance(); - - static inline bool CreateAllocSample(size_t, Sample*); - void* RecordAlloc(Sample&, - void* address, - unsigned offset, - unsigned skip_frames, - bool preserve_data = false); - void* RecordFree(void* address); - - private: - static void InstallAllocatorHooksOnce(); - static bool InstallAllocatorHooks(); - static intptr_t GetNextSampleInterval(uint64_t base_interval); - - void RecordStackTrace(Sample*, unsigned skip_frames); - - base::ThreadLocalBoolean entered_; - base::Lock mutex_; - std::unordered_map<void*, Sample> samples_; - - friend struct base::DefaultSingletonTraits<SamplingNativeHeapProfiler>; - - DISALLOW_COPY_AND_ASSIGN(SamplingNativeHeapProfiler); -}; - -} // namespace blink - -#endif // SamplingNativeHeapProfiler_h
diff --git a/third_party/WebKit/Source/platform/mhtml/MHTMLArchive.cpp b/third_party/WebKit/Source/platform/mhtml/MHTMLArchive.cpp index 16a7882..889d740 100644 --- a/third_party/WebKit/Source/platform/mhtml/MHTMLArchive.cpp +++ b/third_party/WebKit/Source/platform/mhtml/MHTMLArchive.cpp
@@ -51,7 +51,6 @@ namespace { const size_t kMaximumLineLength = 76; -const char kCrlfLineEnding[] = "\r\n"; const char kRFC2047EncodingPrefix[] = "=?utf-8?Q?"; const size_t kRFC2047EncodingPrefixLength = 10; @@ -86,7 +85,7 @@ void DidFinishLine(bool last_line, Vector<char>& out) override { if (!last_line) { out.push_back('='); - out.Append(kCrlfLineEnding, strlen(kCrlfLineEnding)); + out.Append("\r\n", 2); } } }; @@ -115,7 +114,7 @@ void DidFinishLine(bool last_line, Vector<char>& out) override { out.Append(kRFC2047EncodingSuffix, kRFC2047EncodingSuffixLength); if (!last_line) { - out.Append(kCrlfLineEnding, strlen(kCrlfLineEnding)); + out.Append("\r\n", 2); out.push_back(' '); } }
diff --git a/third_party/WebKit/Source/platform/runtime_enabled_features.json5 b/third_party/WebKit/Source/platform/runtime_enabled_features.json5 index e25617ce..c5ea098 100644 --- a/third_party/WebKit/Source/platform/runtime_enabled_features.json5 +++ b/third_party/WebKit/Source/platform/runtime_enabled_features.json5
@@ -502,6 +502,11 @@ status: "test", }, { + name: "ImplicitRootScroller", + status: "experimental", + settable_from_internals: true, + }, + { name: "IncrementalShadowDOM", }, {
diff --git a/third_party/WebKit/Source/platform/scheduler/BUILD.gn b/third_party/WebKit/Source/platform/scheduler/BUILD.gn index 6b0dcb8..eac970ce 100644 --- a/third_party/WebKit/Source/platform/scheduler/BUILD.gn +++ b/third_party/WebKit/Source/platform/scheduler/BUILD.gn
@@ -52,6 +52,8 @@ "child/metrics_helper.h", "child/pollable_thread_safe_flag.cc", "child/pollable_thread_safe_flag.h", + "child/process_state.cc", + "child/process_state.h", "child/scheduler_helper.cc", "child/scheduler_helper.h", "child/single_thread_idle_task_runner.cc",
diff --git a/third_party/WebKit/Source/platform/scheduler/child/metrics_helper.cc b/third_party/WebKit/Source/platform/scheduler/child/metrics_helper.cc index 083d41d..ce59e62 100644 --- a/third_party/WebKit/Source/platform/scheduler/child/metrics_helper.cc +++ b/third_party/WebKit/Source/platform/scheduler/child/metrics_helper.cc
@@ -4,6 +4,8 @@ #include "platform/scheduler/child/metrics_helper.h" +#include "platform/scheduler/child/process_state.h" + namespace blink { namespace scheduler { @@ -22,7 +24,15 @@ thread_task_duration_reporter_( "RendererScheduler.TaskDurationPerThreadType"), thread_task_cpu_duration_reporter_( - "RendererScheduler.TaskCPUDurationPerThreadType") {} + "RendererScheduler.TaskCPUDurationPerThreadType"), + foreground_thread_task_duration_reporter_( + "RendererScheduler.TaskDurationPerThreadType.Foreground"), + foreground_thread_task_cpu_duration_reporter_( + "RendererScheduler.TaskCPUDurationPerThreadType.Foreground"), + background_thread_task_duration_reporter_( + "RendererScheduler.TaskDurationPerThreadType.Background"), + background_thread_task_cpu_duration_reporter_( + "RendererScheduler.TaskCPUDurationPerThreadType.Background") {} MetricsHelper::~MetricsHelper() {} @@ -43,11 +53,30 @@ base::TimeTicks start_time, base::TimeTicks end_time, base::Optional<base::TimeDelta> thread_time) { - thread_task_duration_reporter_.RecordTask(thread_type_, - end_time - start_time); - if (thread_time) { - thread_task_cpu_duration_reporter_.RecordTask(thread_type_, - thread_time.value()); + base::TimeDelta wall_time = end_time - start_time; + + thread_task_duration_reporter_.RecordTask(thread_type_, wall_time); + + bool backgrounded = internal::ProcessState::Get()->is_process_backgrounded; + + if (backgrounded) { + background_thread_task_duration_reporter_.RecordTask(thread_type_, + wall_time); + } else { + foreground_thread_task_duration_reporter_.RecordTask(thread_type_, + wall_time); + } + + if (!thread_time) + return; + thread_task_cpu_duration_reporter_.RecordTask(thread_type_, + thread_time.value()); + if (backgrounded) { + background_thread_task_cpu_duration_reporter_.RecordTask( + thread_type_, thread_time.value()); + } else { + foreground_thread_task_cpu_duration_reporter_.RecordTask( + thread_type_, thread_time.value()); } }
diff --git a/third_party/WebKit/Source/platform/scheduler/child/metrics_helper.h b/third_party/WebKit/Source/platform/scheduler/child/metrics_helper.h index 9877114e..15c9b8b4 100644 --- a/third_party/WebKit/Source/platform/scheduler/child/metrics_helper.h +++ b/third_party/WebKit/Source/platform/scheduler/child/metrics_helper.h
@@ -51,6 +51,14 @@ TaskDurationMetricReporter<ThreadType> thread_task_duration_reporter_; TaskDurationMetricReporter<ThreadType> thread_task_cpu_duration_reporter_; + TaskDurationMetricReporter<ThreadType> + foreground_thread_task_duration_reporter_; + TaskDurationMetricReporter<ThreadType> + foreground_thread_task_cpu_duration_reporter_; + TaskDurationMetricReporter<ThreadType> + background_thread_task_duration_reporter_; + TaskDurationMetricReporter<ThreadType> + background_thread_task_cpu_duration_reporter_; DISALLOW_COPY_AND_ASSIGN(MetricsHelper); };
diff --git a/third_party/WebKit/Source/platform/scheduler/child/process_state.cc b/third_party/WebKit/Source/platform/scheduler/child/process_state.cc new file mode 100644 index 0000000..85b9e3e --- /dev/null +++ b/third_party/WebKit/Source/platform/scheduler/child/process_state.cc
@@ -0,0 +1,26 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "platform/scheduler/child/process_state.h" + +#include "base/lazy_instance.h" + +namespace blink { +namespace scheduler { +namespace internal { + +namespace { + +base::LazyInstance<ProcessState>::Leaky g_process_state; + +} // namespace + +// static +ProcessState* ProcessState::Get() { + return g_process_state.Pointer(); +} + +} // namespace internal +} // namespace scheduler +} // namespace blink
diff --git a/third_party/WebKit/Source/platform/scheduler/child/process_state.h b/third_party/WebKit/Source/platform/scheduler/child/process_state.h new file mode 100644 index 0000000..8c34534 --- /dev/null +++ b/third_party/WebKit/Source/platform/scheduler/child/process_state.h
@@ -0,0 +1,22 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <atomic> + +namespace blink { +namespace scheduler { +namespace internal { + +// Helper lock-free struct to share main state of the process between threads +// for recording methods. +// This class should not be used for synchronization between threads. +struct ProcessState { + static ProcessState* Get(); + + std::atomic_bool is_process_backgrounded; +}; + +} // namespace internal +} // namespace scheduler +} // namespace blink
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc index b5746de..69b2767 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc
@@ -25,6 +25,7 @@ #include "platform/scheduler/base/task_queue_impl.h" #include "platform/scheduler/base/task_queue_selector.h" #include "platform/scheduler/base/virtual_time_domain.h" +#include "platform/scheduler/child/process_state.h" #include "platform/scheduler/renderer/auto_advancing_virtual_time_domain.h" #include "platform/scheduler/renderer/task_queue_throttler.h" #include "platform/scheduler/renderer/web_view_scheduler_impl.h" @@ -271,6 +272,9 @@ } delay_for_background_tab_stopping_ = base::TimeDelta::FromMilliseconds( delay_for_background_tab_stopping_millis); + + internal::ProcessState::Get()->is_process_backgrounded = + main_thread_only().renderer_backgrounded; } RendererSchedulerImpl::~RendererSchedulerImpl() { @@ -880,6 +884,7 @@ } main_thread_only().renderer_backgrounded = backgrounded; + internal::ProcessState::Get()->is_process_backgrounded = backgrounded; main_thread_only().background_status_changed_at = tick_clock()->NowTicks(); seqlock_queueing_time_estimator_.seqlock.WriteBegin();
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollCustomization.cpp b/third_party/WebKit/Source/platform/scroll/ScrollCustomization.cpp new file mode 100644 index 0000000..40d7d5a --- /dev/null +++ b/third_party/WebKit/Source/platform/scroll/ScrollCustomization.cpp
@@ -0,0 +1,35 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "platform/scroll/ScrollCustomization.h" + +namespace blink { +namespace ScrollCustomization { + +ScrollDirection GetScrollDirectionFromDeltas(double delta_x, double delta_y) { + // TODO(ekaramad, tdresser): Find out the right value for kEpsilon here (see + // https://crbug.com/510550). + const double kEpsilon = 0.1f; + + ScrollDirection direction = kScrollDirectionNone; + if (delta_x > kEpsilon) + direction |= kScrollDirectionPanRight; + if (delta_x < -kEpsilon) + direction |= kScrollDirectionPanLeft; + if (delta_y > kEpsilon) + direction |= kScrollDirectionPanDown; + if (delta_y < -kEpsilon) + direction |= kScrollDirectionPanUp; + + if (!direction) { + // TODO(ekaramad, sahel): Remove this and perhaps replace with a DCHECK when + // issue https://crbug.com/728214 is fixed. + return kScrollDirectionAuto; + } + + return direction; +} + +} // namespace ScrollCustomization +} // namespace blink
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollCustomization.h b/third_party/WebKit/Source/platform/scroll/ScrollCustomization.h new file mode 100644 index 0000000..54f05b6 --- /dev/null +++ b/third_party/WebKit/Source/platform/scroll/ScrollCustomization.h
@@ -0,0 +1,33 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ScrollCustomization_h +#define ScrollCustomization_h + +#include <stdint.h> + +#include "platform/PlatformExport.h" + +namespace blink { +namespace ScrollCustomization { +using ScrollDirection = uint8_t; + +constexpr ScrollDirection kScrollDirectionNone = 0; +constexpr ScrollDirection kScrollDirectionPanLeft = 1 << 0; +constexpr ScrollDirection kScrollDirectionPanRight = 1 << 1; +constexpr ScrollDirection kScrollDirectionPanX = + kScrollDirectionPanLeft | kScrollDirectionPanRight; +constexpr ScrollDirection kScrollDirectionPanUp = 1 << 2; +constexpr ScrollDirection kScrollDirectionPanDown = 1 << 3; +constexpr ScrollDirection kScrollDirectionPanY = + kScrollDirectionPanUp | kScrollDirectionPanDown; +constexpr ScrollDirection kScrollDirectionAuto = + kScrollDirectionPanX | kScrollDirectionPanY; + +PLATFORM_EXPORT ScrollDirection GetScrollDirectionFromDeltas(double delta_x, + double delta_y); +} // namespace ScrollCustomization +} // namespace blink + +#endif // ScrollCustomization_h
diff --git a/third_party/WebKit/Source/platform/testing/ImageDecodeBench.cpp b/third_party/WebKit/Source/platform/testing/ImageDecodeBench.cpp index 361aff4..2fb287b 100644 --- a/third_party/WebKit/Source/platform/testing/ImageDecodeBench.cpp +++ b/third_party/WebKit/Source/platform/testing/ImageDecodeBench.cpp
@@ -14,8 +14,8 @@ // the decoded image frame md5 and output that value. // // TODO(noel): Consider integrating this tool in Chrome telemetry for realz, -// using the image corpii used to assess Blink image decode performance. Refer -// to http://crbug.com/398235#c103 and http://crbug.com/258324#c5 +// using the image corpora used to assess Blink image decode performance. See +// http://crbug.com/398235#c103 and http://crbug.com/258324#c5 #include <fstream>
diff --git a/third_party/WebKit/Source/platform/testing/TestingPlatformSupportWithMockScheduler.cpp b/third_party/WebKit/Source/platform/testing/TestingPlatformSupportWithMockScheduler.cpp index 3d0410c..f472c3d 100644 --- a/third_party/WebKit/Source/platform/testing/TestingPlatformSupportWithMockScheduler.cpp +++ b/third_party/WebKit/Source/platform/testing/TestingPlatformSupportWithMockScheduler.cpp
@@ -61,9 +61,10 @@ } std::unique_ptr<WebThread> -TestingPlatformSupportWithMockScheduler::CreateThread(const char* name) { +TestingPlatformSupportWithMockScheduler::CreateThread( + const WebThreadCreationParams& params) { std::unique_ptr<scheduler::WebThreadBase> thread = - scheduler::WebThreadBase::CreateWorkerThread(name, + scheduler::WebThreadBase::CreateWorkerThread(params.name, base::Thread::Options()); thread->Init(); WaitableEvent event;
diff --git a/third_party/WebKit/Source/platform/testing/TestingPlatformSupportWithMockScheduler.h b/third_party/WebKit/Source/platform/testing/TestingPlatformSupportWithMockScheduler.h index bebebb1..740bcf4 100644 --- a/third_party/WebKit/Source/platform/testing/TestingPlatformSupportWithMockScheduler.h +++ b/third_party/WebKit/Source/platform/testing/TestingPlatformSupportWithMockScheduler.h
@@ -32,7 +32,8 @@ ~TestingPlatformSupportWithMockScheduler() override; // Platform: - std::unique_ptr<WebThread> CreateThread(const char* name) override; + std::unique_ptr<WebThread> CreateThread( + const WebThreadCreationParams&) override; WebThread* CurrentThread() override; // Runs a single task.
diff --git a/third_party/WebKit/Source/platform/text/QuotedPrintable.cpp b/third_party/WebKit/Source/platform/text/QuotedPrintable.cpp index 9f80140..9a7e7d50 100644 --- a/third_party/WebKit/Source/platform/text/QuotedPrintable.cpp +++ b/third_party/WebKit/Source/platform/text/QuotedPrintable.cpp
@@ -34,8 +34,6 @@ namespace blink { -static const char kCrlfLineEnding[] = "\r\n"; - static size_t LengthOfLineEndingAtIndex(const char* input, size_t input_length, size_t index) { @@ -84,7 +82,7 @@ size_t length_of_line_ending = LengthOfLineEndingAtIndex(input, input_length, i); if (length_of_line_ending) { - out.Append(kCrlfLineEnding, strlen(kCrlfLineEnding)); + out.Append("\r\n", 2); current_line_length = 0; i += (length_of_line_ending - 1); // -1 because we'll ++ in the for() above.
diff --git a/third_party/WebKit/common/service_worker/service_worker_object.mojom b/third_party/WebKit/common/service_worker/service_worker_object.mojom index c16be3e..cf1c05f 100644 --- a/third_party/WebKit/common/service_worker/service_worker_object.mojom +++ b/third_party/WebKit/common/service_worker/service_worker_object.mojom
@@ -26,4 +26,20 @@ // ServiceWorker#scriptURL url.mojom.Url url; + + // This object's host in the browser process. + associated ServiceWorkerObjectHost? host_ptr_info; +}; + +// The browser-side host of one ServiceWorker JavaScript object. The renderer +// uses this interface to ask the browser process to do operations needed to +// implement ServiceWorker methods. +interface ServiceWorkerObjectHost { + // TODO(leonhsl): Implement all methods. + // Replace ServiceWorkerHostMsg_PostMessageToWorker. + // PostMessage(string message, url.mojom.Origin source_origin, + // array<handle<message_pipe>> sent_message_ports); + + // Replace ServiceWorkerHostMsg_TerminateWorker. + // Terminate(); };
diff --git a/third_party/WebKit/public/blink_typemaps.gni b/third_party/WebKit/public/blink_typemaps.gni index b2be8d2..bd89122f 100644 --- a/third_party/WebKit/public/blink_typemaps.gni +++ b/third_party/WebKit/public/blink_typemaps.gni
@@ -12,7 +12,6 @@ "//services/viz/public/cpp/compositing/returned_resource.typemap", "//services/viz/public/cpp/compositing/surface_id.typemap", "//services/viz/public/cpp/compositing/surface_info.typemap", - "//services/viz/public/cpp/compositing/surface_sequence.typemap", "//skia/public/interfaces/skbitmap_for_blink.typemap", "//ui/gfx/mojo/gpu_fence_handle_for_blink.typemap", ]
diff --git a/third_party/WebKit/public/platform/Platform.h b/third_party/WebKit/public/platform/Platform.h index 0da86d4..7d59e4f 100644 --- a/third_party/WebKit/public/platform/Platform.h +++ b/third_party/WebKit/public/platform/Platform.h
@@ -135,6 +135,7 @@ class WebTaskRunner; class WebThemeEngine; class WebThread; +struct WebThreadCreationParams; class WebTrialTokenValidator; class WebURLLoaderMockFactory; class WebURLResponse; @@ -405,7 +406,8 @@ // Threads ------------------------------------------------------- // Creates an embedder-defined thread. - virtual std::unique_ptr<WebThread> CreateThread(const char* name); + virtual std::unique_ptr<WebThread> CreateThread( + const WebThreadCreationParams&); // Creates a WebAudio-specific thread with the elevated priority. Do NOT use // for any other purpose.
diff --git a/third_party/WebKit/public/platform/WebThread.h b/third_party/WebKit/public/platform/WebThread.h index c983c13a..844e4147 100644 --- a/third_party/WebKit/public/platform/WebThread.h +++ b/third_party/WebKit/public/platform/WebThread.h
@@ -46,6 +46,12 @@ // Always an integer value. typedef uintptr_t PlatformThreadId; +struct BLINK_PLATFORM_EXPORT WebThreadCreationParams { + explicit WebThreadCreationParams(const char* name); + + const char* name; +}; + // Provides an interface to an embedder-defined thread implementation. // // Deleting the thread blocks until all pending, non-delayed tasks have been
diff --git a/third_party/WebKit/public/platform/modules/offscreencanvas/offscreen_canvas_surface.mojom b/third_party/WebKit/public/platform/modules/offscreencanvas/offscreen_canvas_surface.mojom index 68f944ee..6494220 100644 --- a/third_party/WebKit/public/platform/modules/offscreencanvas/offscreen_canvas_surface.mojom +++ b/third_party/WebKit/public/platform/modules/offscreencanvas/offscreen_canvas_surface.mojom
@@ -8,12 +8,11 @@ import "services/viz/public/interfaces/compositing/frame_sink_id.mojom"; import "services/viz/public/interfaces/compositing/surface_id.mojom"; import "services/viz/public/interfaces/compositing/surface_info.mojom"; -import "services/viz/public/interfaces/compositing/surface_sequence.mojom"; -interface OffscreenCanvasSurface { - Require(viz.mojom.SurfaceId surface_id, viz.mojom.SurfaceSequence sequence); - Satisfy(viz.mojom.SurfaceSequence sequence); -}; +// The renderer main thread can shutdown the offscreen canvas by closing this +// interface. +// TODO(kylechar): Refactor so this empty interface isn't needed. +interface OffscreenCanvasSurface {}; interface OffscreenCanvasSurfaceClient { OnFirstSurfaceActivation(viz.mojom.SurfaceInfo surface_info);
diff --git a/third_party/webrtc_overrides/runtime_enabled_features.cc b/third_party/webrtc_overrides/runtime_enabled_features.cc index 5aef651..bbb5deba 100644 --- a/third_party/webrtc_overrides/runtime_enabled_features.cc +++ b/third_party/webrtc_overrides/runtime_enabled_features.cc
@@ -1,23 +1,22 @@ // Copyright 2018 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// +// Define webrtc::runtime_features::IsFeatureEnabled to provide webrtc with a +// chromium runtime flags access. #include "base/feature_list.h" #include "third_party/webrtc/system_wrappers/include/runtime_enabled_features.h" -// Define webrtc::runtime_features::IsFeatureEnabled to provide webrtc with a -// chromium runtime flags access. - namespace webrtc { namespace runtime_enabled_features { - const base::Feature kWebRtcDualStreamMode{"WebRTC-DualStreamMode", base::FEATURE_DISABLED_BY_DEFAULT}; bool IsFeatureEnabled(std::string feature_name) { - if (feature_name == "WebRtcDualStreamMode") + if (feature_name == kDualStreamModeFeatureName) return base::FeatureList::IsEnabled(kWebRtcDualStreamMode); return false; }
diff --git a/tools/clang/scripts/run_tool.py b/tools/clang/scripts/run_tool.py index 842eba0..ef887e8 100755 --- a/tools/clang/scripts/run_tool.py +++ b/tools/clang/scripts/run_tool.py
@@ -262,7 +262,7 @@ nargs='*', help='optional paths to filter what files the tool is run on') parser.add_argument( - '--tool-args', nargs='*', + '--tool-arg', nargs='?', action='append', help='optional arguments passed to the tool') parser.add_argument( '--tool-path', nargs='?', @@ -304,7 +304,7 @@ shard_number, shard_count, len(source_filenames), total_length) dispatcher = _CompilerDispatcher(os.path.join(tool_path, args.tool), - args.tool_args, + args.tool_arg, args.p, source_filenames) dispatcher.Run()
diff --git a/tools/cygprofile/orderfile_generator_backend.py b/tools/cygprofile/orderfile_generator_backend.py index 45db9aae..147a067 100755 --- a/tools/cygprofile/orderfile_generator_backend.py +++ b/tools/cygprofile/orderfile_generator_backend.py
@@ -541,6 +541,9 @@ assert os.path.exists(self._compiler.lib_chrome_so) offsets = process_profiles.GetReachedOffsetsFromDumpFiles( files, self._compiler.lib_chrome_so) + if not offsets: + raise Exception('No profiler offsets found in {}'.format( + '\n'.join(files))) with open(self._MERGED_CYGLOG_FILENAME, 'w') as f: f.write('\n'.join(map(str, offsets))) else: @@ -548,7 +551,7 @@ self._step_recorder.RunCommand([self._MERGE_TRACES_SCRIPT] + files, constants.DIR_SOURCE_ROOT, stdout=merged_cyglog) - except CommandError: + except Exception: for f in files: self._SaveForDebugging(f) raise
diff --git a/tools/cygprofile/process_profiles.py b/tools/cygprofile/process_profiles.py index 12945cd..6d89eafa 100755 --- a/tools/cygprofile/process_profiles.py +++ b/tools/cygprofile/process_profiles.py
@@ -18,6 +18,17 @@ import symbol_extractor +def _Median(items): + if not items: + return None + sorted_items = sorted(items) + if len(sorted_items) & 1: + return sorted_items[len(sorted_items)/2] + else: + return (sorted_items[len(sorted_items)/2 - 1] + + sorted_items[len(sorted_items)/2]) / 2 + + class SymbolOffsetProcessor(object): """Utility for processing symbols in binaries. @@ -167,44 +178,145 @@ return offset_to_symbol_info -def _SortedFilenames(filenames): - """Returns filenames in ascending timestamp order. +class ProfileManager(object): + """Manipulates sets of profiles. - Args: - filenames: (str iterable) List of filenames, matching. *-TIMESTAMP.*. + The manager supports only lightweight-style profiles (see + lightweight_cygprofile.cc) and not the older cygprofile offset lists. - Returns: - [str] Ordered by ascending timestamp. + A "profile set" refers to a set of data from an instrumented version of chrome + that will be processed together, usually to produce a single orderfile. A + "run" refers to a session of chrome, visiting several pages and thus + comprising a browser process and at least one renderer process. A "dump" + refers to the instrumentation in chrome writing out offsets of instrumented + functions. There may be several dumps per run, for example one describing + chrome startup and a second describing steady-state page interaction. Each + process in a run produces one file per dump. + + These dump files have a timestamp of the dump time. Each process produces its + own timestamp, but the dumps from each process occur very near in time to each + other (< 1 second). If there are several dumps per run, each set of dumps is + marked by a "phase" in the filename which is consistent across processes. For + example the dump for the startup could be phase 0 and then the steady-state + would be labeled phase 1. + + We assume the files are named like *-TIMESTAMP.SUFFIX_PHASE, where TIMESTAMP + is in nanoseconds, SUFFIX is string without dashes, PHASE is an integer + numbering the phases as 0, 1, 2..., and the only dot is the one between + TIMESTAMP and SUFFIX. Note that the current dump filename also includes a + process id which is currently unused. + + This manager supports several configurations of dumps. + + * A single dump from a single run. These files are merged together to produce + a single dump without regard for browser versus renderer methods. + + * Several phases of dumps from a single run. Files are grouped by phase as + described above. + + * Several phases of dumps from multiple runs from a set of telemetry + benchmarks. The timestamp is used to distinguish each run because each + benchmark takes < 10 seconds to run but there are > 50 seconds of setup + time. This files can be grouped into run sets that are within 30 seconds of + each other. Each run set is then grouped into phases as before. """ - filename_timestamp = [] - for filename in filenames: - dash_index = filename.rindex('-') - dot_index = filename.rindex('.') - timestamp = int(filename[dash_index+1:dot_index]) - filename_timestamp.append((filename, timestamp)) - filename_timestamp.sort(key=operator.itemgetter(1)) - return [x[0] for x in filename_timestamp] + class _RunGroup(object): + RUN_GROUP_THRESHOLD_NS = 30e9 -def MergeDumps(filenames): - """Merges several dumps. + def __init__(self): + self._filenames = [] - Args: - filenames: (str iterable) List of dump filenames. + def Filenames(self, phase=None): + if phase is None: + return self._filenames + return [f for f in self._filenames + if ProfileManager._Phase(f) == phase] - Returns: - [int] Ordered list of reached offsets. Each offset only appears - once in the output, in the order of the first dump that contains it. - """ - dumps = [[int(x.strip()) for x in open(filename)] for filename in filenames] - seen_offsets = set() - result = [] - for dump in dumps: - for offset in dump: - if offset not in seen_offsets: - result.append(offset) - seen_offsets.add(offset) - return result + def Add(self, filename): + self._filenames.append(filename) + + def IsCloseTo(self, filename): + run_group_ts = _Median( + [ProfileManager._Timestamp(f) for f in self._filenames]) + return abs(ProfileManager._Timestamp(filename) - + run_group_ts) < self.RUN_GROUP_THRESHOLD_NS + + def __init__(self, filenames): + """Initialize a ProfileManager. + + Args: + filenames ([str]): List of filenames describe the profile set. + """ + self._filenames = sorted(filenames, key=self._Timestamp) + self._run_groups = None + + def GetMergedOffsets(self, phase=None): + """Merges files, as if from a single dump. + + Args: + phase (int, optional) If present, restrict to this phase. + + Returns: + [int] Ordered list of reached offsets. Each offset only appears + once in the output, in the order of the first dump that contains it. + """ + if phase is None: + return self._GetOffsetsForGroup(self._filenames) + return self._GetOffsetsForGroup(f for f in self._filenames + if self._Phase(f) == phase) + + def GetRunGroupOffsets(self, phase=None): + """Merges files from each run group and returns offset list for each. + + Args: + phase (int, optional) If present, restrict to this phase. + + Returns: + [ [int] ] List of offsets lists, each as from GetMergedOffsets. + """ + return [self._GetOffsetsForGroup(g) for g in self._GetRunGroups(phase)] + + def _GetOffsetsForGroup(self, filenames): + dumps = [self._ReadOffsets(f) for f in filenames] + seen_offsets = set() + result = [] + for dump in dumps: + for offset in dump: + if offset not in seen_offsets: + result.append(offset) + seen_offsets.add(offset) + return result + + def _GetRunGroups(self, phase=None): + if self._run_groups is None: + self._ComputeRunGroups() + return [g.Filenames(phase) for g in self._run_groups] + + @classmethod + def _Timestamp(cls, filename): + dash_index = filename.rindex('-') + dot_index = filename.rindex('.') + return int(filename[dash_index+1:dot_index]) + + @classmethod + def _Phase(cls, filename): + return int(filename.split('_')[-1]) + + def _ReadOffsets(self, filename): + return [int(x.strip()) for x in open(filename)] + + def _ComputeRunGroups(self): + self._run_groups = [] + for f in self._filenames: + for g in self._run_groups: + if g.IsCloseTo(f): + g.Add(f) + break + else: + g = self._RunGroup() + g.Add(f) + self._run_groups.append(g) def GetReachedOffsetsFromDumpFiles(dump_filenames, library_filename): @@ -219,7 +331,10 @@ given by the deduplicated order of offsets found in dump_filenames (see also MergeDumps(). """ - dump = MergeDumps(dump_filenames) + dump = ProfileManager(dump_filenames).GetMergedOffsets() + if not dump: + logging.error('Empty dump, cannot continue: %s', '\n'.join(dump_filenames)) + return None logging.info('Reached offsets = %d', len(dump)) processor = SymbolOffsetProcessor(library_filename) return processor.GetReachedOffsetsFromDump(dump) @@ -251,7 +366,9 @@ args = parser.parse_args() logging.info('Merging dumps') dump_files = args.dumps.split(',') - dumps = MergeDumps(_SortedFilenames(dump_files)) + profile_manager = ProfileManager(dump_files) + profile_manager.SortByTimestamp() + dumps = profile_manager.GetMergedOffsets() instrumented_native_lib = os.path.join(args.instrumented_build_dir, 'lib.unstripped', args.library_name)
diff --git a/tools/cygprofile/process_profiles_unittest.py b/tools/cygprofile/process_profiles_unittest.py index 37db2ad..33cf934 100644 --- a/tools/cygprofile/process_profiles_unittest.py +++ b/tools/cygprofile/process_profiles_unittest.py
@@ -19,6 +19,15 @@ self._symbol_infos = symbol_infos +class TestProfileManager(process_profiles.ProfileManager): + def __init__(self, filecontents_mapping): + super(TestProfileManager, self).__init__(filecontents_mapping.keys()) + self._filecontents_mapping = filecontents_mapping + + def _ReadOffsets(self, filename): + return self._filecontents_mapping[filename] + + class ProcessProfilesTestCase(unittest.TestCase): def setUp(self): @@ -31,13 +40,19 @@ + [self.symbol_3] * 3) self.symbol_infos = [self.symbol_0, self.symbol_1, self.symbol_2, self.symbol_3] + self._file_counter = 0 + + def File(self, timestamp_sec, phase): + self._file_counter += 1 + return 'file-{}-{}.txt_{}'.format( + self._file_counter, timestamp_sec * 1000 * 1000 * 1000, phase) def testGetOffsetToSymbolInfo(self): processor = TestSymbolOffsetProcessor(self.symbol_infos) offset_to_symbol_info = processor._GetDumpOffsetToSymbolInfo() self.assertListEqual(self.offset_to_symbol_info, offset_to_symbol_info) - def testGetReachedSymbolsFromDump(self): + def testGetReachedOffsetsFromDump(self): processor = TestSymbolOffsetProcessor(self.symbol_infos) # 2 hits for symbol_1, 0 for symbol_2, 1 for symbol_3 dump = [8, 12, 48] @@ -77,13 +92,68 @@ self.assertListEqual(symbols_b[1:3], processor_b.MatchSymbolNames(['Y', 'X'])) - def testSortedFilenames(self): - filenames = ['second-1234-456.txt', 'first-345345-123.txt', - 'third.bar.-789.txt'] - sorted_filenames = process_profiles._SortedFilenames(filenames) - self.assertListEqual( - ['first-345345-123.txt', 'second-1234-456.txt', 'third.bar.-789.txt'], - sorted_filenames) + def testMedian(self): + self.assertEquals(None, process_profiles._Median([])) + self.assertEquals(5, process_profiles._Median([5])) + self.assertEquals(5, process_profiles._Median([1, 5, 20])) + self.assertEquals(5, process_profiles._Median([4, 6])) + self.assertEquals(5, process_profiles._Median([1, 4, 6, 100])) + self.assertEquals(5, process_profiles._Median([1, 4, 5, 6, 100])) + + def testRunGroups(self): + files = [self.File(40, 0), self.File(100, 0), self.File(200, 1), + self.File(35, 1), self.File(42, 0), self.File(95, 0)] + mgr = process_profiles.ProfileManager(files) + mgr._ComputeRunGroups() + self.assertEquals(3, len(mgr._run_groups)) + self.assertEquals(3, len(mgr._run_groups[0].Filenames())) + self.assertEquals(2, len(mgr._run_groups[1].Filenames())) + self.assertEquals(1, len(mgr._run_groups[2].Filenames())) + self.assertTrue(files[0] in mgr._run_groups[0].Filenames()) + self.assertTrue(files[3] in mgr._run_groups[0].Filenames()) + self.assertTrue(files[4] in mgr._run_groups[0].Filenames()) + self.assertTrue(files[1] in mgr._run_groups[1].Filenames()) + self.assertTrue(files[5] in mgr._run_groups[1].Filenames()) + self.assertTrue(files[2] in mgr._run_groups[2].Filenames()) + + def testReadOffsets(self): + mgr = TestProfileManager({ + self.File(30, 0): [1, 3, 5, 7], + self.File(40, 1): [8, 10], + self.File(50, 0): [13, 15]}) + self.assertListEqual([1, 3, 5, 7, 8, 10, 13, 15], + mgr.GetMergedOffsets()) + self.assertListEqual([8, 10], mgr.GetMergedOffsets(1)) + self.assertListEqual([], mgr.GetMergedOffsets(2)) + + def testRunGroupOffsets(self): + mgr = TestProfileManager({ + self.File(30, 0): [1, 2, 3, 4], + self.File(150, 0): [9, 11, 13], + self.File(40, 1): [5, 6, 7]}) + offsets_list = mgr.GetRunGroupOffsets() + self.assertEquals(2, len(offsets_list)) + self.assertListEqual([1, 2, 3, 4, 5, 6, 7], offsets_list[0]) + self.assertListEqual([9, 11, 13], offsets_list[1]) + offsets_list = mgr.GetRunGroupOffsets(0) + self.assertEquals(2, len(offsets_list)) + self.assertListEqual([1, 2, 3, 4], offsets_list[0]) + self.assertListEqual([9, 11, 13], offsets_list[1]) + offsets_list = mgr.GetRunGroupOffsets(1) + self.assertEquals(2, len(offsets_list)) + self.assertListEqual([5, 6, 7], offsets_list[0]) + self.assertListEqual([], offsets_list[1]) + + def testSorted(self): + # The fact that the ProfileManager sorts by filename is implicit in the + # other tests. It is tested explicitly here. + mgr = TestProfileManager({ + self.File(40, 0): [1, 2, 3, 4], + self.File(150, 0): [9, 11, 13], + self.File(30, 1): [5, 6, 7]}) + offsets_list = mgr.GetRunGroupOffsets() + self.assertEquals(2, len(offsets_list)) + self.assertListEqual([5, 6, 7, 1, 2, 3, 4], offsets_list[0]) if __name__ == '__main__':
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 3183b45f..49fc076 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -27752,6 +27752,7 @@ <int value="587" label="overscroll-behavior-y"/> <int value="588" label="font-variant-east-asian"/> <int value="589" label="text-decoration-skip-ink"/> + <int value="590" label="scroll-customization"/> </enum> <enum name="MappedEditingCommands">
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 1b0bf91..b385f8d 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -7198,7 +7198,7 @@ </histogram> <histogram name="Blink.ResourceLoadScheduler.DecodedBytes.KBPerFrameStatus" - enum="RendererSchedulerFrameType"> + enum="RendererSchedulerFrameType2"> <owner>toyoshim@chromium.org</owner> <owner>altimin@chromium.org</owner> <summary> @@ -7285,7 +7285,7 @@ </histogram> <histogram name="Blink.ResourceLoadScheduler.TrafficBytes.KBPerFrameStatus" - enum="RendererSchedulerFrameType"> + enum="RendererSchedulerFrameType2"> <owner>toyoshim@chromium.org</owner> <owner>altimin@chromium.org</owner> <summary> @@ -110251,6 +110251,14 @@ <affected-histogram name="RendererScheduler.RendererMainThreadLoad5"/> </histogram_suffixes> +<histogram_suffixes name="RendererScheduler.ProcessVisibilityStateSplit" + separator="."> + <suffix name="Background"/> + <suffix name="Foreground"/> + <affected-histogram name="RendererScheduler.TaskCPUDurationPerThreadType"/> + <affected-histogram name="RendererScheduler.TaskDurationPerThreadType"/> +</histogram_suffixes> + <histogram_suffixes name="RendererScheduler.TaskCountPerTaskLength" separator="."> <suffix name="LongerThan16ms"/>
diff --git a/tools/perf/core/perf_data_generator.py b/tools/perf/core/perf_data_generator.py index a83875d..74e0c06 100755 --- a/tools/perf/core/perf_data_generator.py +++ b/tools/perf/core/perf_data_generator.py
@@ -372,8 +372,7 @@ ], 'perf_tests': [ ('load_library_perf_tests', 'build145-m1'), - # crbug.com/803455 - # ('performance_browser_tests', 'build145-m1'), + ('performance_browser_tests', 'build145-m1'), ('media_perftests', 'build146-m1')] } ]) @@ -409,9 +408,8 @@ 'build140-m1', 'build141-m1', 'build142-m1' ], 'perf_tests': [ - ('load_library_perf_tests', 'build140-m1')] - # crbug.com/803455 - # ('performance_browser_tests', 'build140-m1')] + ('load_library_perf_tests', 'build140-m1'), + ('performance_browser_tests', 'build140-m1')] } ]) waterfall = add_tester( @@ -430,8 +428,7 @@ # crbug.com/785291 # ('angle_perftests', 'build103-m1'), ('load_library_perf_tests', 'build103-m1'), - # crbug.com/803455 - # ('performance_browser_tests', 'build103-m1'), + ('performance_browser_tests', 'build103-m1'), ('media_perftests', 'build104-m1')] } ]) @@ -449,9 +446,8 @@ ], 'perf_tests': [ ('angle_perftests', 'build166-m1'), - ('load_library_perf_tests', 'build166-m1')] - # crbug.com/803455 - # ('performance_browser_tests', 'build166-m1')] + ('load_library_perf_tests', 'build166-m1'), + ('performance_browser_tests', 'build166-m1')] } ]) waterfall = add_tester( @@ -528,8 +524,7 @@ 'build30-b4' # replacing build8-b1. crbug.com/724998 ], 'perf_tests': [ - # crbug.com/803455 - # ('performance_browser_tests', 'build30-b4') + ('performance_browser_tests', 'build30-b4') ] } ]) @@ -546,8 +541,7 @@ 'build130-b1', 'build131-b1', 'build132-b1' ], 'perf_tests': [ - # crbug.com/803455 - # ('performance_browser_tests', 'build132-b1') + ('performance_browser_tests', 'build132-b1') ] } ]) @@ -564,8 +558,7 @@ 'build125-b1', 'build126-b1', 'build127-b1' ], 'perf_tests': [ - # crbug.com/803455 - # ('performance_browser_tests', 'build126-b1') + ('performance_browser_tests', 'build126-b1') ] } ])
diff --git a/tools/traffic_annotation/README.md b/tools/traffic_annotation/README.md index 5c5e75f3..99b1947 100644 --- a/tools/traffic_annotation/README.md +++ b/tools/traffic_annotation/README.md
@@ -99,4 +99,4 @@ re-enable the test. CLANG_REVISION = '321529' -LASTCHANGE=bfcea61717d615f8d021c0da2d7ad7dc0589a0b1-refs/heads/master@{#530086} +LASTCHANGE=671628d8a99b8420f4dadcdb82751c0d3ea2117a-refs/heads/master@{#530817}
diff --git a/tools/traffic_annotation/auditor/traffic_annotation_auditor.cc b/tools/traffic_annotation/auditor/traffic_annotation_auditor.cc index e7edee43..86c64f3e 100644 --- a/tools/traffic_annotation/auditor/traffic_annotation_auditor.cc +++ b/tools/traffic_annotation/auditor/traffic_annotation_auditor.cc
@@ -157,7 +157,8 @@ fprintf( options_file, "--generate-compdb --tool=traffic_annotation_extractor -p=%s " - "--tool-path=%s --tool-args=--extra-arg=-resource-dir=%s ", + "--tool-path=%s --tool-arg=--extra-arg=-resource-dir=%s " + "--tool-arg=--extra-arg=-Wno-comment ", build_path_.MaybeAsASCII().c_str(), base::MakeAbsoluteFilePath(clang_tool_path_).MaybeAsASCII().c_str(), base::MakeAbsoluteFilePath(GetClangLibraryPath()).MaybeAsASCII().c_str());
diff --git a/tools/traffic_annotation/bin/linux64/traffic_annotation_auditor.sha1 b/tools/traffic_annotation/bin/linux64/traffic_annotation_auditor.sha1 index 94cbc6e..d93eae7 100644 --- a/tools/traffic_annotation/bin/linux64/traffic_annotation_auditor.sha1 +++ b/tools/traffic_annotation/bin/linux64/traffic_annotation_auditor.sha1
@@ -1 +1 @@ -770c080e777cbd7c18b34c918e1a75247ff00bf9 \ No newline at end of file +15452c1f82231c0d5a73ebd9468d36af6735b3f8 \ No newline at end of file
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml index ed3ee46f..ba10521e 100644 --- a/tools/traffic_annotation/summary/annotations.xml +++ b/tools/traffic_annotation/summary/annotations.xml
@@ -11,6 +11,7 @@ <item id="CRD_ice_config_request" hash_code="49825319" type="0" content_hash_code="8740825" os_list="linux,windows" file_path="remoting/protocol/http_ice_config_request.cc"/> <item id="CRD_relay_session_request" hash_code="24058523" type="0" content_hash_code="36997811" os_list="linux,windows" file_path="remoting/protocol/port_allocator.cc"/> <item id="CRD_telemetry_log" hash_code="18670926" type="0" content_hash_code="49025478" os_list="linux,windows" file_path="remoting/base/telemetry_log_writer.cc"/> + <item id="accounts_image_fetcher" hash_code="98658519" type="0" content_hash_code="45432230" os_list="linux,windows" file_path="components/signin/core/browser/account_fetcher_service.cc"/> <item id="adb_client_socket" hash_code="87775794" type="0" content_hash_code="56654828" os_list="linux,windows" file_path="chrome/browser/devtools/device/adb/adb_client_socket.cc"/> <item id="affiliation_lookup" hash_code="111904019" type="0" content_hash_code="81061452" os_list="linux,windows" file_path="components/password_manager/core/browser/android_affiliation/affiliation_fetcher.cc"/> <item id="android_device_manager_socket" hash_code="37249086" type="0" content_hash_code="6436865" os_list="linux,windows" file_path="chrome/browser/devtools/device/android_device_manager.cc"/>
diff --git a/ui/accessibility/platform/ax_platform_node_win.cc b/ui/accessibility/platform/ax_platform_node_win.cc index 7d3ead2..b12f041 100644 --- a/ui/accessibility/platform/ax_platform_node_win.cc +++ b/ui/accessibility/platform/ax_platform_node_win.cc
@@ -3474,6 +3474,8 @@ switch (event) { case AX_EVENT_ALERT: return EVENT_SYSTEM_ALERT; + case AX_EVENT_EXPANDED_CHANGED: + return EVENT_OBJECT_STATECHANGE; case AX_EVENT_FOCUS: return EVENT_OBJECT_FOCUS; case AX_EVENT_MENU_START:
diff --git a/ui/android/delegated_frame_host_android.cc b/ui/android/delegated_frame_host_android.cc index 5520cfc..6e2518c 100644 --- a/ui/android/delegated_frame_host_android.cc +++ b/ui/android/delegated_frame_host_android.cc
@@ -14,7 +14,6 @@ #include "components/viz/common/quads/compositor_frame.h" #include "components/viz/common/surfaces/surface_id.h" #include "components/viz/host/host_frame_sink_manager.h" -#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h" #include "components/viz/service/surfaces/surface.h" #include "ui/android/view_android.h" #include "ui/android/window_android_compositor.h" @@ -27,11 +26,10 @@ namespace { scoped_refptr<cc::SurfaceLayer> CreateSurfaceLayer( - viz::SurfaceManager* surface_manager, viz::SurfaceInfo surface_info, bool surface_opaque) { // manager must outlive compositors using it. - auto layer = cc::SurfaceLayer::Create(surface_manager->reference_factory()); + auto layer = cc::SurfaceLayer::Create(); layer->SetPrimarySurfaceId(surface_info.id(), base::nullopt); layer->SetFallbackSurfaceId(surface_info.id()); layer->SetBounds(surface_info.size_in_pixels()); @@ -54,13 +52,11 @@ DelegatedFrameHostAndroid::DelegatedFrameHostAndroid( ui::ViewAndroid* view, viz::HostFrameSinkManager* host_frame_sink_manager, - viz::FrameSinkManagerImpl* frame_sink_manager, Client* client, const viz::FrameSinkId& frame_sink_id) : frame_sink_id_(frame_sink_id), view_(view), host_frame_sink_manager_(host_frame_sink_manager), - frame_sink_manager_(frame_sink_manager), client_(client), begin_frame_source_(this), enable_surface_synchronization_( @@ -101,8 +97,7 @@ DCHECK(result); content_layer_ = - CreateSurfaceLayer(frame_sink_manager_->surface_manager(), - surface_info_, !has_transparent_background_); + CreateSurfaceLayer(surface_info_, !has_transparent_background_); view_->GetLayer()->AddChild(content_layer_); } else { support_->SubmitCompositorFrame(local_surface_id, std::move(frame)); @@ -127,8 +122,7 @@ DCHECK(!result_callback.is_null()); scoped_refptr<cc::Layer> readback_layer = - CreateSurfaceLayer(frame_sink_manager_->surface_manager(), surface_info_, - !has_transparent_background_); + CreateSurfaceLayer(surface_info_, !has_transparent_background_); readback_layer->SetHideLayerAndSubtree(true); compositor->AttachLayerForReadback(readback_layer); std::unique_ptr<viz::CopyOutputRequest> copy_output_request =
diff --git a/ui/android/delegated_frame_host_android.h b/ui/android/delegated_frame_host_android.h index 5fbfd41..9831d62 100644 --- a/ui/android/delegated_frame_host_android.h +++ b/ui/android/delegated_frame_host_android.h
@@ -24,7 +24,6 @@ namespace viz { class CompositorFrame; -class FrameSinkManagerImpl; class HostFrameSinkManager; } // namespace viz @@ -50,7 +49,6 @@ DelegatedFrameHostAndroid(ViewAndroid* view, viz::HostFrameSinkManager* host_frame_sink_manager, - viz::FrameSinkManagerImpl* frame_sink_manager, Client* client, const viz::FrameSinkId& frame_sink_id); @@ -121,7 +119,6 @@ ViewAndroid* view_; viz::HostFrameSinkManager* const host_frame_sink_manager_; - viz::FrameSinkManagerImpl* const frame_sink_manager_; WindowAndroidCompositor* registered_parent_compositor_ = nullptr; Client* client_;
diff --git a/ui/app_list/BUILD.gn b/ui/app_list/BUILD.gn index 53bce0f..e985be0 100644 --- a/ui/app_list/BUILD.gn +++ b/ui/app_list/BUILD.gn
@@ -63,9 +63,8 @@ "views/image_shadow_animator.h", "views/indicator_chip_view.cc", "views/indicator_chip_view.h", + "views/page_switcher.cc", "views/page_switcher.h", - "views/page_switcher_vertical.cc", - "views/page_switcher_vertical.h", "views/pulsing_block_view.cc", "views/pulsing_block_view.h", "views/search_box_view.cc",
diff --git a/ui/app_list/app_list_constants.cc b/ui/app_list/app_list_constants.cc index f6746fc..1091cfc7 100644 --- a/ui/app_list/app_list_constants.cc +++ b/ui/app_list/app_list_constants.cc
@@ -57,7 +57,6 @@ // Color of the folder bubble shadow. const SkColor kFolderShadowColor = SkColorSetRGB(0xBF, 0xBF, 0xBF); const float kFolderBubbleOpacity = 0.12f; -const int kFolderBackgroundBubbleRadius = 288; const SkColor kCardBackgroundColor = SkColorSetRGB(0xFA, 0xFA, 0xFC); @@ -166,8 +165,11 @@ // The height/width of the shelf from the bottom/side of the screen. const int kShelfSize = 48; -// Max items allowed in a folder. -const size_t kMaxFolderItems = 20; +// Max pages allowed in a folder. +const size_t kMaxFolderPages = 3; + +// Max items per page allowed in a folder. +const size_t kMaxFolderItemsPerPage = 16; // Maximum length of the folder name in chars. const size_t kMaxFolderNameChars = 80; @@ -176,6 +178,11 @@ const ui::ResourceBundle::FontStyle kItemTextFontStyle = ui::ResourceBundle::SmallFont; +// Range of the height of centerline above screen bottom that all apps should +// change opacity. NOTE: this is used to change page switcher's opacity as well. +const float kAllAppsOpacityStartPx = 8.0f; +const float kAllAppsOpacityEndPx = 144.0f; + // The UMA histogram that logs usage of suggested and regular apps. const char kAppListAppLaunched[] = "Apps.AppListAppLaunched";
diff --git a/ui/app_list/app_list_constants.h b/ui/app_list/app_list_constants.h index 58f3b98..ea0393fa 100644 --- a/ui/app_list/app_list_constants.h +++ b/ui/app_list/app_list_constants.h
@@ -55,8 +55,6 @@ APP_LIST_EXPORT extern const SkColor kFolderShadowColor; APP_LIST_EXPORT extern const float kFolderBubbleOpacity; -APP_LIST_EXPORT extern const int kFolderBackgroundBubbleRadius; - APP_LIST_EXPORT extern const SkColor kCardBackgroundColor; APP_LIST_EXPORT extern const int kPageTransitionDurationInMs; @@ -107,12 +105,15 @@ APP_LIST_EXPORT extern const int kPeekingAppListHeight; APP_LIST_EXPORT extern const int kShelfSize; -APP_LIST_EXPORT extern const size_t kMaxFolderItems; -APP_LIST_EXPORT extern const size_t kMaxFolderItems; +APP_LIST_EXPORT extern const size_t kMaxFolderPages; +APP_LIST_EXPORT extern const size_t kMaxFolderItemsPerPage; APP_LIST_EXPORT extern const size_t kMaxFolderNameChars; APP_LIST_EXPORT extern const ui::ResourceBundle::FontStyle kItemTextFontStyle; +APP_LIST_EXPORT extern const float kAllAppsOpacityStartPx; +APP_LIST_EXPORT extern const float kAllAppsOpacityEndPx; + // The different ways that the app list can transition from PEEKING to // FULLSCREEN_ALL_APPS. These values are written to logs. New enum // values can be added, but existing enums must never be renumbered or deleted
diff --git a/ui/app_list/views/app_list_folder_view.cc b/ui/app_list/views/app_list_folder_view.cc index e177d99..36a27e8 100644 --- a/ui/app_list/views/app_list_folder_view.cc +++ b/ui/app_list/views/app_list_folder_view.cc
@@ -10,6 +10,8 @@ #include "ash/app_list/model/app_list_model.h" #include "ui/accessibility/ax_node_data.h" #include "ui/app_list/app_list_constants.h" +#include "ui/app_list/app_list_features.h" +#include "ui/app_list/pagination_model.h" #include "ui/app_list/views/app_list_item_view.h" #include "ui/app_list/views/app_list_main_view.h" #include "ui/app_list/views/apps_container_view.h" @@ -17,11 +19,14 @@ #include "ui/app_list/views/contents_view.h" #include "ui/app_list/views/folder_background_view.h" #include "ui/app_list/views/folder_header_view.h" +#include "ui/app_list/views/page_switcher.h" #include "ui/app_list/views/search_box_view.h" #include "ui/compositor/scoped_layer_animation_settings.h" #include "ui/events/event.h" +#include "ui/gfx/canvas.h" #include "ui/gfx/geometry/rect_conversions.h" #include "ui/strings/grit/ui_strings.h" +#include "ui/views/background.h" #include "ui/views/controls/textfield/textfield.h" #include "ui/views/view_model.h" #include "ui/views/view_model_utils.h" @@ -30,18 +35,37 @@ namespace { -// The preferred width/height for AppListFolderView. -constexpr int kAppsFolderPreferredWidth = 576; -constexpr int kAppsFolderPreferredHeight = 504; +constexpr int kFolderBackgroundCornerRadius = 4; +constexpr int kItemGridsBottomPadding = 24; +constexpr int kFolderPadding = 12; // Indexes of interesting views in ViewModel of AppListFolderView. -const int kIndexFolderHeader = 0; -const int kIndexChildItems = 1; +constexpr int kIndexChildItems = 0; +constexpr int kIndexFolderHeader = 1; +constexpr int kIndexPageSwitcher = 2; -// Threshold for the distance from the center of the item to the circle of the -// folder container ink bubble, beyond which, the item is considered dragged -// out of the folder boundary. -const int kOutOfFolderContainerBubbleDelta = 30; +// A background with rounded corner. +class FolderBackground : public views::Background { + public: + FolderBackground(SkColor color, int corner_radius) + : color_(color), corner_radius_(corner_radius) {} + ~FolderBackground() override = default; + + private: + // views::Background overrides: + void Paint(gfx::Canvas* canvas, views::View* view) const override { + gfx::Rect bounds = view->GetContentsBounds(); + cc::PaintFlags flags; + flags.setAntiAlias(true); + flags.setColor(color_); + canvas->DrawRoundRect(bounds, corner_radius_, flags); + } + + const SkColor color_; + const int corner_radius_; + + DISALLOW_COPY_AND_ASSIGN(FolderBackground); +}; } // namespace @@ -55,20 +79,23 @@ model_(model), folder_item_(NULL), hide_for_reparent_(false) { - AddChildView(folder_header_view_); - view_model_->Add(folder_header_view_, kIndexFolderHeader); - items_grid_view_ = new AppsGridView(app_list_main_view_->contents_view(), this); - items_grid_view_->SetLayout( - container_view->apps_grid_view()->cols(), - container_view->apps_grid_view()->rows_per_page()); items_grid_view_->SetModel(model); AddChildView(items_grid_view_); view_model_->Add(items_grid_view_, kIndexChildItems); + AddChildView(folder_header_view_); + view_model_->Add(folder_header_view_, kIndexFolderHeader); + + page_switcher_ = new PageSwitcher(items_grid_view_->pagination_model(), + false /* vertical */); + AddChildView(page_switcher_); + view_model_->Add(page_switcher_, kIndexPageSwitcher); + SetPaintToLayer(); - layer()->SetFillsBoundsOpaquely(false); + SetBackground(std::make_unique<FolderBackground>( + kCardBackgroundColor, kFolderBackgroundCornerRadius)); model_->AddObserver(this); } @@ -98,14 +125,18 @@ // Stop any previous animation. layer()->GetAnimator()->StopAnimating(); - // Hide the top items temporarily if showing the view for opening the folder. - if (show) + if (show) { + // Hide the top items temporarily if showing the view for opening the + // folder. items_grid_view_->SetTopItemViewsVisible(false); + // Reset page if showing the view. + items_grid_view_->pagination_model()->SelectPage(0, false); + } + // Set initial state. layer()->SetOpacity(show ? 0.0f : 1.0f); SetVisible(true); - UpdateFolderNameVisibility(true); ui::ScopedLayerAnimationSettings animation(layer()->GetAnimator()); animation.SetTweenType(show ? kFolderFadeInTweenType @@ -115,11 +146,13 @@ show ? kFolderTransitionInDurationMs : kFolderTransitionOutDurationMs)); layer()->SetOpacity(show ? 1.0f : 0.0f); - app_list_main_view_->search_box_view()->ShowBackOrGoogleIcon(show); } gfx::Size AppListFolderView::CalculatePreferredSize() const { - gfx::Size size(kAppsFolderPreferredWidth, kAppsFolderPreferredHeight); + gfx::Size size = items_grid_view_->GetTileGridSizeWithoutPadding(); + size.Enlarge(0, kItemGridsBottomPadding + + folder_header_view_->GetPreferredSize().height()); + size.Enlarge(kFolderPadding * 2, kFolderPadding * 2); return size; } @@ -168,14 +201,30 @@ if (rect.IsEmpty()) return; + rect.Inset(kFolderPadding, kFolderPadding); + + // Calculate bounds for items grid view. + gfx::Rect grid_frame(rect); + grid_frame.Inset(items_grid_view_->GetTilePadding()); + grid_frame.set_height(items_grid_view_->GetPreferredSize().height()); + view_model_->set_ideal_bounds(kIndexChildItems, grid_frame); + + // Calculate bounds for folder header view.. gfx::Rect header_frame(rect); - gfx::Size size = folder_header_view_->GetPreferredSize(); - header_frame.set_height(size.height()); + header_frame.set_y(grid_frame.bottom() + + items_grid_view_->GetTilePadding().bottom() + + kItemGridsBottomPadding); + header_frame.set_height(folder_header_view_->GetPreferredSize().height()); view_model_->set_ideal_bounds(kIndexFolderHeader, header_frame); - gfx::Rect grid_frame(rect); - grid_frame.Subtract(header_frame); - view_model_->set_ideal_bounds(kIndexChildItems, grid_frame); + // Calculate bounds for page_switcher. + gfx::Rect page_switcher_frame(rect); + gfx::Size page_switcher_size = page_switcher_->GetPreferredSize(); + page_switcher_frame.set_x(page_switcher_frame.right() - + page_switcher_size.width()); + page_switcher_frame.set_y(header_frame.y()); + page_switcher_frame.set_size(page_switcher_size); + view_model_->set_ideal_bounds(kIndexPageSwitcher, page_switcher_frame); } void AppListFolderView::StartSetupDragInRootLevelAppsGridView( @@ -210,36 +259,9 @@ return to_folder; } -void AppListFolderView::UpdateFolderViewBackground(bool show_bubble) { - if (hide_for_reparent_) - return; - - // Before showing the folder container inking bubble, hide the folder name. - if (show_bubble) - UpdateFolderNameVisibility(false); - - container_view_->folder_background_view()->UpdateFolderContainerBubble( - show_bubble ? FolderBackgroundView::SHOW_BUBBLE - : FolderBackgroundView::HIDE_BUBBLE); -} - -void AppListFolderView::UpdateFolderNameVisibility(bool visible) { - folder_header_view_->UpdateFolderNameVisibility(visible); -} - -void AppListFolderView::SetBackButtonLabel(bool folder) { - app_list_main_view_->search_box_view()->SetBackButtonLabel(folder); -} - bool AppListFolderView::IsPointOutsideOfFolderBoundary( const gfx::Point& point) { - if (!GetLocalBounds().Contains(point)) - return true; - - gfx::Point center = GetLocalBounds().CenterPoint(); - float delta = (point - center).Length(); - return delta > - kFolderBackgroundBubbleRadius + kOutOfFolderContainerBubbleDelta; + return !GetLocalBounds().Contains(point); } // When user drags a folder item out of the folder boundary ink bubble, the
diff --git a/ui/app_list/views/app_list_folder_view.h b/ui/app_list/views/app_list_folder_view.h index 6641797..a1b9c10 100644 --- a/ui/app_list/views/app_list_folder_view.h +++ b/ui/app_list/views/app_list_folder_view.h
@@ -27,12 +27,13 @@ class AppListMainView; class AppListModel; class FolderHeaderView; +class PageSwitcher; -class AppListFolderView : public views::View, - public FolderHeaderViewDelegate, - public AppListModelObserver, - public ui::ImplicitAnimationObserver, - public AppsGridViewFolderDelegate { +class APP_LIST_EXPORT AppListFolderView : public views::View, + public FolderHeaderViewDelegate, + public AppListModelObserver, + public ui::ImplicitAnimationObserver, + public AppsGridViewFolderDelegate { public: AppListFolderView(AppsContainerView* container_view, AppListModel* model, @@ -50,9 +51,6 @@ // AppListFolderView. gfx::Rect GetItemIconBoundsAt(int index); - void UpdateFolderNameVisibility(bool visible); - void SetBackButtonLabel(bool folder); - // Hides the view immediately without animation. void HideViewImmediately(); @@ -94,7 +92,6 @@ void SetItemName(AppListFolderItem* item, const std::string& name) override; // Overridden from AppsGridViewFolderDelegate: - void UpdateFolderViewBackground(bool show_bubble) override; void ReparentItem(AppListItemView* original_drag_view, const gfx::Point& drag_point_in_folder_grid, bool has_native_drag) override; @@ -111,6 +108,7 @@ AppListMainView* app_list_main_view_; // Not Owned. FolderHeaderView* folder_header_view_; // Owned by views hierarchy. AppsGridView* items_grid_view_; // Owned by the views hierarchy. + PageSwitcher* page_switcher_ = nullptr; // Owned by the views hierarchy. std::unique_ptr<views::ViewModel> view_model_;
diff --git a/ui/app_list/views/app_list_item_view.cc b/ui/app_list/views/app_list_item_view.cc index 47874df..33d27e1 100644 --- a/ui/app_list/views/app_list_item_view.cc +++ b/ui/app_list/views/app_list_item_view.cc
@@ -52,6 +52,12 @@ // 650ms. constexpr int kTouchLongpressDelayInMs = 300; +// The color of the title for the tiles within folder. +constexpr SkColor kFolderGridTitleColor = SK_ColorBLACK; + +// The color of the selected item view within folder. +constexpr SkColor kFolderGridSelectedColor = SkColorSetARGBMacro(31, 0, 0, 0); + } // namespace // static @@ -82,7 +88,9 @@ title_->SetFontList(font); title_->SetLineHeight(font.GetHeight()); title_->SetHorizontalAlignment(gfx::ALIGN_CENTER); - title_->SetEnabledColor(kGridTitleColor); + title_->SetEnabledColor(apps_grid_view_->is_in_folder() + ? kFolderGridTitleColor + : kGridTitleColor); SetTitleSubpixelAA(); @@ -335,7 +343,8 @@ (rect.height() - kGridSelectedSize) / 2); cc::PaintFlags flags; flags.setAntiAlias(true); - flags.setColor(kGridSelectedColor); + flags.setColor(apps_grid_view_->is_in_folder() ? kFolderGridSelectedColor + : kGridSelectedColor); flags.setStyle(cc::PaintFlags::kFill_Style); canvas->DrawRoundRect(gfx::RectF(rect), kGridSelectedCornerRadius, flags); }
diff --git a/ui/app_list/views/app_list_view.cc b/ui/app_list/views/app_list_view.cc index 9b33e43..054d1c1 100644 --- a/ui/app_list/views/app_list_view.cc +++ b/ui/app_list/views/app_list_view.cc
@@ -510,7 +510,13 @@ // No-op if app list is on fullscreen all apps state and the event location is // within apps grid view's bounds. if (app_list_state_ == AppListViewState::FULLSCREEN_ALL_APPS && - GetAppsGridView()->GetBoundsInScreen().Contains(event->location())) { + GetRootAppsGridView()->GetBoundsInScreen().Contains(event->location())) { + return; + } + + if (GetAppsContainerView()->IsInFolderView()) { + // Close the folder if it is opened. + GetAppsContainerView()->app_list_folder_view()->CloseFolderPage(); return; } @@ -684,11 +690,8 @@ target_state != AppListViewState::FULLSCREEN_ALL_APPS) return; - AppsContainerView* apps_container_view = - app_list_main_view_->contents_view()->apps_container_view(); - - if (apps_container_view->IsInFolderView()) - apps_container_view->ResetForShowApps(); + if (GetAppsContainerView()->IsInFolderView()) + GetAppsContainerView()->ResetForShowApps(); if (target_state == AppListViewState::PEEKING) { app_list_main_view_->contents_view()->SetActiveState( @@ -701,7 +704,7 @@ } } else { // Set timer to ignore further scroll events for this transition. - GetAppsGridView()->StartTimerToIgnoreScrollEvents(); + GetRootAppsGridView()->StartTimerToIgnoreScrollEvents(); app_list_main_view_->contents_view()->SetActiveState( AppListModel::STATE_APPS, !is_side_shelf_); @@ -774,10 +777,16 @@ return display::Screen::GetScreen()->GetDisplayNearestView(parent_window_); } -AppsGridView* AppListView::GetAppsGridView() const { - return app_list_main_view_->contents_view() - ->apps_container_view() - ->apps_grid_view(); +AppsContainerView* AppListView::GetAppsContainerView() { + return app_list_main_view_->contents_view()->apps_container_view(); +} + +AppsGridView* AppListView::GetRootAppsGridView() { + return GetAppsContainerView()->apps_grid_view(); +} + +AppsGridView* AppListView::GetFolderAppsGridView() { + return GetAppsContainerView()->app_list_folder_view()->items_grid_view(); } AppListStateTransitionSource AppListView::GetAppListStateTransitionSource( @@ -1000,12 +1009,16 @@ return false; // Let the Apps grid view handle the event first in FULLSCREEN_ALL_APPS. - if (app_list_state_ == AppListViewState::FULLSCREEN_ALL_APPS && - GetAppsGridView()->HandleScrollFromAppListView(offset, type)) { - // Set the scroll ignore timer to avoid processing the tail end of the - // stream of scroll events, which would close the view. - SetOrRestartScrollIgnoreTimer(); - return true; + if (app_list_state_ == AppListViewState::FULLSCREEN_ALL_APPS) { + AppsGridView* apps_grid_view = GetAppsContainerView()->IsInFolderView() + ? GetFolderAppsGridView() + : GetRootAppsGridView(); + if (apps_grid_view->HandleScrollFromAppListView(offset, type)) { + // Set the scroll ignore timer to avoid processing the tail end of the + // stream of scroll events, which would close the view. + SetOrRestartScrollIgnoreTimer(); + return true; + } } if (ShouldIgnoreScrollEvents()) @@ -1065,10 +1078,7 @@ // Updates the visibility of app list items according to the change of // |app_list_state_|. - app_list_main_view_->contents_view() - ->apps_container_view() - ->apps_grid_view() - ->UpdateControlVisibility(app_list_state_, is_in_drag_); + GetAppsContainerView()->UpdateControlVisibility(app_list_state_, is_in_drag_); } void AppListView::StartAnimationForState(AppListViewState target_state) { @@ -1196,8 +1206,8 @@ DraggingLayout(); } -PaginationModel* AppListView::GetAppsPaginationModel() const { - return GetAppsGridView()->pagination_model(); +PaginationModel* AppListView::GetAppsPaginationModel() { + return GetRootAppsGridView()->pagination_model(); } gfx::Rect AppListView::GetAppInfoDialogBounds() const { @@ -1215,10 +1225,7 @@ return; is_in_drag_ = is_in_drag; - app_list_main_view_->contents_view() - ->apps_container_view() - ->apps_grid_view() - ->UpdateControlVisibility(app_list_state_, is_in_drag_); + GetAppsContainerView()->UpdateControlVisibility(app_list_state_, is_in_drag_); } int AppListView::GetScreenBottom() { @@ -1236,7 +1243,7 @@ // Updates the opacity of the items in the app list. search_box_view_->UpdateOpacity(); - GetAppsGridView()->UpdateOpacity(); + GetAppsContainerView()->UpdateOpacity(); Layout(); } @@ -1247,12 +1254,10 @@ views::Textfield* search_box = search_box_view_->search_box(); const bool is_search_box_focused = search_box->HasFocus(); - const bool is_folder_header_view_focused = - app_list_main_view_->contents_view() - ->apps_container_view() - ->app_list_folder_view() - ->folder_header_view() - ->HasTextFocus(); + const bool is_folder_header_view_focused = GetAppsContainerView() + ->app_list_folder_view() + ->folder_header_view() + ->HasTextFocus(); if (is_search_box_focused || is_folder_header_view_focused) { // Do not redirect the key event to the |search_box_| when focus is on a // text field.
diff --git a/ui/app_list/views/app_list_view.h b/ui/app_list/views/app_list_view.h index 684e8a0..4524adf 100644 --- a/ui/app_list/views/app_list_view.h +++ b/ui/app_list/views/app_list_view.h
@@ -37,6 +37,7 @@ } namespace app_list { +class AppsContainerView; class ApplicationDragAndDropHost; class AppListMainView; class AppListModel; @@ -178,7 +179,7 @@ } // Gets the PaginationModel owned by this view's apps grid. - PaginationModel* GetAppsPaginationModel() const; + PaginationModel* GetAppsPaginationModel(); // Gets the content bounds of the app info dialog of the app list in the // screen coordinates. @@ -271,8 +272,14 @@ // Gets the display nearest to the parent window. display::Display GetDisplayNearestView() const; - // Gets the apps grid view owned by this view. - AppsGridView* GetAppsGridView() const; + // Gets the apps container view owned by this view. + AppsContainerView* GetAppsContainerView(); + + // Gets the root apps grid view owned by this view. + AppsGridView* GetRootAppsGridView(); + + // Gets the apps grid view within the folder view owned by this view. + AppsGridView* GetFolderAppsGridView(); // Gets the AppListStateTransitionSource for |app_list_state_| to // |target_state|. If we are not interested in recording a state transition
diff --git a/ui/app_list/views/app_list_view_unittest.cc b/ui/app_list/views/app_list_view_unittest.cc index c817c77..c090f1b 100644 --- a/ui/app_list/views/app_list_view_unittest.cc +++ b/ui/app_list/views/app_list_view_unittest.cc
@@ -595,13 +595,12 @@ std::vector<views::View*> forward_view_list; forward_view_list.push_back(search_box_view()->search_box()); - forward_view_list.push_back( - app_list_folder_view()->folder_header_view()->GetFolderNameViewForTest()); const views::ViewModelT<AppListItemView>* view_model = app_list_folder_view()->items_grid_view()->view_model_for_test(); for (int i = 0; i < view_model->view_size(); ++i) forward_view_list.push_back(view_model->view_at(i)); - forward_view_list.push_back(search_box_view()->back_button()); + forward_view_list.push_back( + app_list_folder_view()->folder_header_view()->GetFolderNameViewForTest()); forward_view_list.push_back(search_box_view()->search_box()); std::vector<views::View*> backward_view_list = forward_view_list; std::reverse(backward_view_list.begin(), backward_view_list.end()); @@ -744,12 +743,13 @@ std::vector<views::View*> forward_view_list; forward_view_list.push_back(search_box_view()->search_box()); - forward_view_list.push_back( - app_list_folder_view()->folder_header_view()->GetFolderNameViewForTest()); const views::ViewModelT<AppListItemView>* view_model = app_list_folder_view()->items_grid_view()->view_model_for_test(); - for (int i = 0; i < view_model->view_size(); i += apps_grid_view()->cols()) + for (int i = 0; i < view_model->view_size(); + i += app_list_folder_view()->items_grid_view()->cols()) forward_view_list.push_back(view_model->view_at(i)); + forward_view_list.push_back( + app_list_folder_view()->folder_header_view()->GetFolderNameViewForTest()); forward_view_list.push_back(search_box_view()->search_box()); // Test traversal triggered by down. @@ -757,11 +757,11 @@ std::vector<views::View*> backward_view_list; backward_view_list.push_back(search_box_view()->search_box()); - for (int i = view_model->view_size() - 1; i >= 0; - i -= apps_grid_view()->cols()) - backward_view_list.push_back(view_model->view_at(i)); backward_view_list.push_back( app_list_folder_view()->folder_header_view()->GetFolderNameViewForTest()); + for (int i = view_model->view_size() - 1; i >= 0; + i -= app_list_folder_view()->items_grid_view()->cols()) + backward_view_list.push_back(view_model->view_at(i)); backward_view_list.push_back(search_box_view()->search_box()); // Test traversal triggered by up.
diff --git a/ui/app_list/views/apps_container_view.cc b/ui/app_list/views/apps_container_view.cc index 5db8047..962ded1 100644 --- a/ui/app_list/views/apps_container_view.cc +++ b/ui/app_list/views/apps_container_view.cc
@@ -17,6 +17,7 @@ #include "ui/app_list/views/apps_grid_view.h" #include "ui/app_list/views/contents_view.h" #include "ui/app_list/views/folder_background_view.h" +#include "ui/app_list/views/page_switcher.h" #include "ui/app_list/views/search_box_view.h" #include "ui/app_list/views/suggestions_container_view.h" #include "ui/base/l10n/l10n_util.h" @@ -42,13 +43,17 @@ apps_grid_view_->SetLayout(kPreferredCols, kPreferredRows); AddChildView(apps_grid_view_); - folder_background_view_ = new FolderBackgroundView(); - AddChildView(folder_background_view_); + // Page switcher should be initialized after AppsGridView. + page_switcher_ = new PageSwitcher(apps_grid_view_->pagination_model(), + true /* vertical */); + AddChildView(page_switcher_); app_list_folder_view_ = new AppListFolderView(this, model, app_list_main_view); // The folder view is initially hidden. app_list_folder_view_->SetVisible(false); + folder_background_view_ = new FolderBackgroundView(app_list_folder_view_); + AddChildView(folder_background_view_); AddChildView(app_list_folder_view_); apps_grid_view_->SetModel(model); @@ -69,7 +74,10 @@ CreateViewsForFolderTopItemsAnimation(folder_item, true); + // Disable all the items behind the folder so that they will not be reached + // during focus traversal. contents_view()->GetSearchBoxView()->search_box()->RequestFocus(); + apps_grid_view_->DisableFocusForShowingActiveFolder(true); } void AppsContainerView::ShowApps(AppListFolderItem* folder_item) { @@ -78,12 +86,12 @@ PrepareToShowApps(folder_item); SetShowState(SHOW_APPS, true); + apps_grid_view_->DisableFocusForShowingActiveFolder(false); } void AppsContainerView::ResetForShowApps() { SetShowState(SHOW_APPS, false); - folder_background_view_->UpdateFolderContainerBubble( - FolderBackgroundView::NO_BUBBLE); + apps_grid_view_->DisableFocusForShowingActiveFolder(false); } void AppsContainerView::SetDragAndDropHostOfCurrentAppList( @@ -100,6 +108,7 @@ PrepareToShowApps(folder_item); SetShowState(SHOW_ITEM_REPARENT, false); + apps_grid_view_->DisableFocusForShowingActiveFolder(false); } bool AppsContainerView::IsInFolderView() const { @@ -111,13 +120,40 @@ show_state_ = AppsContainerView::SHOW_APPS; } -gfx::Size AppsContainerView::CalculatePreferredSize() const { - const gfx::Size grid_size = apps_grid_view_->GetPreferredSize(); - const gfx::Size folder_view_size = app_list_folder_view_->GetPreferredSize(); +void AppsContainerView::UpdateControlVisibility(AppListViewState app_list_state, + bool is_in_drag) { + apps_grid_view_->UpdateControlVisibility(app_list_state, is_in_drag); + page_switcher_->SetVisible( + app_list_state == AppListViewState::FULLSCREEN_ALL_APPS || is_in_drag); +} - int width = std::max(grid_size.width(), folder_view_size.width()); - int height = std::max(grid_size.height(), folder_view_size.height()); - return gfx::Size(width, height); +void AppsContainerView::UpdateOpacity() { + apps_grid_view_->UpdateOpacity(); + + // Updates the opacity of page switcher buttons. The same rule as all apps in + // AppsGridView. + AppListView* app_list_view = contents_view()->app_list_view(); + bool should_restore_opacity = + !app_list_view->is_in_drag() && + (app_list_view->app_list_state() != AppListViewState::CLOSED); + int screen_bottom = app_list_view->GetScreenBottom(); + gfx::Rect switcher_bounds = page_switcher_->GetBoundsInScreen(); + float centerline_above_work_area = + std::max<float>(screen_bottom - switcher_bounds.CenterPoint().y(), 0.f); + float opacity = + std::min(std::max((centerline_above_work_area - kAllAppsOpacityStartPx) / + (kAllAppsOpacityEndPx - kAllAppsOpacityStartPx), + 0.f), + 1.0f); + page_switcher_->layer()->SetOpacity(should_restore_opacity ? 1.0f : opacity); +} + +gfx::Size AppsContainerView::CalculatePreferredSize() const { + gfx::Size size = apps_grid_view_->GetPreferredSize(); + // Add padding to both side of the apps grid to keep it horizontally + // centered since we place page switcher on the right side. + size.Enlarge(kAppsGridLeftRightPadding * 2, 0); + return size; } void AppsContainerView::Layout() { @@ -126,13 +162,36 @@ return; switch (show_state_) { - case SHOW_APPS: - apps_grid_view_->SetBoundsRect(rect); + case SHOW_APPS: { + gfx::Rect grid_rect = rect; + grid_rect.Inset(kAppsGridLeftRightPadding, 0); + apps_grid_view_->SetBoundsRect(grid_rect); + + gfx::Rect page_switcher_rect = rect; + const int page_switcher_width = + page_switcher_->GetPreferredSize().width(); + page_switcher_rect.set_x(page_switcher_rect.right() - + page_switcher_width); + page_switcher_rect.set_width(page_switcher_width); + page_switcher_->SetBoundsRect(page_switcher_rect); break; - case SHOW_ACTIVE_FOLDER: + } + case SHOW_ACTIVE_FOLDER: { folder_background_view_->SetBoundsRect(rect); - app_list_folder_view_->SetBoundsRect(rect); + + // The opened folder view's center should try to overlap with the folder + // item's center while it must fit within the bounds of this view. + DCHECK(apps_grid_view_->activated_folder_item_view()); + gfx::Rect item_bounds_in_container = apps_grid_view_->ConvertRectToParent( + apps_grid_view_->activated_folder_item_view()->bounds()); + gfx::Rect folder_bounds_in_container = + gfx::Rect(app_list_folder_view_->GetPreferredSize()); + folder_bounds_in_container += (item_bounds_in_container.CenterPoint() - + folder_bounds_in_container.CenterPoint()); + folder_bounds_in_container.AdjustToFit(rect); + app_list_folder_view_->SetBoundsRect(folder_bounds_in_container); break; + } case SHOW_ITEM_REPARENT: break; default: @@ -275,31 +334,24 @@ switch (show_state_) { case SHOW_APPS: folder_background_view_->SetVisible(false); - if (show_apps_with_animation) { + apps_grid_view_->ResetForShowApps(); + if (show_apps_with_animation) app_list_folder_view_->ScheduleShowHideAnimation(false, false); - apps_grid_view_->ScheduleShowHideAnimation(true); - } else { + else app_list_folder_view_->HideViewImmediately(); - apps_grid_view_->ResetForShowApps(); - } break; case SHOW_ACTIVE_FOLDER: folder_background_view_->SetVisible(true); - apps_grid_view_->ScheduleShowHideAnimation(false); app_list_folder_view_->ScheduleShowHideAnimation(true, false); break; case SHOW_ITEM_REPARENT: folder_background_view_->SetVisible(false); - folder_background_view_->UpdateFolderContainerBubble( - FolderBackgroundView::NO_BUBBLE); app_list_folder_view_->ScheduleShowHideAnimation(false, true); - apps_grid_view_->ScheduleShowHideAnimation(true); break; default: NOTREACHED(); } - app_list_folder_view_->SetBackButtonLabel(IsInFolderView()); Layout(); } @@ -317,6 +369,9 @@ void AppsContainerView::CreateViewsForFolderTopItemsAnimation( AppListFolderItem* active_folder, bool open_folder) { + if (!is_folder_top_items_animation_enabled_) + return; + top_icon_views_.clear(); std::vector<gfx::Rect> top_items_bounds = GetTopItemIconBoundsInActiveFolder();
diff --git a/ui/app_list/views/apps_container_view.h b/ui/app_list/views/apps_container_view.h index 3a18695c..400823a 100644 --- a/ui/app_list/views/apps_container_view.h +++ b/ui/app_list/views/apps_container_view.h
@@ -27,6 +27,7 @@ class AppListMainView; class AppListModel; class FolderBackgroundView; +class PageSwitcher; // AppsContainerView contains a root level AppsGridView to render the root level // app items, and a AppListFolderView to render the app items inside the @@ -65,6 +66,14 @@ // Called to notify the AppsContainerView that a reparent drag has completed. void ReparentDragEnded(); + // Updates the visibility of the items in this view according to + // |app_list_state| and |is_in_drag|. + void UpdateControlVisibility(AppListViewState app_list_state, + bool is_in_drag); + + // Updates the opacity of the items in this view during dragging. + void UpdateOpacity(); + // views::View overrides: gfx::Size CalculatePreferredSize() const override; void Layout() override; @@ -91,6 +100,10 @@ } AppListFolderView* app_list_folder_view() { return app_list_folder_view_; } + void set_folder_top_items_animation_enabled_for_test(bool enabled) { + is_folder_top_items_animation_enabled_ = enabled; + } + private: enum ShowState { SHOW_NONE, // initial state @@ -123,6 +136,7 @@ // The views below are owned by views hierarchy. AppsGridView* apps_grid_view_ = nullptr; AppListFolderView* app_list_folder_view_ = nullptr; + PageSwitcher* page_switcher_ = nullptr; FolderBackgroundView* folder_background_view_ = nullptr; ShowState show_state_ = SHOW_NONE; @@ -133,6 +147,9 @@ size_t top_icon_animation_pending_count_ = 0u; + // True if the animation for the folder top items is enabled. + bool is_folder_top_items_animation_enabled_ = true; + DISALLOW_COPY_AND_ASSIGN(AppsContainerView); };
diff --git a/ui/app_list/views/apps_grid_view.cc b/ui/app_list/views/apps_grid_view.cc index 6f8fcbf..eba96767 100644 --- a/ui/app_list/views/apps_grid_view.cc +++ b/ui/app_list/views/apps_grid_view.cc
@@ -31,7 +31,6 @@ #include "ui/app_list/views/contents_view.h" #include "ui/app_list/views/expand_arrow_view.h" #include "ui/app_list/views/indicator_chip_view.h" -#include "ui/app_list/views/page_switcher_vertical.h" #include "ui/app_list/views/pulsing_block_view.h" #include "ui/app_list/views/search_box_view.h" #include "ui/app_list/views/search_result_tile_item_view.h" @@ -84,6 +83,9 @@ constexpr int kTileHorizontalPadding = 12; constexpr int kTileVerticalPadding = 6; +// Padding of a tile within the folder view. +constexpr int kFolderTilePadding = 6; + // Width in pixels of the area on the sides that triggers a page flip. constexpr int kPageFlipZoneSize = 40; @@ -135,11 +137,6 @@ constexpr float kExpandArrowShowStartFraction = 0.5f; constexpr float kExpandArrowShowEndFraction = 1.0f; -// Range of the height of centerline above screen bottom that all apps should -// change opacity. -constexpr float kAllAppsOpacityStartPx = 8.0f; -constexpr float kAllAppsOpacityEndPx = 144.0f; - // The length of time we ignore scroll events on the AppsGridView after the // AppListView transitions to FULLSCREEN_ALL_APPS. constexpr base::TimeDelta kIgnoreScrollEventsDurationMs = @@ -378,10 +375,10 @@ pagination_model_.AddObserver(this); - page_switcher_view_ = new PageSwitcherVertical(&pagination_model_); pagination_controller_.reset(new PaginationController( - &pagination_model_, PaginationController::SCROLL_AXIS_VERTICAL)); - AddChildView(page_switcher_view_); + &pagination_model_, folder_delegate_ + ? PaginationController::SCROLL_AXIS_HORIZONTAL + : PaginationController::SCROLL_AXIS_VERTICAL)); } AppsGridView::~AppsGridView() { @@ -399,7 +396,6 @@ if (item_list_) item_list_->RemoveObserver(this); - // Make sure |page_switcher_view_| is deleted before |pagination_model_|. view_model_.Clear(); RemoveAllChildViews(true); } @@ -409,8 +405,7 @@ rows_per_page_ = rows_per_page; } -// static -gfx::Size AppsGridView::GetTotalTileSize() { +gfx::Size AppsGridView::GetTotalTileSize() const { static gfx::Size rect_size; if (!rect_size.IsEmpty()) @@ -423,17 +418,17 @@ return rect_size; } -// static -gfx::Insets AppsGridView::GetTilePadding() { - static gfx::Insets tile_padding_full_screen; +gfx::Insets AppsGridView::GetTilePadding() const { + if (folder_delegate_) + return gfx::Insets(-kFolderTilePadding, -kFolderTilePadding); + return gfx::Insets(-kTileVerticalPadding, -kTileHorizontalPadding); +} - // Full screen mode. - if (!tile_padding_full_screen.IsEmpty()) - return tile_padding_full_screen; - tile_padding_full_screen = - gfx::Insets(-kTileVerticalPadding, -kTileHorizontalPadding, - -kTileVerticalPadding, -kTileHorizontalPadding); - return tile_padding_full_screen; +gfx::Size AppsGridView::GetTileGridSizeWithoutPadding() const { + gfx::Size size = GetTileGridSize(); + gfx::Insets grid_padding = GetTilePadding(); + size.Enlarge(grid_padding.width(), grid_padding.height()); + return size; } void AppsGridView::ResetForShowApps() { @@ -451,6 +446,14 @@ static_cast<size_t>(view_model_.view_size())); } +void AppsGridView::DisableFocusForShowingActiveFolder(bool disabled) { + for (auto* v : suggestions_container_->tile_views()) + v->SetEnabled(!disabled); + for (int i = 0; i < view_model_.view_size(); ++i) { + view_model_.view_at(i)->SetEnabled(!disabled); + } +} + void AppsGridView::SetModel(AppListModel* model) { if (model_) model_->RemoveObserver(this); @@ -494,8 +497,6 @@ } if (suggestions_container_) suggestions_container_->ClearSelectedIndex(); - if (expand_arrow_view_) - expand_arrow_view_->SetSelected(false); } bool AppsGridView::IsSelectedView(const AppListItemView* view) const { @@ -505,7 +506,7 @@ views::View* AppsGridView::GetSelectedView() const { if (selected_view_) return selected_view_; - if (expand_arrow_view_ && expand_arrow_view_->selected()) + if (expand_arrow_view_ && expand_arrow_view_->HasFocus()) return expand_arrow_view_; if (suggestions_container_) return suggestions_container_->GetSelectedView(); @@ -596,11 +597,6 @@ MaybeStartPageFlipTimer(last_drag_point_); - gfx::Point page_switcher_point(last_drag_point_); - views::View::ConvertPointToTarget(this, page_switcher_view_, - &page_switcher_point); - page_switcher_view_->UpdateUIForDragPoint(page_switcher_point); - if (last_folder_drop_target != folder_drop_target_ || last_reorder_drop_target != reorder_drop_target_ || last_drop_attempt != drop_attempt_) { @@ -691,11 +687,6 @@ AnimateToIdealBounds(); StopPageFlipTimer(); - - // If user releases mouse inside a folder's grid view, burst the folder - // container ink bubble. - if (folder_delegate_ && !IsDraggingForReparentInHiddenGridView()) - folder_delegate_->UpdateFolderViewBackground(false); } void AppsGridView::StopPageFlipTimer() { @@ -826,10 +817,10 @@ } gfx::Size AppsGridView::CalculatePreferredSize() const { + if (folder_delegate_) + return GetTileGridSize(); + gfx::Size size = gfx::Size(kAppsGridPreferredWidth, kAppsGridPreferredHeight); - // Add padding to both side of the apps grid to keep it horizontally - // centered since we place page switcher on the right side. - size.Enlarge(kAppsGridLeftRightPadding * 2, 0); return size; } @@ -911,12 +902,6 @@ view->SetBoundsRect(view_model_.ideal_bounds(i)); } views::ViewModelUtils::SetViewBoundsToIdealBounds(pulsing_blocks_model_); - - const int page_switcher_width = - page_switcher_view_->GetPreferredSize().width(); - rect.set_x(rect.right() - page_switcher_width); - rect.set_width(page_switcher_width); - page_switcher_view_->SetBoundsRect(rect); } void AppsGridView::UpdateControlVisibility(AppListViewState app_list_state, @@ -935,8 +920,6 @@ AppListItemView* view = GetItemViewAt(i); view->SetVisible(fullscreen_apps_in_drag); } - - page_switcher_view_->SetVisible(fullscreen_apps_in_drag); } bool AppsGridView::OnKeyPressed(const ui::KeyEvent& event) { @@ -1000,6 +983,7 @@ view_model_.Add(view, i); AddChildView(view); } + UpdateColsAndRowsForFolder(); UpdatePaging(); UpdatePulsingBlockViews(); Layout(); @@ -1016,15 +1000,13 @@ } int AppsGridView::TilesPerPage(int page) const { + if (folder_delegate_) + return kMaxFolderItemsPerPage; if (page == 0) return cols_ * (rows_per_page_ - 1); return cols_ * rows_per_page_; } -int AppsGridView::LastIndexOfPage(int page) const { - return TilesPerPage(page) - 1; -} - void AppsGridView::UpdatePaging() { if (!view_model_.view_size() || !TilesPerPage(0)) { pagination_model_.SetTotalPages(0); @@ -1164,180 +1146,6 @@ return GetIndexFromModelIndex(view_index); } -void AppsGridView::MoveSelected(int page_delta, - int slot_x_delta, - int slot_y_delta) { - if (expand_arrow_view_ && expand_arrow_view_->selected() && - HandleExpandArrowMove(page_delta, slot_x_delta, slot_y_delta)) { - return; - } - - if (!selected_view_) { - // If fullscreen app list is enabled and we are on the first page, moving - // selected should consider suggested apps tiles before all apps tiles. - int current_page = pagination_model_.selected_page(); - if (!suggestions_container_ || current_page != 0) - return SetSelectedItemByIndex(Index(current_page, 0)); - if (HandleSuggestionsMove(page_delta, slot_x_delta, slot_y_delta)) - return; - } - - const Index& selected = GetIndexOfView(selected_view_); - int target_slot = selected.slot + slot_x_delta + slot_y_delta * cols_; - - // Moving left from the first slot of all apps tiles should move focus to - // the last slot of previous page or last tile of suggested apps. - if (selected.slot == 0 && slot_x_delta == -1) { - if (selected.page == 0) { - ClearSelectedView(selected_view_); - if (!suggestions_container_) - return; - suggestions_container_->SetSelectedIndex( - suggestions_container_->num_results() - 1); - return; - } else { - page_delta = -1; - target_slot = LastIndexOfPage(selected.page + page_delta); - } - } - - // Moving right from last slot should flip to next page and focus on the - // first tile. - if (selected.slot == LastIndexOfPage(selected.page) && slot_x_delta == 1) { - page_delta = 1; - target_slot = 0; - } - - // Moving up from the first row of all apps tiles should move focus to the - // last row of previous page or suggested apps. - if (selected.slot / cols_ == 0 && slot_y_delta == -1) { - if (selected.page == 0) { - ClearSelectedView(selected_view_); - if (!suggestions_container_) - return; - const int max_suggestion_index = - suggestions_container_->num_results() - 1; - int selected_index = std::min(max_suggestion_index, selected.slot); - suggestions_container_->SetSelectedIndex(selected_index); - return; - } else { - page_delta = -1; - target_slot = LastIndexOfPage(selected.page + page_delta) - - (cols_ - 1 - selected.slot); - } - } - - // Moving down from the last row of all apps tiles should move focus to the - // first row of next page if it exists. - if (LastIndexOfPage(selected.page) - selected.slot < cols_ && - slot_y_delta == 1) { - if (selected.page < pagination_model_.total_pages() - 1) { - page_delta = 1; - target_slot = - (cols_ - 1) - (LastIndexOfPage(selected.page) - selected.slot); - } else { - target_slot = selected.slot; - } - } - - // Clamp the target slot to the last item if we are moving in or to the last - // page but our target slot is past the end of the item list. - if (selected.page + page_delta == pagination_model_.total_pages() - 1) { - int last_item_slot = - GetIndexFromModelIndex(view_model_.view_size() - 1).slot; - if (last_item_slot < target_slot) { - target_slot = last_item_slot; - } - } - - int target_page = std::min(pagination_model_.total_pages() - 1, - std::max(selected.page + page_delta, 0)); - SetSelectedItemByIndex(Index(target_page, target_slot)); -} - -bool AppsGridView::HandleSuggestionsMove(int page_delta, - int slot_x_delta, - int slot_y_delta) { - DCHECK(suggestions_container_); - DCHECK(expand_arrow_view_); - - if (suggestions_container_->selected_index() == -1) { - suggestions_container_->SetSelectedIndex(0); - return true; - } - - if (page_delta == -1 || slot_y_delta == -1) - return true; - - if (slot_x_delta != 0) { - int new_index = suggestions_container_->selected_index() + slot_x_delta; - if (new_index == suggestions_container_->num_results()) { - suggestions_container_->ClearSelectedIndex(); - if (contents_view_->GetActiveState() == AppListModel::STATE_START) { - // In state start, moving right out of |suggestions_container_| should - // give selection to the expand arrow. - expand_arrow_view_->SetSelected(true); - } else { - DCHECK(contents_view_->GetActiveState() == AppListModel::STATE_APPS); - // In state apps, moving right out of |suggestions_container_| should - // give selection to the first tile of all apps. - SetSelectedItemByIndex(Index(0, 0)); - } - } else if (suggestions_container_->IsValidSelectionIndex(new_index)) { - suggestions_container_->SetSelectedIndex(new_index); - } - return true; - } - - if (slot_y_delta == 1) { - if (contents_view_->GetActiveState() == AppListModel::STATE_START) { - // In state start, moving down from |suggestions_container_| should give - // selection to the expand arrow. - expand_arrow_view_->SetSelected(true); - } else { - DCHECK(contents_view_->GetActiveState() == AppListModel::STATE_APPS); - // In state apps, moving down from |suggestions_container_| should give - // selection to the first row of all apps. - SetSelectedItemByIndex( - Index(0, suggestions_container_->selected_index())); - } - suggestions_container_->ClearSelectedIndex(); - return true; - } - - // A page flip to next page from |suggestions_container_| should focus to - // the first tile of next page. - if (page_delta == 1) { - SetSelectedItemByIndex(Index(page_delta, 0)); - suggestions_container_->ClearSelectedIndex(); - return true; - } - return false; -} - -bool AppsGridView::HandleExpandArrowMove(int page_delta, - int slot_x_delta, - int slot_y_delta) { - DCHECK(suggestions_container_); - DCHECK(expand_arrow_view_); - DCHECK(contents_view_->GetActiveState() == AppListModel::STATE_START); - - if (page_delta != 0 || slot_x_delta == 1 || slot_y_delta == 1 || - (slot_x_delta == 0 && slot_y_delta == 0)) { - return true; - } - - if (slot_x_delta == -1 || slot_y_delta == -1) { - // Move focus to the last app in ||suggestions_container|. - expand_arrow_view_->SetSelected(false); - suggestions_container_->SetSelectedIndex( - suggestions_container_->num_results() - 1); - return true; - } - - return false; -} - const gfx::Vector2d AppsGridView::CalculateTransitionOffset( int page_of_view) const { gfx::Size grid_size = GetTileGridSize(); @@ -1574,7 +1382,8 @@ // Items can only be dropped into non-folders (which have no children) or // folders that have fewer than the max allowed items. // The OEM folder does not allow drag/drop of other items into it. - if (target_item->ChildItemCount() >= kMaxFolderItems || + const size_t kMaxItemCount = kMaxFolderItemsPerPage * kMaxFolderPages; + if (target_item->ChildItemCount() >= kMaxItemCount || IsOEMFolderItem(target_item)) { return false; } @@ -1657,9 +1466,6 @@ return; } - // Regular drag and drop in a folder's grid view. - folder_delegate_->UpdateFolderViewBackground(true); - // Calculate if the drag_view_ is dragged out of the folder's container // ink bubble. gfx::Rect bounds_to_folder_view = ConvertRectToParent(drag_view_->bounds()); @@ -1767,7 +1573,7 @@ // Move focus based on target global focus index. if (target_global_index < 0 || target_global_index >= cols_ * row_total) { // Target index is outside apps grid view. - if (folder_delegate_ && arrow_up) { + if (folder_delegate_ && !arrow_up) { contents_view_->apps_container_view() ->app_list_folder_view() ->folder_header_view() @@ -1785,6 +1591,17 @@ return true; } +void AppsGridView::UpdateColsAndRowsForFolder() { + if (!folder_delegate_ || !item_list_->item_count()) + return; + + // Try to shape the apps grid into a square. + int items_in_one_page = + std::min(kMaxFolderItemsPerPage, item_list_->item_count()); + cols_ = std::sqrt(items_in_one_page - 1) + 1; + rows_per_page_ = (items_in_one_page - 1) / cols_ + 1; +} + void AppsGridView::DispatchDragEventForReparent(Pointer pointer, const gfx::Point& drag_point) { folder_delegate_->DispatchDragEventForReparent(pointer, drag_point); @@ -1969,20 +1786,6 @@ item_view->layer()->SetOpacity(should_restore_opacity ? 1.0f : opacity); } - - // Updates the opacity of page switcher buttons. The same rule as all apps. - if (page_switcher_view_) { - gfx::Rect switcher_bounds = page_switcher_view_->GetBoundsInScreen(); - centerline_above_work_area = - std::max<float>(screen_bottom - switcher_bounds.CenterPoint().y(), 0.f); - opacity = std::min( - std::max((centerline_above_work_area - kAllAppsOpacityStartPx) / - (kAllAppsOpacityEndPx - kAllAppsOpacityStartPx), - 0.f), - 1.0f); - page_switcher_view_->layer()->SetOpacity(should_restore_opacity ? 1.0f - : opacity); - } } void AppsGridView::StartTimerToIgnoreScrollEvents() { @@ -2076,14 +1879,6 @@ else if (drag_point.y() > height() - kPageFlipZoneSize) new_page_flip_target = pagination_model_.selected_page() + 1; } else { - if (page_switcher_view_->bounds().Contains(drag_point)) { - gfx::Point page_switcher_point(drag_point); - views::View::ConvertPointToTarget(this, page_switcher_view_, - &page_switcher_point); - new_page_flip_target = - page_switcher_view_->GetPageForPoint(page_switcher_point); - } - // TODO(xiyuan): Fix this for RTL. if (new_page_flip_target == -1 && drag_point.x() < kPageFlipZoneSize) new_page_flip_target = pagination_model_.selected_page() - 1; @@ -2181,6 +1976,7 @@ bounds_animator_.SetAnimationDelegate( drag_view_, std::unique_ptr<gfx::AnimationDelegate>( new ItemRemoveAnimationDelegate(drag_view_))); + UpdateColsAndRowsForFolder(); UpdatePaging(); } @@ -2223,6 +2019,7 @@ item_list_->AddObserver(this); model_->AddObserver(this); + UpdateColsAndRowsForFolder(); UpdatePaging(); } @@ -2295,6 +2092,7 @@ bounds_animator_.SetAnimationDelegate( drag_view_, std::unique_ptr<gfx::AnimationDelegate>( new ItemRemoveAnimationDelegate(drag_view_))); + UpdateColsAndRowsForFolder(); UpdatePaging(); return true; @@ -2420,6 +2218,7 @@ // on drag/animation from PEEKING. view->SetVisible(model_->state_fullscreen() != AppListViewState::PEEKING); + UpdateColsAndRowsForFolder(); UpdatePaging(); UpdatePulsingBlockViews(); Layout(); @@ -2431,6 +2230,7 @@ DeleteItemViewAtIndex(index); + UpdateColsAndRowsForFolder(); UpdatePaging(); UpdatePulsingBlockViews(); Layout(); @@ -2443,6 +2243,7 @@ EndDrag(true); view_model_.Move(from_index, to_index); + UpdateColsAndRowsForFolder(); UpdatePaging(); AnimateToIdealBounds(); } @@ -2540,7 +2341,13 @@ } gfx::Size AppsGridView::GetTileGridSize() const { - return gfx::Size(kAppsGridPreferredWidth, kAppsGridPreferredHeight); + if (!folder_delegate_) + return gfx::Size(kAppsGridPreferredWidth, kAppsGridPreferredHeight); + + gfx::Rect bounds = GetExpectedTileBounds(Index(0, 0)); + bounds.Union(GetExpectedTileBounds(Index(0, rows_per_page_ * cols_ - 1))); + bounds.Inset(GetTilePadding()); + return bounds.size(); } int AppsGridView::GetHeightOnTopOfAllAppsTiles(int page) const { @@ -2559,8 +2366,13 @@ } gfx::Rect AppsGridView::GetExpectedTileBounds(const Index& index) const { + if (!cols_) + return gfx::Rect(); + gfx::Rect bounds(GetContentsBounds()); - bounds.Offset(kAppsGridLeftRightPadding - kTileHorizontalPadding, 0); + if (!folder_delegate_) + bounds.Offset(-kTileHorizontalPadding, 0); + bounds.Inset(0, GetHeightOnTopOfAllAppsTiles(index.page), 0, 0); int row = index.slot / cols_; int col = index.slot % cols_;
diff --git a/ui/app_list/views/apps_grid_view.h b/ui/app_list/views/apps_grid_view.h index 0cbee48..2a7fb28 100644 --- a/ui/app_list/views/apps_grid_view.h +++ b/ui/app_list/views/apps_grid_view.h
@@ -51,7 +51,6 @@ class ContentsView; class IndicatorChipView; class SuggestionsContainerView; -class PageSwitcher; class PaginationController; class PulsingBlockView; class ExpandArrowView; @@ -82,14 +81,21 @@ int rows_per_page() const { return rows_per_page_; } // Returns the size of a tile view including its padding. - static gfx::Size GetTotalTileSize(); + gfx::Size GetTotalTileSize() const; // Returns the padding around a tile view. - static gfx::Insets GetTilePadding(); + gfx::Insets GetTilePadding() const; + + // Returns the size of the entire tile grid without padding. + gfx::Size GetTileGridSizeWithoutPadding() const; // This resets the grid view to a fresh state for showing the app list. void ResetForShowApps(); + // All items in this view become unfocusable if |disabled| is true. This is + // used to trap focus within the folder when it is opened. + void DisableFocusForShowingActiveFolder(bool disabled); + // Sets |model| to use. Note this does not take ownership of |model|. void SetModel(AppListModel* model); @@ -236,6 +242,8 @@ folder_delegate_ = folder_delegate; } + bool is_in_folder() const { return !!folder_delegate_; } + AppListItemView* activated_folder_item_view() const { return activated_folder_item_view_; } @@ -289,9 +297,6 @@ // Returns all apps tiles per page based on |page|. int TilesPerPage(int page) const; - // Returns the last index of |page|. - int LastIndexOfPage(int page) const; - // Updates from model. void Update(); @@ -326,20 +331,6 @@ // Gets the index of the AppListItemView at the end of the view model. Index GetLastViewIndex() const; - void MoveSelected(int page_delta, int slot_x_delta, int slot_y_delta); - - // Returns true if the given moving operation should be handled by - // |suggestions_container_|, otherwise false. - bool HandleSuggestionsMove(int page_delta, - int slot_x_delta, - int slot_y_delta); - - // Returns true if the given moving operation should be handled by - // |expand_arrow_view_|, otherwise false. - bool HandleExpandArrowMove(int page_delta, - int slot_x_delta, - int slot_y_delta); - // Calculates the offset for |page_of_view| based on current page and // transition target page. const gfx::Vector2d CalculateTransitionOffset(int page_of_view) const; @@ -533,6 +524,9 @@ // state. bool HandleFocusMovementInFullscreenAllAppsState(bool arrow_up); + // Update number of columns and rows for apps within a folder. + void UpdateColsAndRowsForFolder(); + AppListModel* model_ = nullptr; // Owned by AppListView. AppListItemList* item_list_ = nullptr; // Not owned. @@ -542,7 +536,6 @@ PaginationModel pagination_model_; // Must appear after |pagination_model_|. std::unique_ptr<PaginationController> pagination_controller_; - PageSwitcher* page_switcher_view_ = nullptr; // Owned by views hierarchy. // Created by AppListMainView, owned by views hierarchy. ContentsView* contents_view_ = nullptr;
diff --git a/ui/app_list/views/apps_grid_view_folder_delegate.h b/ui/app_list/views/apps_grid_view_folder_delegate.h index 924a653..402fc7b 100644 --- a/ui/app_list/views/apps_grid_view_folder_delegate.h +++ b/ui/app_list/views/apps_grid_view_folder_delegate.h
@@ -19,10 +19,6 @@ // A delegate which allows an AppsGridView to communicate with its host folder. class APP_LIST_EXPORT AppsGridViewFolderDelegate { public: - // Updates the folder view background to show or hide folder container ink - // bubble. - virtual void UpdateFolderViewBackground(bool show_bubble) = 0; - // Called when a folder item is dragged out of the folder to be re-parented. // |original_drag_view| is the |drag_view_| inside the folder's grid view. // |drag_point_in_folder_grid| is the last drag point in coordinate of the
diff --git a/ui/app_list/views/apps_grid_view_unittest.cc b/ui/app_list/views/apps_grid_view_unittest.cc index c4880332..2a33975 100644 --- a/ui/app_list/views/apps_grid_view_unittest.cc +++ b/ui/app_list/views/apps_grid_view_unittest.cc
@@ -30,6 +30,7 @@ #include "ui/app_list/test/app_list_test_model.h" #include "ui/app_list/test/app_list_test_view_delegate.h" #include "ui/app_list/test/test_search_result.h" +#include "ui/app_list/views/app_list_folder_view.h" #include "ui/app_list/views/app_list_item_view.h" #include "ui/app_list/views/app_list_main_view.h" #include "ui/app_list/views/app_list_view.h" @@ -37,6 +38,7 @@ #include "ui/app_list/views/apps_grid_view_folder_delegate.h" #include "ui/app_list/views/contents_view.h" #include "ui/app_list/views/expand_arrow_view.h" +#include "ui/app_list/views/folder_background_view.h" #include "ui/app_list/views/search_box_view.h" #include "ui/app_list/views/search_result_tile_item_view.h" #include "ui/app_list/views/suggestions_container_view.h" @@ -178,6 +180,10 @@ return apps_grid_view_->pagination_model(); } + AppListFolderView* app_list_folder_view() const { + return contents_view_->apps_container_view()->app_list_folder_view(); + } + // Points are in |apps_grid_view_|'s coordinates, and fixed for RTL. AppListItemView* SimulateDrag(AppsGridView::Pointer pointer, const gfx::Point& from, @@ -215,30 +221,6 @@ apps_grid_view_->OnKeyPressed(key_event); } - bool CheckNoSelection() { - return !expand_arrow_view_->selected() && - -1 == suggestions_container_->selected_index() && - !apps_grid_view_->has_selected_view(); - } - - bool CheckSelectionAtSuggestionsContainer(int index) { - return !expand_arrow_view_->selected() && - index == suggestions_container_->selected_index() && - !apps_grid_view_->has_selected_view(); - } - - bool CheckSelectionAtExpandArrow() { - return expand_arrow_view_->selected() && - -1 == suggestions_container_->selected_index() && - !apps_grid_view_->has_selected_view(); - } - - bool CheckSelectionAtAppsGridView(int index) { - return !expand_arrow_view_->selected() && - -1 == suggestions_container_->selected_index() && - apps_grid_view_->IsSelectedView(GetItemViewAt(index)); - } - AppListView* app_list_view_ = nullptr; // Owned by native widget. AppsGridView* apps_grid_view_ = nullptr; // Owned by |app_list_view_|. ContentsView* contents_view_ = nullptr; // Owned by |app_list_view_|. @@ -269,11 +251,6 @@ TestAppsGridViewFolderDelegate() = default; ~TestAppsGridViewFolderDelegate() override = default; - // Overridden from AppsGridViewFolderDelegate: - void UpdateFolderViewBackground(bool show_bubble) override { - show_bubble_ = show_bubble; - } - void ReparentItem(AppListItemView* original_drag_view, const gfx::Point& drag_point_in_folder_grid, bool has_native_drag) override {} @@ -293,11 +270,7 @@ void SetRootLevelDragViewVisible(bool visible) override {} - bool show_bubble() { return show_bubble_; } - private: - bool show_bubble_ = false; - DISALLOW_COPY_AND_ASSIGN(TestAppsGridViewFolderDelegate); }; @@ -407,7 +380,8 @@ TEST_P(AppsGridViewTest, MouseDragMaxItemsInFolder) { // Create and add a folder with |kMaxFolderItemsFullscreen - 1| items. - size_t kTotalItems = kMaxFolderItems - 1; + const size_t kMaxItems = kMaxFolderItemsPerPage * kMaxFolderPages; + const size_t kTotalItems = kMaxItems - 1; model_->CreateAndPopulateFolderWithApps(kTotalItems); EXPECT_EQ(1u, model_->top_level_item_list()->item_count()); EXPECT_EQ(AppListFolderItem::kItemType, @@ -421,9 +395,9 @@ model_->PopulateAppWithId(kTotalItems + 1); EXPECT_EQ(3u, model_->top_level_item_list()->item_count()); EXPECT_EQ(folder_item->id(), model_->top_level_item_list()->item_at(0)->id()); - EXPECT_EQ(model_->GetItemName(kMaxFolderItems - 1), + EXPECT_EQ(model_->GetItemName(kMaxItems - 1), model_->top_level_item_list()->item_at(1)->id()); - EXPECT_EQ(model_->GetItemName(kMaxFolderItems), + EXPECT_EQ(model_->GetItemName(kMaxItems), model_->top_level_item_list()->item_at(2)->id()); gfx::Point from = GetItemRectOnCurrentPageAt(0, 1).CenterPoint(); @@ -434,8 +408,8 @@ apps_grid_view_->EndDrag(false); EXPECT_EQ(2u, model_->top_level_item_list()->item_count()); EXPECT_EQ(folder_item->id(), model_->top_level_item_list()->item_at(0)->id()); - EXPECT_EQ(kMaxFolderItems, folder_item->ChildItemCount()); - EXPECT_EQ(model_->GetItemName(kMaxFolderItems), + EXPECT_EQ(kMaxItems, folder_item->ChildItemCount()); + EXPECT_EQ(model_->GetItemName(kMaxItems), model_->top_level_item_list()->item_at(1)->id()); test_api_->LayoutToIdealBounds(); @@ -444,7 +418,7 @@ SimulateDrag(AppsGridView::MOUSE, from, to); apps_grid_view_->EndDrag(false); EXPECT_EQ(2u, model_->top_level_item_list()->item_count()); - EXPECT_EQ(kMaxFolderItems, folder_item->ChildItemCount()); + EXPECT_EQ(kMaxItems, folder_item->ChildItemCount()); test_api_->LayoutToIdealBounds(); } @@ -452,8 +426,9 @@ // folder. TEST_P(AppsGridViewTest, MouseDragMaxItemsInFolderWithMovement) { // Create and add a folder with |kMaxFolderItemsFullscreen| in it. - size_t kTotalItems = kMaxFolderItems; - model_->CreateAndPopulateFolderWithApps(kTotalItems); + const size_t kMaxItems = kMaxFolderItemsPerPage * kMaxFolderPages; + size_t kTotalItems = kMaxItems; + model_->CreateAndPopulateFolderWithApps(kMaxItems); EXPECT_EQ(1u, model_->top_level_item_list()->item_count()); EXPECT_EQ(AppListFolderItem::kItemType, model_->top_level_item_list()->item_at(0)->GetItemType()); @@ -465,7 +440,7 @@ model_->PopulateAppWithId(kTotalItems); EXPECT_EQ(2u, model_->top_level_item_list()->item_count()); EXPECT_EQ(folder_item->id(), model_->top_level_item_list()->item_at(0)->id()); - EXPECT_EQ(model_->GetItemName(kMaxFolderItems), + EXPECT_EQ(model_->GetItemName(kMaxItems), model_->top_level_item_list()->item_at(1)->id()); AppListItemView* folder_view = @@ -495,7 +470,7 @@ // The item should not have moved into the folder. EXPECT_EQ(2u, model_->top_level_item_list()->item_count()); - EXPECT_EQ(kMaxFolderItems, folder_item->ChildItemCount()); + EXPECT_EQ(kMaxItems, folder_item->ChildItemCount()); test_api_->LayoutToIdealBounds(); } @@ -685,9 +660,7 @@ // Starts a mouse drag and then cancels it. SimulateDrag(AppsGridView::MOUSE, mouse_from, mouse_to); - EXPECT_TRUE(folder_delegate.show_bubble()); apps_grid_view_->EndDrag(true); - EXPECT_FALSE(folder_delegate.show_bubble()); EXPECT_EQ(std::string("Item 0,Item 1,Item 2,Item 3"), model_->GetModelContent()); } @@ -749,33 +722,6 @@ apps_grid_view_->IsSelectedView(GetItemViewAt(kAllAppsItems - 1))); } -// TODO(crbug.com/766807): Remove the test once the new focus model is stable. -// Tests that moving selection down from the searchbox selects the first app. -TEST_P(AppsGridViewTest, DISABLED_SelectionDownFromSearchBoxSelectsFirstApp) { - model_->PopulateApps(5); - // Check that nothing is selected. - EXPECT_TRUE(CheckNoSelection()); - - // Moves selection to the first app in the suggestions container. - SimulateKeyPress(ui::VKEY_DOWN); - - EXPECT_TRUE(CheckSelectionAtSuggestionsContainer(0)); -} - -// TODO(crbug.com/766807): Remove the test once the new focus model is stable. -// Tests that moving selection up from the first app selects nothing. -TEST_P(AppsGridViewTest, DISABLED_SelectionUpFromFirstAppSelectsNothing) { - model_->PopulateApps(5); - // Select the first app. - suggestions_container_->SetSelectedIndex(0); - - // Tests moving up. - SimulateKeyPress(ui::VKEY_UP); - - // Check that there is no selection in AppsGridView. - EXPECT_TRUE(CheckNoSelection()); -} - // Tests that UMA is properly collected when either a suggested or normal app is // launched. TEST_F(AppsGridViewTest, UMATestForLaunchingApps) { @@ -801,243 +747,6 @@ histogram_tester.ExpectBucketCount("Apps.AppListAppLaunchedFullscreen", 1, 1); } -// TODO(crbug.com/766807): Remove the test once the new focus model is stable. -// Tests that moving selection backwards (left in ltr, right in rtl) from the -// first app selects nothing, and that selection returns to the suggested apps -// when selection moves forwards (right in ltr, left in rtl). -TEST_P(AppsGridViewTest, - DISABLED_SelectionMovingBackwardsAndForwardsOnFirstSuggestedApp) { - model_->PopulateApps(5); - - // Check that nothing is selected. - EXPECT_TRUE(CheckNoSelection()); - - // Move selection forward. - SimulateKeyPress(is_rtl_ ? ui::VKEY_LEFT : ui::VKEY_RIGHT); - - // Check that the first suggested app is selected. - EXPECT_TRUE(CheckSelectionAtSuggestionsContainer(0)); - - // Move selection backward. - SimulateKeyPress(is_rtl_ ? ui::VKEY_RIGHT : ui::VKEY_LEFT); - - // Check that there is no selection. - EXPECT_TRUE(CheckNoSelection()); - - // Move selection forward. - SimulateKeyPress(is_rtl_ ? ui::VKEY_LEFT : ui::VKEY_RIGHT); - - // Check that the first suggested app is selected. - EXPECT_TRUE(CheckSelectionAtSuggestionsContainer(0)); -} - -// TODO(crbug.com/766807): Remove the test once the new focus model is stable. -// Tests that selection can traverse all suggested apps. -TEST_P(AppsGridViewTest, DISABLED_SelectionTraversesAllSuggestedApps) { - model_->PopulateApps(5); - - // Select the first suggested app. - suggestions_container_->SetSelectedIndex(0); - - // Advance selection to the next app. - SimulateKeyPress(is_rtl_ ? ui::VKEY_LEFT : ui::VKEY_RIGHT); - - // Check selection at the next suggested app. - EXPECT_TRUE(CheckSelectionAtSuggestionsContainer(1)); - - // Advance selection to the next app. - SimulateKeyPress(is_rtl_ ? ui::VKEY_LEFT : ui::VKEY_RIGHT); - - // Check selection at the next suggested app. - EXPECT_TRUE(CheckSelectionAtSuggestionsContainer(2)); - - // Advance selection to the next app, which is in the AppsGridView. - SimulateKeyPress(is_rtl_ ? ui::VKEY_LEFT : ui::VKEY_RIGHT); - - // Check selection at the first app in AppsGridView. - EXPECT_TRUE(CheckSelectionAtAppsGridView(0)); -} - -// TODO(crbug.com/766807): Remove the test once the new focus model is stable. -// Tests that selection moves from the last suggested app to the first app that -// is not suggested when selection moves forward. -TEST_P(AppsGridViewTest, - DISABLED_SelectionMovesFromLastSuggestedAppToFirstAppInGrid) { - model_->PopulateApps(5); - // Select the last of three selected apps. - suggestions_container_->SetSelectedIndex(2); - - // Move selection forward, off of the last suggested app. - SimulateKeyPress(is_rtl_ ? ui::VKEY_LEFT : ui::VKEY_RIGHT); - - // Check selection at apps grid view position 0 (first app in the app grid). - EXPECT_TRUE(CheckSelectionAtAppsGridView(0)); -} - -// TODO(crbug.com/766807): Remove the test once the new focus model is stable. -// Tests that selection moves to the first element of the next page when the -// next key is pressed. -TEST_P(AppsGridViewTest, - DISABLED_SelectionMovesToFirstElementOfNextPageWithNextKey) { - const int kPages = 2; - const int kAllAppsItems = GetTilesPerPage(0) + 1; - model_->PopulateApps(kAllAppsItems); - // Check that the first page is selected. - EXPECT_EQ(0, GetPaginationModel()->selected_page()); - - // Move to next page. - apps_grid_view_->ClearAnySelectedView(); - SimulateKeyPress(ui::VKEY_DOWN); - SimulateKeyPress(ui::VKEY_NEXT); - - // Check that the selection is on the last app item, and that the page changed - // to the last page. - EXPECT_TRUE(CheckSelectionAtAppsGridView(kAllAppsItems - 1)); - EXPECT_EQ(kPages - 1, GetPaginationModel()->selected_page()); -} - -// TODO(crbug.com/766807): Remove the test once the new focus model is stable. -// Tests that selection moves to the first element of the previous page with the -// prev key. -TEST_P(AppsGridViewTest, - DISABLED_SelectionMovesToFirstElementOfPrevPageWithPrevKey) { - const int kAllAppsItems = GetTilesPerPage(0) + 1; - model_->PopulateApps(kAllAppsItems); - // Move to next page. - apps_grid_view_->ClearAnySelectedView(); - SimulateKeyPress(ui::VKEY_DOWN); - SimulateKeyPress(ui::VKEY_NEXT); - EXPECT_TRUE( - apps_grid_view_->IsSelectedView(GetItemViewAt(kAllAppsItems - 1))); - - // Press the PREV key to return to the previous page. - SimulateKeyPress(ui::VKEY_PRIOR); - - // Check that the page has changed to page 0, and the first app is selected. - EXPECT_TRUE(CheckSelectionAtAppsGridView(0)); - EXPECT_EQ(0, GetPaginationModel()->selected_page()); -} - -// TODO(crbug.com/766807): Remove the test once the new focus model is stable. -// Tests that in state start there's no selection at the beginning. And hitting -// down/tab/right arrow key moves the selection to the first app in suggestions -// container. -TEST_P(AppsGridViewTest, DISABLED_InitialSelectionInStateStart) { - // Simulates that the app list is at state start. - contents_view_->SetActiveState(AppListModel::STATE_START); - model_->PopulateApps(GetTilesPerPage(0)); - EXPECT_TRUE(CheckNoSelection()); - - SimulateKeyPress(ui::VKEY_DOWN); - EXPECT_TRUE(CheckSelectionAtSuggestionsContainer(0)); - - apps_grid_view_->ClearAnySelectedView(); - SimulateKeyPress(ui::VKEY_RIGHT); - EXPECT_TRUE(CheckSelectionAtSuggestionsContainer(0)); - - apps_grid_view_->ClearAnySelectedView(); - SimulateKeyPress(ui::VKEY_TAB); - EXPECT_TRUE(CheckSelectionAtSuggestionsContainer(0)); -} - -// TODO(crbug.com/766807): Remove the test once the new focus model is stable. -// Tests that in state start when selection exists. Hitting tab key does -// nothing while hitting shift+tab key clears selection. -TEST_P(AppsGridViewTest, DISABLED_ClearSelectionInStateStart) { - // Simulates that the app list is at state start. - contents_view_->SetActiveState(AppListModel::STATE_START); - model_->PopulateApps(GetTilesPerPage(0)); - - // Moves selection to the first app in the suggestions container. - SimulateKeyPress(ui::VKEY_DOWN); - - SimulateKeyPress(ui::VKEY_TAB); - EXPECT_TRUE(CheckSelectionAtSuggestionsContainer(0)); - - SimulateKeyPress(ui::VKEY_TAB, ui::EF_SHIFT_DOWN); - EXPECT_TRUE(CheckNoSelection()); -} - -// TODO(crbug.com/766807): Remove the test once the new focus model is stable. -// Tests that in state start when selection is on expand arrow, only hitting -// left/up arrow key moves the selection to the last app in suggestion -// container. -TEST_P(AppsGridViewTest, DISABLED_ExpandArrowSelectionInStateStart) { - // Simulates that the app list is at state start. - contents_view_->SetActiveState(AppListModel::STATE_START); - model_->PopulateApps(GetTilesPerPage(0)); - - // Moves selection to the expand arrow. - expand_arrow_view_->SetSelected(true); - - // Expect the selection to be on the expand arrow. - EXPECT_TRUE(CheckSelectionAtExpandArrow()); - - SimulateKeyPress(ui::VKEY_DOWN); - - // Expect the selection to be on the expand arrow. - EXPECT_TRUE(CheckSelectionAtExpandArrow()); - - SimulateKeyPress(is_rtl_ ? ui::VKEY_LEFT : ui::VKEY_RIGHT); - - // Expect the selection to be on the expand arrow. - EXPECT_TRUE(CheckSelectionAtExpandArrow()); - - SimulateKeyPress(ui::VKEY_TAB); - - // Expect the selection to be on the expand arrow. - EXPECT_TRUE(CheckSelectionAtExpandArrow()); - - SimulateKeyPress(ui::VKEY_UP); - - // Expect the selection to be on the last suggested app. - EXPECT_TRUE(CheckSelectionAtSuggestionsContainer(kNumOfSuggestedApps - 1)); - - // Resets selection to the expand arrow. - apps_grid_view_->ClearAnySelectedView(); - expand_arrow_view_->SetSelected(true); - SimulateKeyPress(is_rtl_ ? ui::VKEY_RIGHT : ui::VKEY_LEFT); - - // Expect the selection to be on the last suggested app. - EXPECT_TRUE(CheckSelectionAtSuggestionsContainer(kNumOfSuggestedApps - 1)); -} - -// TODO(crbug.com/766807): Remove the test once the new focus model is stable. -// Tests that in state start when selection is on app in suggestions container, -// hitting up key moves clear selection. Hitting left/right key moves the -// selection to app on the left/right if index is valid. Hitting right key when -// selection is on the last app in suggestions container or hitting down key -// move the selection to the expand arrow. -TEST_P(AppsGridViewTest, DISABLED_SuggestionsContainerSelectionInStateStart) { - // Simulates that the app list is at state start. - contents_view_->SetActiveState(AppListModel::STATE_START); - model_->PopulateApps(GetTilesPerPage(0)); - SimulateKeyPress(ui::VKEY_DOWN); - - // Tests moving up. - SimulateKeyPress(ui::VKEY_UP); - EXPECT_TRUE(CheckNoSelection()); - SimulateKeyPress(ui::VKEY_DOWN); - - // Tests moving right. - SimulateKeyPress(is_rtl_ ? ui::VKEY_LEFT : ui::VKEY_RIGHT); - EXPECT_TRUE(CheckSelectionAtSuggestionsContainer(1)); - - // Tests moving left. - SimulateKeyPress(is_rtl_ ? ui::VKEY_RIGHT : ui::VKEY_LEFT); - EXPECT_TRUE(CheckSelectionAtSuggestionsContainer(0)); - - // Tests moving down. - SimulateKeyPress(ui::VKEY_DOWN); - EXPECT_TRUE(CheckSelectionAtExpandArrow()); - - // Sets selection to the last app in the suggestions container. - apps_grid_view_->ClearAnySelectedView(); - suggestions_container_->SetSelectedIndex(kNumOfSuggestedApps - 1); - SimulateKeyPress(is_rtl_ ? ui::VKEY_LEFT : ui::VKEY_RIGHT); - EXPECT_TRUE(CheckSelectionAtExpandArrow()); -} - TEST_F(AppsGridViewTest, ItemLabelShortNameOverride) { // If the app's full name and short name differ, the title label's tooltip // should always be the full name of the app. @@ -1119,5 +828,103 @@ ASSERT_NE(0, GetPaginationModel()->transition().progress); } +TEST_F(AppsGridViewTest, CloseFolderByClickingBackground) { + // Disable the animation for the folder top items for test purpose. + AppsContainerView* apps_container_view = + contents_view_->apps_container_view(); + apps_container_view->set_folder_top_items_animation_enabled_for_test(false); + + const size_t kTotalItems = kMaxFolderItemsPerPage; + model_->CreateAndPopulateFolderWithApps(kTotalItems); + EXPECT_EQ(1u, model_->top_level_item_list()->item_count()); + EXPECT_EQ(AppListFolderItem::kItemType, + model_->top_level_item_list()->item_at(0)->GetItemType()); + + // Open the folder. + test_api_->PressItemAt(0); + EXPECT_TRUE(apps_container_view->IsInFolderView()); + + // Simulate mouse press on folder background to close the folder. + ui::MouseEvent event(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(), + ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, + ui::EF_LEFT_MOUSE_BUTTON); + apps_container_view->folder_background_view()->OnMouseEvent(&event); + EXPECT_FALSE(apps_container_view->IsInFolderView()); +} + +TEST_F(AppsGridViewTest, PageResetAfterOpenFolder) { + // Disable the animation for the folder top items for test purpose. + contents_view_->apps_container_view() + ->set_folder_top_items_animation_enabled_for_test(false); + + const size_t kTotalItems = kMaxFolderPages * kMaxFolderItemsPerPage; + model_->CreateAndPopulateFolderWithApps(kTotalItems); + EXPECT_EQ(1u, model_->top_level_item_list()->item_count()); + EXPECT_EQ(AppListFolderItem::kItemType, + model_->top_level_item_list()->item_at(0)->GetItemType()); + + // Open the folder. It should be at page 0. + test_api_->PressItemAt(0); + PaginationModel* pagination_model = + app_list_folder_view()->items_grid_view()->pagination_model(); + EXPECT_EQ(3, pagination_model->total_pages()); + EXPECT_EQ(0, pagination_model->selected_page()); + + // Select page 2. + pagination_model->SelectPage(2, false /* animate */); + EXPECT_EQ(2, pagination_model->selected_page()); + + // Close the folder and reopen it. It should be at page 0. + app_list_folder_view()->CloseFolderPage(); + test_api_->PressItemAt(0); + EXPECT_EQ(3, pagination_model->total_pages()); + EXPECT_EQ(0, pagination_model->selected_page()); +} + +TEST_F(AppsGridViewTest, FolderColsAndRows) { + // Disable the animation for the folder top items for test purpose. + contents_view_->apps_container_view() + ->set_folder_top_items_animation_enabled_for_test(false); + + // Populate folders with different number of apps. + model_->CreateAndPopulateFolderWithApps(2); + model_->CreateAndPopulateFolderWithApps(5); + model_->CreateAndPopulateFolderWithApps(9); + model_->CreateAndPopulateFolderWithApps(15); + model_->CreateAndPopulateFolderWithApps(17); + + // Check the number of cols and rows for each opened folder. + AppsGridView* items_grid_view = app_list_folder_view()->items_grid_view(); + test_api_->PressItemAt(0); + EXPECT_EQ(2, items_grid_view->view_model_for_test()->view_size()); + EXPECT_EQ(2, items_grid_view->cols()); + EXPECT_EQ(1, items_grid_view->rows_per_page()); + app_list_folder_view()->CloseFolderPage(); + + test_api_->PressItemAt(1); + EXPECT_EQ(5, items_grid_view->view_model_for_test()->view_size()); + EXPECT_EQ(3, items_grid_view->cols()); + EXPECT_EQ(2, items_grid_view->rows_per_page()); + app_list_folder_view()->CloseFolderPage(); + + test_api_->PressItemAt(2); + EXPECT_EQ(9, items_grid_view->view_model_for_test()->view_size()); + EXPECT_EQ(3, items_grid_view->cols()); + EXPECT_EQ(3, items_grid_view->rows_per_page()); + app_list_folder_view()->CloseFolderPage(); + + test_api_->PressItemAt(3); + EXPECT_EQ(15, items_grid_view->view_model_for_test()->view_size()); + EXPECT_EQ(4, items_grid_view->cols()); + EXPECT_EQ(4, items_grid_view->rows_per_page()); + app_list_folder_view()->CloseFolderPage(); + + test_api_->PressItemAt(4); + EXPECT_EQ(17, items_grid_view->view_model_for_test()->view_size()); + EXPECT_EQ(4, items_grid_view->cols()); + EXPECT_EQ(4, items_grid_view->rows_per_page()); + app_list_folder_view()->CloseFolderPage(); +} + } // namespace test } // namespace app_list
diff --git a/ui/app_list/views/expand_arrow_view.cc b/ui/app_list/views/expand_arrow_view.cc index ff0d0d80..02ada452 100644 --- a/ui/app_list/views/expand_arrow_view.cc +++ b/ui/app_list/views/expand_arrow_view.cc
@@ -92,25 +92,14 @@ ExpandArrowView::~ExpandArrowView() = default; -void ExpandArrowView::SetSelected(bool selected) { - if (selected == selected_) - return; - - selected_ = selected; - SchedulePaint(); - - if (selected) - NotifyAccessibilityEvent(ui::AX_EVENT_SELECTION, true); -} - void ExpandArrowView::PaintButtonContents(gfx::Canvas* canvas) { gfx::Rect rect(GetContentsBounds()); // Draw focused or unfocused background. cc::PaintFlags flags; flags.setAntiAlias(true); - flags.setColor(selected_ ? kFocusedBackgroundColor - : kUnFocusedBackgroundColor); + flags.setColor(HasFocus() ? kFocusedBackgroundColor + : kUnFocusedBackgroundColor); flags.setStyle(cc::PaintFlags::kFill_Style); canvas->DrawCircle(gfx::PointF(rect.CenterPoint()), kSelectedRadius, flags); @@ -154,11 +143,13 @@ } void ExpandArrowView::OnFocus() { - SetSelected(true); + SchedulePaint(); + Button::OnFocus(); } void ExpandArrowView::OnBlur() { - SetSelected(false); + SchedulePaint(); + Button::OnBlur(); } std::unique_ptr<views::InkDrop> ExpandArrowView::CreateInkDrop() {
diff --git a/ui/app_list/views/expand_arrow_view.h b/ui/app_list/views/expand_arrow_view.h index 6ea9bae..fad9e9f 100644 --- a/ui/app_list/views/expand_arrow_view.h +++ b/ui/app_list/views/expand_arrow_view.h
@@ -32,9 +32,6 @@ ExpandArrowView(ContentsView* contents_view, AppListView* app_list_view); ~ExpandArrowView() override; - bool selected() { return selected_; } - void SetSelected(bool selected); - // Overridden from views::Button: void PaintButtonContents(gfx::Canvas* canvas) override; @@ -78,8 +75,6 @@ float pulse_opacity_; int pulse_radius_; - bool selected_ = false; - std::unique_ptr<gfx::SlideAnimation> animation_; // Whether the expand arrow view is pressed or not. If true, animation should
diff --git a/ui/app_list/views/folder_background_view.cc b/ui/app_list/views/folder_background_view.cc index 6fffa54d..a7e1dfe 100644 --- a/ui/app_list/views/folder_background_view.cc +++ b/ui/app_list/views/folder_background_view.cc
@@ -4,94 +4,29 @@ #include "ui/app_list/views/folder_background_view.h" -#include <algorithm> - -#include "ui/app_list/app_list_constants.h" -#include "ui/app_list/app_list_features.h" #include "ui/app_list/views/app_list_folder_view.h" -#include "ui/app_list/views/apps_container_view.h" -#include "ui/compositor/scoped_layer_animation_settings.h" -#include "ui/gfx/canvas.h" -#include "ui/gfx/transform_util.h" namespace app_list { -namespace { +FolderBackgroundView::FolderBackgroundView(AppListFolderView* folder_view) + : folder_view_(folder_view) {} -const float kFolderInkBubbleScale = 1.2f; -const int kBubbleTransitionDurationMs = 200; +FolderBackgroundView::~FolderBackgroundView() = default; -} // namespace - -FolderBackgroundView::FolderBackgroundView() - : folder_view_(NULL), show_state_(NO_BUBBLE) { - SetPaintToLayer(); - layer()->SetFillsBoundsOpaquely(false); +bool FolderBackgroundView::OnMousePressed(const ui::MouseEvent& event) { + HandleClickOrTap(); + return true; } -FolderBackgroundView::~FolderBackgroundView() { -} - -void FolderBackgroundView::UpdateFolderContainerBubble(ShowState state) { - if (show_state_ == state || - (state == HIDE_BUBBLE && show_state_ == NO_BUBBLE)) { +void FolderBackgroundView::OnGestureEvent(ui::GestureEvent* event) { + if (event->type() != ui::ET_GESTURE_TAP) return; - } - - show_state_ = state; - - // Set the initial state before the animation starts. - const gfx::Rect bounds(layer()->bounds().size()); - gfx::Transform transform = - gfx::GetScaleTransform(bounds.CenterPoint(), kFolderInkBubbleScale); - if (show_state_ == SHOW_BUBBLE) { - layer()->SetOpacity(0.0f); - layer()->SetTransform(transform); - } else { - layer()->SetOpacity(GetBubbleOpacity()); - layer()->SetTransform(gfx::Transform()); - } - - ui::ScopedLayerAnimationSettings settings(layer()->GetAnimator()); - settings.AddObserver(this); - settings.SetTransitionDuration( - base::TimeDelta::FromMilliseconds((kBubbleTransitionDurationMs))); - if (show_state_ == SHOW_BUBBLE) { - settings.SetTweenType(gfx::Tween::LINEAR_OUT_SLOW_IN); - layer()->SetOpacity(GetBubbleOpacity()); - layer()->SetTransform(gfx::Transform()); - } else { - settings.SetTweenType(gfx::Tween::FAST_OUT_LINEAR_IN); - layer()->SetOpacity(0.0f); - layer()->SetTransform(transform); - } - - SchedulePaint(); + HandleClickOrTap(); + event->SetHandled(); } -void FolderBackgroundView::OnPaint(gfx::Canvas* canvas) { - if (show_state_ == NO_BUBBLE) - return; - - // Draw ink bubble that shows the folder boundary. - cc::PaintFlags flags; - flags.setStyle(cc::PaintFlags::kFill_Style); - flags.setAntiAlias(true); - flags.setColor(FolderImage::kFolderBubbleColor); - canvas->DrawCircle(GetContentsBounds().CenterPoint(), - kFolderBackgroundBubbleRadius, flags); -} - -void FolderBackgroundView::OnImplicitAnimationsCompleted() { - // Show folder name after the ink bubble disappears. - if (show_state_ == HIDE_BUBBLE) { - static_cast<AppsContainerView*>(parent())->app_list_folder_view()-> - UpdateFolderNameVisibility(true); - } -} - -float FolderBackgroundView::GetBubbleOpacity() const { - return kFolderBubbleOpacity; +void FolderBackgroundView::HandleClickOrTap() { + folder_view_->CloseFolderPage(); } } // namespace app_list
diff --git a/ui/app_list/views/folder_background_view.h b/ui/app_list/views/folder_background_view.h index cd5a0fa..5f16274 100644 --- a/ui/app_list/views/folder_background_view.h +++ b/ui/app_list/views/folder_background_view.h
@@ -5,46 +5,32 @@ #ifndef UI_APP_LIST_VIEWS_FOLDER_BACKGROUND_VIEW_H_ #define UI_APP_LIST_VIEWS_FOLDER_BACKGROUND_VIEW_H_ -#include "base/macros.h" -#include "ui/compositor/layer_animation_observer.h" #include "ui/views/view.h" namespace app_list { class AppListFolderView; -// Draws the ink bubble indicating the boundary of the folder when user drags an -// item inside a folder. -class FolderBackgroundView : public views::View, - public ui::ImplicitAnimationObserver { +// An invisible background view of the folder in fullscreen app list. It is used +// to close folder when the user clicks/taps outside the opened folder. +class FolderBackgroundView : public views::View { public: - enum ShowState { - NO_BUBBLE, - SHOW_BUBBLE, - HIDE_BUBBLE, - }; - - FolderBackgroundView(); + explicit FolderBackgroundView(AppListFolderView* folder_view); ~FolderBackgroundView() override; - // Updates the ink bubble's ShowState. - void UpdateFolderContainerBubble(ShowState state); - void set_folder_view(AppListFolderView* folder_view) { folder_view_ = folder_view; } private: // views::View overrides: - void OnPaint(gfx::Canvas* canvas) override; + bool OnMousePressed(const ui::MouseEvent& event) override; + void OnGestureEvent(ui::GestureEvent* event) override; - // ui::ImplicitAnimationObserver overrides: - void OnImplicitAnimationsCompleted() override; - - float GetBubbleOpacity() const; + // Handles mouse click event or gesture tap event. + void HandleClickOrTap(); AppListFolderView* folder_view_; - ShowState show_state_; DISALLOW_COPY_AND_ASSIGN(FolderBackgroundView); };
diff --git a/ui/app_list/views/folder_header_view.cc b/ui/app_list/views/folder_header_view.cc index e71dd35..41860ae 100644 --- a/ui/app_list/views/folder_header_view.cc +++ b/ui/app_list/views/folder_header_view.cc
@@ -27,10 +27,8 @@ namespace { -constexpr int kPreferredWidth = 360; -constexpr int kPreferredHeight = 48; -constexpr int kBottomSeparatorHeight = 1; -constexpr int kMaxFolderNameWidthFullScreen = 236; +constexpr int kMaxFolderNameWidth = 204; +constexpr SkColor kFolderNameColor = SkColorSetARGBMacro(138, 0, 0, 0); } // namespace @@ -38,7 +36,7 @@ public: FolderNameView() { SetBorder(views::CreateEmptyBorder(1, 1, 1, 1)); } - ~FolderNameView() override {} + ~FolderNameView() override = default; void OnFocus() override { SelectAll(false); @@ -66,8 +64,7 @@ // Make folder name font size 14px. folder_name_view_->SetFontList(font_list.DeriveWithSizeDelta(-1)); folder_name_view_->SetBackgroundColor(SK_ColorTRANSPARENT); - folder_name_view_->SetTextColor(kGridTitleColor); - + folder_name_view_->SetTextColor(kFolderNameColor); folder_name_view_->set_controller(this); AddChildView(folder_name_view_); } @@ -149,10 +146,8 @@ } gfx::Size FolderHeaderView::CalculatePreferredSize() const { - const int preferred_height = kPreferredHeight + - kBottomSeparatorBottomPadding + - AppsGridView::GetTilePadding().top(); - return gfx::Size(kPreferredWidth, preferred_height); + return gfx::Size(kMaxFolderNameWidth, + folder_name_view_->GetPreferredSize().height()); } views::View* FolderHeaderView::GetFolderNameViewForTest() const { @@ -160,7 +155,7 @@ } int FolderHeaderView::GetMaxFolderNameWidth() const { - return kMaxFolderNameWidthFullScreen; + return kMaxFolderNameWidth; } base::string16 FolderHeaderView::GetElidedFolderName( @@ -205,26 +200,6 @@ return false; } -void FolderHeaderView::OnPaint(gfx::Canvas* canvas) { - views::View::OnPaint(canvas); - - gfx::Rect rect(GetContentsBounds()); - if (rect.IsEmpty() || !folder_name_visible_) - return; - - // Draw bottom separator line. - rect.Inset(kAppsGridLeftRightPadding + - (-AppsGridView::GetTilePadding().left()) + - kBottomSeparatorLeftRightPadding, - 0); - int extra_bottom_padding = - kBottomSeparatorBottomPadding + AppsGridView::GetTilePadding().top(); - rect.set_y(rect.bottom() - kBottomSeparatorHeight - extra_bottom_padding); - rect.set_height(kBottomSeparatorHeight); - SkColor color = kBottomSeparatorColor; - canvas->FillRect(rect, color); -} - void FolderHeaderView::ContentsChanged(views::Textfield* sender, const base::string16& new_contents) { // Temporarily remove from observer to ignore data change caused by us.
diff --git a/ui/app_list/views/folder_header_view.h b/ui/app_list/views/folder_header_view.h index 52a49a4..5d5cb2f 100644 --- a/ui/app_list/views/folder_header_view.h +++ b/ui/app_list/views/folder_header_view.h
@@ -68,7 +68,6 @@ // views::View overrides: void Layout() override; bool OnKeyPressed(const ui::KeyEvent& event) override; - void OnPaint(gfx::Canvas* canvas) override; // views::TextfieldController overrides: void ContentsChanged(views::Textfield* sender,
diff --git a/ui/app_list/views/page_switcher_vertical.cc b/ui/app_list/views/page_switcher.cc similarity index 66% rename from ui/app_list/views/page_switcher_vertical.cc rename to ui/app_list/views/page_switcher.cc index 05a652a..c14d7c7b 100644 --- a/ui/app_list/views/page_switcher_vertical.cc +++ b/ui/app_list/views/page_switcher.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 "ui/app_list/views/page_switcher_vertical.h" +#include "ui/app_list/views/page_switcher.h" #include <algorithm> @@ -34,26 +34,35 @@ constexpr int kNormalButtonRadius = 3; constexpr int kSelectedButtonRadius = 4; constexpr int kInkDropRadius = 8; -// The padding on top/bottom side of each button. -constexpr int kButtonPadding = 12; constexpr int kMaxButtonRadius = 8; constexpr int kPreferredButtonStripWidth = kMaxButtonRadius * 2; - -// The selected button color. -constexpr SkColor kSelectedButtonColor = SK_ColorWHITE; -// The normal button color (54% white). -constexpr SkColor kNormalColor = SkColorSetA(SK_ColorWHITE, 138); -constexpr SkColor kInkDropBaseColor = SK_ColorWHITE; -constexpr SkColor kInkDropRippleColor = SkColorSetA(kInkDropBaseColor, 20); -constexpr SkColor kInkDropHighlightColor = SkColorSetA(kInkDropBaseColor, 15); - constexpr SkScalar kStrokeWidth = SkIntToScalar(1); +// Constants for the button strip that grows vertically. +// The padding on top/bottom side of each button. +constexpr int kVerticalButtonPadding = 12; +// The selected button color. +constexpr SkColor kVerticalSelectedButtonColor = SK_ColorWHITE; +// The normal button color (54% white). +constexpr SkColor kVerticalNormalColor = SkColorSetA(SK_ColorWHITE, 138); +constexpr SkColor kVerticalInkDropBaseColor = SK_ColorWHITE; +constexpr SkColor kVerticalInkDropRippleColor = + SkColorSetA(kVerticalInkDropBaseColor, 20); +constexpr SkColor kVerticalInkDropHighlightColor = + SkColorSetA(kVerticalInkDropBaseColor, 15); + +// Constants for the button strip that grows horizontally. +// The padding on left/right side of each button. +constexpr int kHorizontalButtonPadding = 6; +// The normal button color (54% black). +constexpr SkColor kHorizontalNormalColor = SkColorSetA(SK_ColorBLACK, 138); + class PageSwitcherButton : public views::Button { public: - explicit PageSwitcherButton(views::ButtonListener* listener) - : views::Button(listener) { - SetInkDropMode(InkDropMode::ON); + PageSwitcherButton(views::ButtonListener* listener, bool vertical) + : views::Button(listener), vertical_(vertical) { + if (vertical) + SetInkDropMode(InkDropMode::ON); } ~PageSwitcherButton() override {} @@ -99,15 +108,15 @@ 2 * kMaxButtonRadius); return std::make_unique<views::FloodFillInkDropRipple>( size(), GetLocalBounds().InsetsFrom(bounds), - GetInkDropCenterBasedOnLastEvent(), kInkDropRippleColor, 1.0f); + GetInkDropCenterBasedOnLastEvent(), kVerticalInkDropRippleColor, 1.0f); } std::unique_ptr<views::InkDropHighlight> CreateInkDropHighlight() const override { return std::make_unique<views::InkDropHighlight>( gfx::PointF(GetLocalBounds().CenterPoint()), - std::make_unique<views::CircleLayerDelegate>(kInkDropHighlightColor, - kInkDropRadius)); + std::make_unique<views::CircleLayerDelegate>( + kVerticalInkDropHighlightColor, kInkDropRadius)); } void NotifyClick(const ui::Event& event) override { @@ -128,12 +137,13 @@ PaintButtonInfo BuildPaintButtonInfo() { PaintButtonInfo info; if (selected_) { - info.color = kSelectedButtonColor; + info.color = + vertical_ ? kVerticalSelectedButtonColor : kHorizontalNormalColor; info.style = cc::PaintFlags::kFill_Style; info.radius = SkIntToScalar(kSelectedButtonRadius); info.stroke_width = SkIntToScalar(0); } else { - info.color = kNormalColor; + info.color = vertical_ ? kVerticalNormalColor : kHorizontalNormalColor; info.style = cc::PaintFlags::kStroke_Style; info.radius = SkIntToScalar(kNormalButtonRadius); info.stroke_width = kStrokeWidth; @@ -157,6 +167,9 @@ // If this button is selected, set to true. By default, set to false; bool selected_ = false; + // True if the page switcher button strip should grow vertically. + const bool vertical_; + DISALLOW_COPY_AND_ASSIGN(PageSwitcherButton); }; @@ -167,13 +180,19 @@ } // namespace -PageSwitcherVertical::PageSwitcherVertical(PaginationModel* model) - : model_(model), buttons_(new views::View) { +PageSwitcher::PageSwitcher(PaginationModel* model, bool vertical) + : model_(model), buttons_(new views::View), vertical_(vertical) { SetPaintToLayer(); layer()->SetFillsBoundsOpaquely(false); - buttons_->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::kVertical, gfx::Insets(), kButtonPadding)); + if (vertical_) { + buttons_->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::kVertical, gfx::Insets(), kVerticalButtonPadding)); + } else { + buttons_->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::kHorizontal, gfx::Insets(), + kHorizontalButtonPadding)); + } AddChildView(buttons_); @@ -182,68 +201,34 @@ model_->AddObserver(this); } -PageSwitcherVertical::~PageSwitcherVertical() { - model_->RemoveObserver(this); +PageSwitcher::~PageSwitcher() { + if (model_) + model_->RemoveObserver(this); } -int PageSwitcherVertical::GetPageForPoint(const gfx::Point& point) const { - if (!buttons_->bounds().Contains(point)) - return -1; - - gfx::Point buttons_point(point); - views::View::ConvertPointToTarget(this, buttons_, &buttons_point); - - for (int i = 0; i < buttons_->child_count(); ++i) { - const views::View* button = buttons_->child_at(i); - if (button->bounds().Contains(buttons_point)) - return i; - } - - return -1; -} - -void PageSwitcherVertical::UpdateUIForDragPoint(const gfx::Point& point) { - int page = GetPageForPoint(point); - - const int button_count = buttons_->child_count(); - if (page >= 0 && page < button_count) { - PageSwitcherButton* button = - static_cast<PageSwitcherButton*>(buttons_->child_at(page)); - button->SetState(views::Button::STATE_HOVERED); - return; - } - - for (int i = 0; i < button_count; ++i) { - PageSwitcherButton* button = - static_cast<PageSwitcherButton*>(buttons_->child_at(i)); - button->SetState(views::Button::STATE_NORMAL); - } -} - -gfx::Rect PageSwitcherVertical::GetButtonsBoundsInScreen() { - return buttons_->GetBoundsInScreen(); -} - -gfx::Size PageSwitcherVertical::CalculatePreferredSize() const { +gfx::Size PageSwitcher::CalculatePreferredSize() const { // Always return a size with correct width so that container resize is not // needed when more pages are added. - return gfx::Size(kPreferredButtonStripWidth, - buttons_->GetPreferredSize().height()); + if (vertical_) { + return gfx::Size(kPreferredButtonStripWidth, + buttons_->GetPreferredSize().height()); + } + return gfx::Size(buttons_->GetPreferredSize().width(), + kPreferredButtonStripWidth); } -void PageSwitcherVertical::Layout() { +void PageSwitcher::Layout() { gfx::Rect rect(GetContentsBounds()); - - // Makes |buttons_| vertically center and horizontally fill. gfx::Size buttons_size(buttons_->GetPreferredSize()); - gfx::Rect buttons_bounds(rect.x(), - rect.CenterPoint().y() - buttons_size.height() / 2, - rect.width(), buttons_size.height()); - buttons_->SetBoundsRect(gfx::IntersectRects(rect, buttons_bounds)); + rect.ClampToCenteredSize(buttons_size); + buttons_->SetBoundsRect(rect); } -void PageSwitcherVertical::ButtonPressed(views::Button* sender, - const ui::Event& event) { +void PageSwitcher::ButtonPressed(views::Button* sender, + const ui::Event& event) { + if (!model_) + return; + for (int i = 0; i < buttons_->child_count(); ++i) { if (sender == static_cast<views::Button*>(buttons_->child_at(i))) { if (model_->selected_page() == i) @@ -258,10 +243,13 @@ } } -void PageSwitcherVertical::TotalPagesChanged() { +void PageSwitcher::TotalPagesChanged() { + if (!model_) + return; + buttons_->RemoveAllChildViews(true); for (int i = 0; i < model_->total_pages(); ++i) { - PageSwitcherButton* button = new PageSwitcherButton(this); + PageSwitcherButton* button = new PageSwitcherButton(this, vertical_); button->SetAccessibleName(l10n_util::GetStringFUTF16( IDS_APP_LIST_PAGE_SWITCHER, base::FormatNumber(i + 1), base::FormatNumber(model_->total_pages()))); @@ -272,18 +260,17 @@ Layout(); } -void PageSwitcherVertical::SelectedPageChanged(int old_selected, - int new_selected) { +void PageSwitcher::SelectedPageChanged(int old_selected, int new_selected) { if (old_selected >= 0 && old_selected < buttons_->child_count()) GetButtonByIndex(buttons_, old_selected)->SetSelected(false); if (new_selected >= 0 && new_selected < buttons_->child_count()) GetButtonByIndex(buttons_, new_selected)->SetSelected(true); } -void PageSwitcherVertical::TransitionStarted() {} +void PageSwitcher::TransitionStarted() {} -void PageSwitcherVertical::TransitionChanged() {} +void PageSwitcher::TransitionChanged() {} -void PageSwitcherVertical::TransitionEnded() {} +void PageSwitcher::TransitionEnded() {} } // namespace app_list
diff --git a/ui/app_list/views/page_switcher.h b/ui/app_list/views/page_switcher.h index 5cb6c0bc..67348355f 100644 --- a/ui/app_list/views/page_switcher.h +++ b/ui/app_list/views/page_switcher.h
@@ -5,26 +5,46 @@ #ifndef UI_APP_LIST_VIEWS_PAGE_SWITCHER_H_ #define UI_APP_LIST_VIEWS_PAGE_SWITCHER_H_ -#include "ui/views/view.h" +#include "base/macros.h" +#include "ui/app_list/pagination_model_observer.h" +#include "ui/views/controls/button/button.h" namespace app_list { -// PageSwitcher represents its underlying PaginationModel with a button strip. -// Each page in the PageinationModel has a button in the strip and when the -// button is clicked, the corresponding page becomes selected. -class PageSwitcher : public views::View { +class PaginationModel; + +// PageSwitcher represents its underlying PaginationModel with a button +// strip. Each page in the PageinationModel has a button in the strip and +// when the button is clicked, the corresponding page becomes selected. +class PageSwitcher : public views::View, + public views::ButtonListener, + public PaginationModelObserver { public: - // Returns the page index of the page switcher button under the point. If no - // page switcher button is under the point, -1 is return. |point| is in - // PageSwitcher's coordinates. - virtual int GetPageForPoint(const gfx::Point& point) const = 0; + PageSwitcher(PaginationModel* model, bool vertical); + ~PageSwitcher() override; - // Shows hover for button under the point. |point| is in PageSwitcher's - // coordinates. - virtual void UpdateUIForDragPoint(const gfx::Point& point) = 0; + // Overridden from views::View: + gfx::Size CalculatePreferredSize() const override; + void Layout() override; - // Gets the screen bounds of the buttons in the page switcher. - virtual gfx::Rect GetButtonsBoundsInScreen() = 0; + private: + // Overridden from views::ButtonListener: + void ButtonPressed(views::Button* sender, const ui::Event& event) override; + + // Overridden from PaginationModelObserver: + void TotalPagesChanged() override; + void SelectedPageChanged(int old_selected, int new_selected) override; + void TransitionStarted() override; + void TransitionChanged() override; + void TransitionEnded() override; + + PaginationModel* model_; // Owned by AppsGridView. + views::View* buttons_; // Owned by views hierarchy. + + // True if the page switcher button strip should grow vertically. + const bool vertical_; + + DISALLOW_COPY_AND_ASSIGN(PageSwitcher); }; } // namespace app_list
diff --git a/ui/app_list/views/page_switcher_vertical.h b/ui/app_list/views/page_switcher_vertical.h deleted file mode 100644 index 25650aa..0000000 --- a/ui/app_list/views/page_switcher_vertical.h +++ /dev/null
@@ -1,55 +0,0 @@ -// 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. - -#ifndef UI_APP_LIST_VIEWS_PAGE_SWITCHER_VERTICAL_H_ -#define UI_APP_LIST_VIEWS_PAGE_SWITCHER_VERTICAL_H_ - -#include "base/macros.h" -#include "ui/app_list/pagination_model_observer.h" -#include "ui/app_list/views/page_switcher.h" -#include "ui/views/controls/button/button.h" - -namespace app_list { - -class PaginationModel; - -// PageSwitcher represents its underlying PaginationModel with a button strip. -// Each page in the PageinationModel has a button in the strip and when the -// button is clicked, the corresponding page becomes selected. -class PageSwitcherVertical : public PageSwitcher, - public views::ButtonListener, - public PaginationModelObserver { - public: - explicit PageSwitcherVertical(PaginationModel* model); - ~PageSwitcherVertical() override; - - // Overridden from PageSwitcher: - int GetPageForPoint(const gfx::Point& point) const override; - void UpdateUIForDragPoint(const gfx::Point& point) override; - gfx::Rect GetButtonsBoundsInScreen() override; - - // Overridden from views::View: - gfx::Size CalculatePreferredSize() const override; - void Layout() override; - - private: - // Overridden from views::ButtonListener: - void ButtonPressed(views::Button* sender, const ui::Event& event) override; - - // Overridden from PaginationModelObserver: - void TotalPagesChanged() override; - void SelectedPageChanged(int old_selected, int new_selected) override; - void TransitionStarted() override; - void TransitionChanged() override; - void TransitionEnded() override; - - PaginationModel* model_; // Owned by AppsGridView. - views::View* buttons_; // Owned by views hierarchy. - - DISALLOW_COPY_AND_ASSIGN(PageSwitcherVertical); -}; - -} // namespace app_list - -#endif // UI_APP_LIST_VIEWS_PAGE_SWITCHER_VERTICAL_H_
diff --git a/ui/app_list/views/search_box_view.cc b/ui/app_list/views/search_box_view.cc index 6149dd05..b1b5c342 100644 --- a/ui/app_list/views/search_box_view.cc +++ b/ui/app_list/views/search_box_view.cc
@@ -172,12 +172,12 @@ } void OnFocus() override { - search_box_view_->SetSelected(true); + search_box_view_->OnOnSearchBoxFocusedChanged(); Textfield::OnFocus(); } void OnBlur() override { - search_box_view_->SetSelected(false); + search_box_view_->OnOnSearchBoxFocusedChanged(); // Clear selection and set the caret to the end of the text. ClearSelection(); Textfield::OnBlur(); @@ -547,14 +547,7 @@ return static_cast<ContentsView*>(contents_view_)->GetSelectedView(); } -void SearchBoxView::SetSelected(bool selected) { - if (selected_ == selected) - return; - selected_ = selected; - if (selected) { - // Set the ChromeVox focus to the search box. - search_box_->NotifyAccessibilityEvent(ui::AX_EVENT_SELECTION, true); - } +void SearchBoxView::OnOnSearchBoxFocusedChanged() { UpdateSearchBoxBorder(); Layout(); SchedulePaint(); @@ -726,7 +719,7 @@ } void SearchBoxView::UpdateSearchBoxBorder() { - if (selected() && !is_search_box_active()) { + if (search_box_->HasFocus() && !is_search_box_active()) { // Show a gray ring around search box to indicate that the search box is // selected. Do not show it when search box is active, because blinking // cursor already indicates that.
diff --git a/ui/app_list/views/search_box_view.h b/ui/app_list/views/search_box_view.h index 33b7aa7..435294b 100644 --- a/ui/app_list/views/search_box_view.h +++ b/ui/app_list/views/search_box_view.h
@@ -136,8 +136,7 @@ // Returns selected view in contents view. views::View* GetSelectedViewInContentsView() const; - bool selected() { return selected_; } - void SetSelected(bool selected); + void OnOnSearchBoxFocusedChanged(); private: // Updates model text and selection model with current Textfield info. @@ -218,9 +217,6 @@ // The current search box color. SkColor search_box_color_ = kDefaultSearchboxColor; - // Whether the search box is selected. - bool selected_ = false; - DISALLOW_COPY_AND_ASSIGN(SearchBoxView); };
diff --git a/ui/aura/local/window_port_local.cc b/ui/aura/local/window_port_local.cc index c9b3213..4cdb51a 100644 --- a/ui/aura/local/window_port_local.cc +++ b/ui/aura/local/window_port_local.cc
@@ -4,7 +4,7 @@ #include "ui/aura/local/window_port_local.h" -#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h" +#include "components/viz/host/host_frame_sink_manager.h" #include "ui/aura/client/cursor_client.h" #include "ui/aura/env.h" #include "ui/aura/local/layer_tree_frame_sink_local.h" @@ -171,15 +171,8 @@ void WindowPortLocal::OnSurfaceChanged(const viz::SurfaceInfo& surface_info) { DCHECK_EQ(surface_info.id().frame_sink_id(), frame_sink_id_); DCHECK_EQ(surface_info.id().local_surface_id(), local_surface_id_); - scoped_refptr<viz::SurfaceReferenceFactory> reference_factory = - aura::Env::GetInstance() - ->context_factory_private() - ->GetFrameSinkManager() - ->surface_manager() - ->reference_factory(); - window_->layer()->SetShowPrimarySurface(surface_info.id(), - window_->bounds().size(), - SK_ColorWHITE, reference_factory); + window_->layer()->SetShowPrimarySurface( + surface_info.id(), window_->bounds().size(), SK_ColorWHITE); window_->layer()->SetFallbackSurfaceId(surface_info.id()); }
diff --git a/ui/aura/mus/client_surface_embedder.cc b/ui/aura/mus/client_surface_embedder.cc index 17029d2..b22c68d 100644 --- a/ui/aura/mus/client_surface_embedder.cc +++ b/ui/aura/mus/client_surface_embedder.cc
@@ -5,7 +5,6 @@ #include "ui/aura/mus/client_surface_embedder.h" #include "base/memory/ptr_util.h" -#include "components/viz/common/surfaces/stub_surface_reference_factory.h" #include "ui/aura/window.h" #include "ui/gfx/geometry/dip_util.h" @@ -30,7 +29,6 @@ // this is the case with window decorations provided by Window Manager. // This content should appear underneath the content of the embedded client. window_->layer()->StackAtTop(surface_layer_.get()); - ref_factory_ = new viz::StubSurfaceReferenceFactory(); } ClientSurfaceEmbedder::~ClientSurfaceEmbedder() = default; @@ -38,7 +36,7 @@ void ClientSurfaceEmbedder::SetPrimarySurfaceId( const viz::SurfaceId& surface_id) { surface_layer_->SetShowPrimarySurface(surface_id, window_->bounds().size(), - SK_ColorWHITE, ref_factory_); + SK_ColorWHITE); } void ClientSurfaceEmbedder::SetFallbackSurfaceInfo(
diff --git a/ui/aura/mus/client_surface_embedder.h b/ui/aura/mus/client_surface_embedder.h index e5085af..cfbb0bc 100644 --- a/ui/aura/mus/client_surface_embedder.h +++ b/ui/aura/mus/client_surface_embedder.h
@@ -8,9 +8,7 @@ #include <memory> #include "base/macros.h" -#include "base/memory/ref_counted.h" #include "components/viz/common/surfaces/surface_info.h" -#include "components/viz/common/surfaces/surface_reference_factory.h" #include "ui/gfx/geometry/insets.h" namespace gfx { @@ -70,8 +68,6 @@ bool inject_gutter_; gfx::Insets client_area_insets_; - scoped_refptr<viz::SurfaceReferenceFactory> ref_factory_; - DISALLOW_COPY_AND_ASSIGN(ClientSurfaceEmbedder); };
diff --git a/ui/aura/mus/window_port_mus.cc b/ui/aura/mus/window_port_mus.cc index 5b4bcab..777f06e 100644 --- a/ui/aura/mus/window_port_mus.cc +++ b/ui/aura/mus/window_port_mus.cc
@@ -6,7 +6,7 @@ #include "base/memory/ptr_util.h" #include "components/viz/client/local_surface_id_provider.h" -#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h" +#include "components/viz/host/host_frame_sink_manager.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/client/transient_window_client.h" #include "ui/aura/env.h" @@ -661,18 +661,13 @@ } void WindowPortMus::OnSurfaceChanged(const viz::SurfaceInfo& surface_info) { + // TODO(fsamuel): Rename OnFirstSurfaceActivation() and set primary earlier + // based on feedback from LayerTreeFrameSinkLocal. DCHECK(!switches::IsMusHostingViz()); DCHECK_EQ(surface_info.id().frame_sink_id(), GetFrameSinkId()); DCHECK_EQ(surface_info.id().local_surface_id(), local_surface_id_); - scoped_refptr<viz::SurfaceReferenceFactory> reference_factory = - aura::Env::GetInstance() - ->context_factory_private() - ->GetFrameSinkManager() - ->surface_manager() - ->reference_factory(); - window_->layer()->SetShowPrimarySurface(surface_info.id(), - window_->bounds().size(), - SK_ColorWHITE, reference_factory); + window_->layer()->SetShowPrimarySurface( + surface_info.id(), window_->bounds().size(), SK_ColorWHITE); window_->layer()->SetFallbackSurfaceId(surface_info.id()); }
diff --git a/ui/compositor/compositor.cc b/ui/compositor/compositor.cc index 9615f95..2584b5c 100644 --- a/ui/compositor/compositor.cc +++ b/ui/compositor/compositor.cc
@@ -205,7 +205,6 @@ animation_host_->AddAnimationTimeline(animation_timeline_.get()); host_->SetRootLayer(root_web_layer_); - host_->SetFrameSinkId(frame_sink_id_); host_->SetVisible(true); if (command_line->HasSwitch(switches::kUISlowAnimations)) {
diff --git a/ui/compositor/compositor.h b/ui/compositor/compositor.h index eb56a10..e1e50227 100644 --- a/ui/compositor/compositor.h +++ b/ui/compositor/compositor.h
@@ -21,8 +21,8 @@ #include "cc/trees/layer_tree_host_client.h" #include "cc/trees/layer_tree_host_single_thread_client.h" #include "components/viz/common/frame_sinks/begin_frame_args.h" +#include "components/viz/common/surfaces/frame_sink_id.h" #include "components/viz/common/surfaces/local_surface_id.h" -#include "components/viz/common/surfaces/surface_sequence.h" #include "components/viz/host/host_frame_sink_client.h" #include "third_party/skia/include/core/SkColor.h" #include "third_party/skia/include/core/SkMatrix44.h"
diff --git a/ui/compositor/layer.cc b/ui/compositor/layer.cc index c5f6711..2a77c47 100644 --- a/ui/compositor/layer.cc +++ b/ui/compositor/layer.cc
@@ -189,8 +189,7 @@ if (surface_layer_->primary_surface_id().is_valid()) { clone->SetShowPrimarySurface(surface_layer_->primary_surface_id(), frame_size_in_dip_, - surface_layer_->background_color(), - surface_layer_->surface_reference_factory()); + surface_layer_->background_color()); } if (surface_layer_->fallback_surface_id().is_valid()) clone->SetFallbackSurfaceId(surface_layer_->fallback_surface_id()); @@ -746,16 +745,13 @@ return texture_layer_->flipped(); } -void Layer::SetShowPrimarySurface( - const viz::SurfaceId& surface_id, - const gfx::Size& frame_size_in_dip, - SkColor default_background_color, - scoped_refptr<viz::SurfaceReferenceFactory> ref_factory) { +void Layer::SetShowPrimarySurface(const viz::SurfaceId& surface_id, + const gfx::Size& frame_size_in_dip, + SkColor default_background_color) { DCHECK(type_ == LAYER_TEXTURED || type_ == LAYER_SOLID_COLOR); if (!surface_layer_) { - scoped_refptr<cc::SurfaceLayer> new_layer = - cc::SurfaceLayer::Create(ref_factory); + scoped_refptr<cc::SurfaceLayer> new_layer = cc::SurfaceLayer::Create(); SwitchToLayer(new_layer); surface_layer_ = new_layer; } @@ -767,8 +763,8 @@ RecomputeDrawsContentAndUVRect(); for (const auto& mirror : mirrors_) { - mirror->dest()->SetShowPrimarySurface( - surface_id, frame_size_in_dip, default_background_color, ref_factory); + mirror->dest()->SetShowPrimarySurface(surface_id, frame_size_in_dip, + default_background_color); } }
diff --git a/ui/compositor/layer.h b/ui/compositor/layer.h index 736c4d5..aa3712c 100644 --- a/ui/compositor/layer.h +++ b/ui/compositor/layer.h
@@ -22,7 +22,6 @@ #include "cc/layers/surface_layer.h" #include "cc/layers/texture_layer_client.h" #include "components/viz/common/resources/transferable_resource.h" -#include "components/viz/common/surfaces/sequence_surface_reference_factory.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/compositor/compositor.h" #include "ui/compositor/layer_animation_delegate.h" @@ -303,12 +302,11 @@ void SetTextureFlipped(bool flipped); bool TextureFlipped() const; + // TODO(fsamuel): Update this comment. // Begins showing content from a surface with a particular ID. - void SetShowPrimarySurface( - const viz::SurfaceId& surface_id, - const gfx::Size& frame_size_in_dip, - SkColor default_background_color, - scoped_refptr<viz::SurfaceReferenceFactory> surface_ref); + void SetShowPrimarySurface(const viz::SurfaceId& surface_id, + const gfx::Size& frame_size_in_dip, + SkColor default_background_color); // In the event that the primary surface is not yet available in the // display compositor, the fallback surface will be used.
diff --git a/ui/compositor/layer_unittest.cc b/ui/compositor/layer_unittest.cc index 1c8dd0fa..d55f320e 100644 --- a/ui/compositor/layer_unittest.cc +++ b/ui/compositor/layer_unittest.cc
@@ -33,10 +33,7 @@ #include "components/viz/common/frame_sinks/copy_output_request.h" #include "components/viz/common/frame_sinks/copy_output_result.h" #include "components/viz/common/resources/transferable_resource.h" -#include "components/viz/common/surfaces/sequence_surface_reference_factory.h" #include "components/viz/common/surfaces/surface_id.h" -#include "components/viz/common/surfaces/surface_reference_factory.h" -#include "components/viz/common/surfaces/surface_sequence.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/khronos/GLES2/gl2.h" @@ -1833,26 +1830,6 @@ EXPECT_TRUE(delegate.painted()); } -namespace { - -class TestSurfaceReferenceFactory - : public viz::SequenceSurfaceReferenceFactory { - public: - TestSurfaceReferenceFactory() = default; - - private: - ~TestSurfaceReferenceFactory() override = default; - - // cc::SequenceSurfaceReferenceFactory implementation: - void SatisfySequence(const viz::SurfaceSequence& seq) const override {} - void RequireSequence(const viz::SurfaceId& id, - const viz::SurfaceSequence& seq) const override {} - - DISALLOW_COPY_AND_ASSIGN(TestSurfaceReferenceFactory); -}; - -} // namespace - TEST_F(LayerWithDelegateTest, ExternalContent) { std::unique_ptr<Layer> root( CreateNoTextureLayer(gfx::Rect(0, 0, 1000, 1000))); @@ -1872,8 +1849,7 @@ // Showing surface content changes the underlying cc layer. before = child->cc_layer_for_testing(); child->SetShowPrimarySurface(viz::SurfaceId(), gfx::Size(10, 10), - SK_ColorWHITE, - new TestSurfaceReferenceFactory()); + SK_ColorWHITE); EXPECT_TRUE(child->cc_layer_for_testing()); EXPECT_NE(before.get(), child->cc_layer_for_testing()); @@ -1886,14 +1862,11 @@ TEST_F(LayerWithDelegateTest, ExternalContentMirroring) { std::unique_ptr<Layer> layer(CreateLayer(LAYER_SOLID_COLOR)); - scoped_refptr<viz::SurfaceReferenceFactory> reference_factory( - new TestSurfaceReferenceFactory()); viz::SurfaceId surface_id( viz::FrameSinkId(0, 1), viz::LocalSurfaceId(2, base::UnguessableToken::Create())); - layer->SetShowPrimarySurface(surface_id, gfx::Size(10, 10), SK_ColorWHITE, - reference_factory); + layer->SetShowPrimarySurface(surface_id, gfx::Size(10, 10), SK_ColorWHITE); const auto mirror = layer->Mirror(); auto* const cc_layer = mirror->cc_layer_for_testing(); @@ -1905,13 +1878,11 @@ surface_id = viz::SurfaceId(viz::FrameSinkId(1, 2), viz::LocalSurfaceId(3, base::UnguessableToken::Create())); - layer->SetShowPrimarySurface(surface_id, gfx::Size(20, 20), SK_ColorWHITE, - reference_factory); + layer->SetShowPrimarySurface(surface_id, gfx::Size(20, 20), SK_ColorWHITE); // The mirror should continue to use the same cc_layer. EXPECT_EQ(cc_layer, mirror->cc_layer_for_testing()); - layer->SetShowPrimarySurface(surface_id, gfx::Size(20, 20), SK_ColorWHITE, - reference_factory); + layer->SetShowPrimarySurface(surface_id, gfx::Size(20, 20), SK_ColorWHITE); // Surface updates propagate to the mirror. EXPECT_EQ(surface_id, surface->primary_surface_id()); @@ -1932,8 +1903,7 @@ // Showing surface content changes the underlying cc layer. scoped_refptr<cc::Layer> before = layer->cc_layer_for_testing(); layer->SetShowPrimarySurface(viz::SurfaceId(), gfx::Size(10, 10), - SK_ColorWHITE, - new TestSurfaceReferenceFactory()); + SK_ColorWHITE); EXPECT_EQ(layer->layer_grayscale(), 0.5f); EXPECT_TRUE(layer->cc_layer_for_testing()); EXPECT_NE(before.get(), layer->cc_layer_for_testing());
diff --git a/ui/events/ozone/evdev/event_auto_repeat_handler.cc b/ui/events/ozone/evdev/event_auto_repeat_handler.cc index 502d2fae4..ebfbb60d 100644 --- a/ui/events/ozone/evdev/event_auto_repeat_handler.cc +++ b/ui/events/ozone/evdev/event_auto_repeat_handler.cc
@@ -84,13 +84,10 @@ if (repeat_sequence_ != sequence) return; - // Post a task behind any pending key releases in the message loop - // FIFO. This ensures there's no spurious repeats during periods of UI - // thread jank. - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, + base::OnceClosure commit = base::BindOnce(&EventAutoRepeatHandler::OnRepeatCommit, - weak_ptr_factory_.GetWeakPtr(), repeat_sequence_)); + weak_ptr_factory_.GetWeakPtr(), repeat_sequence_); + delegate_->FlushInput(std::move(commit)); } void EventAutoRepeatHandler::OnRepeatCommit(unsigned int sequence) {
diff --git a/ui/events/ozone/evdev/event_auto_repeat_handler.h b/ui/events/ozone/evdev/event_auto_repeat_handler.h index 1be980e..37b1896 100644 --- a/ui/events/ozone/evdev/event_auto_repeat_handler.h +++ b/ui/events/ozone/evdev/event_auto_repeat_handler.h
@@ -18,6 +18,10 @@ public: class Delegate { public: + // Gives the client a chance to flush the input queue + // cancelling possible spurios auto repeat keys. + // Useful under janky situations. + virtual void FlushInput(base::OnceClosure closure) = 0; virtual void DispatchKey(unsigned int key, bool down, bool repeat,
diff --git a/ui/events/ozone/evdev/keyboard_evdev.cc b/ui/events/ozone/evdev/keyboard_evdev.cc index 58921f2d..a0f5420 100644 --- a/ui/events/ozone/evdev/keyboard_evdev.cc +++ b/ui/events/ozone/evdev/keyboard_evdev.cc
@@ -82,6 +82,13 @@ return result; } +void KeyboardEvdev::FlushInput(base::OnceClosure closure) { + // Post a task behind any pending key releases in the message loop + // FIFO. This ensures there's no spurious repeats during periods of UI + // thread jank. + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(closure)); +} + void KeyboardEvdev::UpdateModifier(int modifier_flag, bool down) { if (modifier_flag == EF_NONE) return;
diff --git a/ui/events/ozone/evdev/keyboard_evdev.h b/ui/events/ozone/evdev/keyboard_evdev.h index 1b8521a..b4ee004 100644 --- a/ui/events/ozone/evdev/keyboard_evdev.h +++ b/ui/events/ozone/evdev/keyboard_evdev.h
@@ -69,6 +69,7 @@ void UpdateCapsLockLed(); // EventAutoRepeatHandler::Delegate + void FlushInput(base::OnceClosure closure) override; void DispatchKey(unsigned int key, bool down, bool repeat,
diff --git a/ui/ozone/platform/wayland/wayland_keyboard.cc b/ui/ozone/platform/wayland/wayland_keyboard.cc index a033e2dc..570a346 100644 --- a/ui/ozone/platform/wayland/wayland_keyboard.cc +++ b/ui/ozone/platform/wayland/wayland_keyboard.cc
@@ -95,32 +95,17 @@ uint32_t key, uint32_t state) { WaylandKeyboard* keyboard = static_cast<WaylandKeyboard*>(data); + DCHECK(keyboard); + keyboard->connection_->set_serial(serial); - DomCode dom_code = - KeycodeConverter::NativeKeycodeToDomCode(key + kXkbKeycodeOffset); - if (dom_code == ui::DomCode::NONE) - return; - - uint8_t flags = keyboard->event_modifiers_.GetModifierFlags(); - DomKey dom_key; - KeyboardCode key_code; - if (!KeyboardLayoutEngineManager::GetKeyboardLayoutEngine()->Lookup( - dom_code, flags, &dom_key, &key_code)) - return; - bool down = state == WL_KEYBOARD_KEY_STATE_PRESSED; - // TODO(tonikitoo,msisov): only the two lines below if not handling repeat. - int flag = ModifierDomKeyToEventFlag(dom_key); - keyboard->UpdateModifier(flag, down); - - ui::KeyEvent event( - down ? ET_KEY_PRESSED : ET_KEY_RELEASED, key_code, dom_code, - keyboard->event_modifiers_.GetModifierFlags(), dom_key, - base::TimeTicks() + base::TimeDelta::FromMilliseconds(time)); - event.set_source_device_id(keyboard->obj_.id()); - keyboard->callback_.Run(&event); + // TODO(tonikitoo,msisov): Handler 'repeat' parameter below. + keyboard->DispatchKey( + key, down, false /*repeat*/, + base::TimeTicks() + base::TimeDelta::FromMilliseconds(time), + keyboard->obj_.id()); } void WaylandKeyboard::Modifiers(void* data, @@ -145,6 +130,35 @@ NOTIMPLEMENTED(); } +void WaylandKeyboard::DispatchKey(uint32_t key, + bool down, + bool repeat, + base::TimeTicks timestamp, + int device_id) { + DomCode dom_code = + KeycodeConverter::NativeKeycodeToDomCode(key + kXkbKeycodeOffset); + if (dom_code == ui::DomCode::NONE) + return; + + uint8_t flags = event_modifiers_.GetModifierFlags(); + DomKey dom_key; + KeyboardCode key_code; + if (!KeyboardLayoutEngineManager::GetKeyboardLayoutEngine()->Lookup( + dom_code, flags, &dom_key, &key_code)) + return; + + if (!repeat) { + int flag = ModifierDomKeyToEventFlag(dom_key); + UpdateModifier(flag, down); + } + + ui::KeyEvent event(down ? ET_KEY_PRESSED : ET_KEY_RELEASED, key_code, + dom_code, event_modifiers_.GetModifierFlags(), dom_key, + timestamp); + event.set_source_device_id(device_id); + callback_.Run(&event); +} + void WaylandKeyboard::UpdateModifier(int modifier_flag, bool down) { if (modifier_flag == EF_NONE) return;
diff --git a/ui/ozone/platform/wayland/wayland_keyboard.h b/ui/ozone/platform/wayland/wayland_keyboard.h index 727a993..70251f6d 100644 --- a/ui/ozone/platform/wayland/wayland_keyboard.h +++ b/ui/ozone/platform/wayland/wayland_keyboard.h
@@ -60,6 +60,12 @@ void UpdateModifier(int modifier_flag, bool down); + void DispatchKey(unsigned int key, + bool down, + bool repeat, + base::TimeTicks timestamp, + int device_id); + WaylandConnection* connection_ = nullptr; wl::Object<wl_keyboard> obj_; EventDispatchCallback callback_;
diff --git a/ui/views/win/hwnd_message_handler_delegate.h b/ui/views/win/hwnd_message_handler_delegate.h index 2168aed..16b1032 100644 --- a/ui/views/win/hwnd_message_handler_delegate.h +++ b/ui/views/win/hwnd_message_handler_delegate.h
@@ -5,12 +5,16 @@ #ifndef UI_VIEWS_WIN_HWND_MESSAGE_HANDLER_DELEGATE_H_ #define UI_VIEWS_WIN_HWND_MESSAGE_HANDLER_DELEGATE_H_ +#include "base/win/windows_types.h" +#include "ui/base/ui_base_types.h" +#include "ui/gfx/native_widget_types.h" #include "ui/views/views_export.h" namespace gfx { class Insets; class Path; class Point; +class Rect; class Size; } @@ -19,6 +23,8 @@ class InputMethod; class KeyEvent; class MouseEvent; +class PointerEvent; +class ScrollEvent; class TouchEvent; }
diff --git a/ui/webui/resources/cr_components/chromeos/network/network_config.js b/ui/webui/resources/cr_components/chromeos/network/network_config.js index a886a12..32371d4 100644 --- a/ui/webui/resources/cr_components/chromeos/network/network_config.js +++ b/ui/webui/resources/cr_components/chromeos/network/network_config.js
@@ -365,12 +365,13 @@ var propertiesToSet = this.getPropertiesToSet_(); if (!this.guid || this.getSource_() == CrOnc.Source.NONE) { - // New network configurations default to 'AutoConnect' unless prohibited - // by policy. + // New non VPN network configurations default to 'AutoConnect' unless + // prohibited by policy. + var prohibitAutoConnect = this.globalPolicy && + this.globalPolicy.AllowOnlyPolicyNetworksToConnect; CrOnc.setTypeProperty( propertiesToSet, 'AutoConnect', - !(this.globalPolicy && - this.globalPolicy.AllowOnlyPolicyNetworksToConnect)); + this.type != CrOnc.Type.VPN && !prohibitAutoConnect); // Create the configuration, then connect to it in the callback. this.networkingPrivate.createNetwork(