diff --git a/DEPS b/DEPS index 09dfc29..da5b85f 100644 --- a/DEPS +++ b/DEPS
@@ -133,11 +133,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': '52e620ffd0bded92a6884d42c2515487539b19e0', + 'skia_revision': '4c1ea43a79b5be7522adeac2e1e0d9ae21f26193', # 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': '0a7a6252f822ffe94ee5a8879ee34f5b2c8f7322', + 'v8_revision': '3e8a733af17a7812eba188dad612be503bd45c57', # 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. @@ -149,7 +149,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': '2995dc2a67c7d7b15ef10932757770b392dc3a5a', + 'swiftshader_revision': '45faa0849352bb3c2f6ee6fa28cf91b790607d99', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. @@ -260,7 +260,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': '579cf621f3dcd72128e60721754d0966f3249ed2', + 'dawn_revision': 'aa9d6ad09d0d43ad2a35263fb45c272f40f95937', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -772,7 +772,7 @@ }, 'src/third_party/custom_tabs_client/src': { - 'url': Var('chromium_git') + '/custom-tabs-client.git' + '@' + '51a4ff1d07d8507b934fc9d9af226a969b6c4674', + 'url': Var('chromium_git') + '/custom-tabs-client.git' + '@' + 'cea0bcafdebe711f0f83a5f05e07bc367ca18422', 'condition': 'checkout_android', }, @@ -846,7 +846,7 @@ }, 'src/third_party/glslang/src': - Var('chromium_git') + '/external/github.com/KhronosGroup/glslang.git' + '@' + '79d25ea0ce184f583e07aec9989101740e139033', + Var('chromium_git') + '/external/github.com/KhronosGroup/glslang.git' + '@' + '40c16ec0b3ad03fc170f1369a58e7bbe662d82cd', 'src/third_party/google_toolbox_for_mac/src': { 'url': Var('chromium_git') + '/external/github.com/google/google-toolbox-for-mac.git' + '@' + Var('google_toolbox_for_mac_revision'), @@ -1119,7 +1119,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + 'df42f3b1d646fef4d27aef6be1567d0ba50e0745', + Var('android_git') + '/platform/external/perfetto.git' + '@' + 'c0eace27e740347e63d7730ee9b4eba492e7ea1e', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78', @@ -1334,7 +1334,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@45209e43f286b950277bb13f64f8aefe3f1129b1', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@5b257f91fc81cfb1633b415deca73312a57947fa', 'condition': 'checkout_src_internal', },
diff --git a/build/android/apk_operations.py b/build/android/apk_operations.py index 7f69c4f..a641daf8 100755 --- a/build/android/apk_operations.py +++ b/build/android/apk_operations.py
@@ -1471,6 +1471,17 @@ mode=self.args.build_mode) +class _ManifestCommand(_Command): + name = 'dump-manifest' + description = 'Dump the android manifest from this bundle, as XML, to stdout.' + need_device_args = False + + def Run(self): + bundletool.RunBundleTool([ + 'dump', 'manifest', '--bundle', self.bundle_generation_info.bundle_path + ]) + + # Shared commands for regular APKs and app bundles. _COMMANDS = [ _DevicesCommand, @@ -1494,6 +1505,7 @@ # Commands specific to app bundles. _BUNDLE_COMMANDS = [ _BuildBundleApks, + _ManifestCommand, ]
diff --git a/build/android/docs/android_app_bundles.md b/build/android/docs/android_app_bundles.md index e9e8284..81d38be 100644 --- a/build/android/docs/android_app_bundles.md +++ b/build/android/docs/android_app_bundles.md
@@ -197,3 +197,10 @@ --apks=/tmp/BundleFoo.apks \ --adb=$(which adb) ``` + +The task of examining the manifest is simplified by running the following, +which dumps the application manifest as XML to stdout: + +```sh + build/android/gyp/bundletool.py dump-manifest +```
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index 9487da4..ca6ff2b1 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn
@@ -1590,7 +1590,6 @@ # TODO(thakis): Enable this for more platforms, https://crbug.com/926235 # Fuchsia: https://crbug.com/935588 - # iOS: https://crbug.com/936211 has_dchecks = is_debug || dcheck_always_on if (has_dchecks && !is_fuchsia) { cflags += [ "-Wextra-semi" ]
diff --git a/build/config/coverage/BUILD.gn b/build/config/coverage/BUILD.gn index 2604411..ae5435bb 100644 --- a/build/config/coverage/BUILD.gn +++ b/build/config/coverage/BUILD.gn
@@ -25,20 +25,25 @@ } } - cflags = [ - "-fprofile-instr-generate", - "-fcoverage-mapping", + # Coverage flags are only on by default when instrument all source files. + # Otherwise, coverage flags are dynamically passed to the compile command + # via the //build/toolchain/clang_code_coverage_wrapper.py script. + if (coverage_instrumentation_input_file == "") { + cflags = [ + "-fprofile-instr-generate", + "-fcoverage-mapping", - # Following experimental flags removes unused header functions from the - # coverage mapping data embedded in the test binaries, and the reduction - # of binary size enables building Chrome's large unit test targets on - # MacOS. Please refer to crbug.com/796290 for more details. - "-mllvm", - "-limited-coverage-experimental=true", - ] + # Following experimental flags removes unused header functions from the + # coverage mapping data embedded in the test binaries, and the reduction + # of binary size enables building Chrome's large unit test targets on + # MacOS. Please refer to crbug.com/796290 for more details. + "-mllvm", + "-limited-coverage-experimental=true", + ] - if (!is_win) { - cflags += [ "-fno-use-cxa-atexit" ] + if (!is_win) { + cflags += [ "-fno-use-cxa-atexit" ] + } } } }
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index 33e3372..d9d3747 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -bb61479483bd49c8db68b7c6cb72de68866b8b91 \ No newline at end of file +bccf588306321fe071f6421918793ce1ad1c0148 \ No newline at end of file
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index 86ff0a24..8916285 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -64758f33cc3d77082e41d5114ecd23d16ae0da84 \ No newline at end of file +d2912e75c6c98188ef6e209ef6168974a8ec4320 \ No newline at end of file
diff --git a/build/toolchain/clang_code_coverage_wrapper.py b/build/toolchain/clang_code_coverage_wrapper.py index 96978056..eb493bfa 100755 --- a/build/toolchain/clang_code_coverage_wrapper.py +++ b/build/toolchain/clang_code_coverage_wrapper.py
@@ -2,19 +2,11 @@ # 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. -"""Removes code coverage flags from invocations of the Clang C/C++ compiler. +"""Adds code coverage flags to the invocations of the Clang C/C++ compiler. -If the GN arg `use_clang_coverage=true`, this script will be invoked by default. -GN will add coverage instrumentation flags to almost all source files. - -This script is used to remove instrumentation flags from a subset of the source -files. By default, it will not remove flags from any files. If the option ---files-to-instrument is passed, this script will remove flags from all files -except the ones listed in --files-to-instrument. - -This script also contains hard-coded exclusion lists of files to never -instrument, indexed by target operating system. Files in these lists have their -flags removed in both modes. The OS can be selected with --target-os. +This script is used to instrument a subset of the source files, and the list of +files to instrument is specified by an input file that is passed to this script +as a command-line argument. The path to the coverage instrumentation input file should be relative to the root build directory, and the file consists of multiple lines where each line @@ -45,8 +37,6 @@ import sys # Flags used to enable coverage instrumentation. -# Flags should be listed in the same order that they are added in -# build/config/coverage/BUILD.gn _COVERAGE_FLAGS = [ '-fprofile-instr-generate', '-fcoverage-mapping', # Following experimental flags remove unused header functions from the @@ -56,41 +46,6 @@ '-mllvm', '-limited-coverage-experimental=true' ] -# Map of exclusion lists indexed by target OS. -# If no target OS is defined, or one is defined that doesn't have a specific -# entry, use the 'default' exclusion_list. Anything added to 'default' will -# apply to all platforms that don't have their own specific list. -_COVERAGE_EXCLUSION_LIST_MAP = { - 'default': [], - 'chromeos': [ - # These files caused clang to crash while compiling them. They are - # excluded pending an investigation into the underlying compiler bug. - '../../third_party/webrtc/p2p/base/p2p_transport_channel.cc', - '../../third_party/icu/source/common/uts46.cpp', - '../../third_party/icu/source/common/ucnvmbcs.cpp', - '../../base/android/android_image_reader_compat.cc', - ] -} - - -def _remove_flags_from_command(command): - # We need to remove the coverage flags for this file, but we only want to - # remove them if we see the exact sequence defined in _COVERAGE_FLAGS. - # That ensures that we only remove the flags added by GN when - # "use_clang_coverage" is true. Otherwise, we would remove flags set by - # other parts of the build system. - start_flag = _COVERAGE_FLAGS[0] - num_flags = len(_COVERAGE_FLAGS) - start_idx = 0 - try: - while True: - idx = command.index(start_flag, start_idx) - start_idx = idx + 1 - if command[idx:idx+num_flags] == _COVERAGE_FLAGS: - del command[idx:idx+num_flags] - break - except ValueError: - pass def main(): # TODO(crbug.com/898695): Make this wrapper work on Windows platform. @@ -99,23 +54,16 @@ arg_parser.add_argument( '--files-to-instrument', type=str, + required=True, help='Path to a file that contains a list of file names to instrument.') - arg_parser.add_argument( - '--target-os', - required=False, - help='The OS to compile for.') arg_parser.add_argument('args', nargs=argparse.REMAINDER) parsed_args = arg_parser.parse_args() - if (parsed_args.files_to_instrument and - not os.path.isfile(parsed_args.files_to_instrument)): + if not os.path.isfile(parsed_args.files_to_instrument): raise Exception('Path to the coverage instrumentation file: "%s" doesn\'t ' 'exist.' % parsed_args.files_to_instrument) compile_command = parsed_args.args - if not any('clang' in s for s in compile_command): - return subprocess.call(compile_command) - try: # The command is assumed to use Clang as the compiler, and the path to the # source file is behind the -c argument, and the path to the source path is @@ -131,19 +79,12 @@ raise Exception('Source file to be compiled is missing from the command.') compile_source_file = compile_command[index_dash_c + 1] - target_os = parsed_args.target_os - if target_os not in _COVERAGE_EXCLUSION_LIST_MAP: - target_os = 'default' - exclusion_list = _COVERAGE_EXCLUSION_LIST_MAP[target_os] - - if compile_source_file in exclusion_list: - _remove_flags_from_command(compile_command) - elif parsed_args.files_to_instrument: - with open(parsed_args.files_to_instrument) as f: - if compile_source_file not in f.read(): - _remove_flags_from_command(compile_command) + with open(parsed_args.files_to_instrument) as f: + if compile_source_file + '\n' in f.read(): + compile_command.extend(_COVERAGE_FLAGS) return subprocess.call(compile_command) + if __name__ == '__main__': sys.exit(main())
diff --git a/build/toolchain/gcc_toolchain.gni b/build/toolchain/gcc_toolchain.gni index 38340ad..47f18c8a 100644 --- a/build/toolchain/gcc_toolchain.gni +++ b/build/toolchain/gcc_toolchain.gni
@@ -194,48 +194,25 @@ compiler_prefix = "${analyzer_wrapper} " + compiler_prefix } - # A specific toolchain may wish to avoid coverage instrumentation, so we - # allow the global "use_clang_coverage" arg to be overridden. - if (defined(toolchain_args.use_clang_coverage)) { - toolchain_use_clang_coverage = toolchain_args.use_clang_coverage + if (defined(toolchain_args.coverage_instrumentation_input_file)) { + toolchain_coverage_instrumentation_input_file = + toolchain_args.coverage_instrumentation_input_file } else { - toolchain_use_clang_coverage = use_clang_coverage + toolchain_coverage_instrumentation_input_file = + coverage_instrumentation_input_file } - - # For a coverage build, we use the wrapper script globally so that it can - # remove coverage cflags from files that should not have them. - if (toolchain_use_clang_coverage) { + _use_clang_coverage_wrapper = + toolchain_coverage_instrumentation_input_file != "" + if (_use_clang_coverage_wrapper) { assert(!use_clang_static_analyzer, "Clang static analyzer wrapper and Clang code coverage wrapper " + "cannot be used together.") - # "coverage_instrumentation_input_file" is set in args.gn, but it can be - # overridden by a toolchain config. - if (defined(toolchain_args.coverage_instrumentation_input_file)) { - toolchain_coverage_instrumentation_input_file = - toolchain_args.coverage_instrumentation_input_file - } else { - toolchain_coverage_instrumentation_input_file = - coverage_instrumentation_input_file - } - _coverage_wrapper = rebase_path("//build/toolchain/clang_code_coverage_wrapper.py", + root_build_dir) + " --files-to-instrument=" + + rebase_path(toolchain_coverage_instrumentation_input_file, root_build_dir) - - # The wrapper needs to know what OS we target because it uses that to - # select a list of files that should not be instrumented. - _coverage_wrapper = _coverage_wrapper + "--target-os=" + target_os - - # We want to instrument everything if there is no input file set. - # If there is a file we need to give it to the wrapper script so it can - # instrument only those files. - if (toolchain_coverage_instrumentation_input_file != "") { - _coverage_wrapper = - _coverage_wrapper + " --files-to-instrument=" + - rebase_path(toolchain_coverage_instrumentation_input_file, - root_build_dir) - } compiler_prefix = "${_coverage_wrapper} " + compiler_prefix }
diff --git a/build/vs_toolchain.py b/build/vs_toolchain.py index 83b5e25d..1ab7be5 100755 --- a/build/vs_toolchain.py +++ b/build/vs_toolchain.py
@@ -367,8 +367,9 @@ to build with.""" env_version = GetVisualStudioVersion() if env_version == '2017': - # VS 2017 Update 9 (15.9.3) with 10.0.17763.132 SDK with ARM64 libraries. - toolchain_hash = 'e04af53255fe13c130e9cfde7d9ac861b9fb674a' + # VS 2017 Update 9 (15.9.3) with 10.0.17763.132 SDK, 10.0.17134 version of + # d3dcompiler_47.dll, with ARM64 libraries. + toolchain_hash = '818a152b3f1da991c1725d85be19a0f27af6bab4' # Third parties that do not have access to the canonical toolchain can map # canonical toolchain version to their own toolchain versions. toolchain_hash_mapping_key = 'GYP_MSVS_HASH_%s' % toolchain_hash
diff --git a/build/win/BUILD.gn b/build/win/BUILD.gn index febe884..ea2b3991 100644 --- a/build/win/BUILD.gn +++ b/build/win/BUILD.gn
@@ -115,55 +115,54 @@ data += [ "$clang_base_path/lib/clang/$clang_version/lib/windows/clang_rt.asan_dynamic-i386.dll" ] } } - } - if (current_cpu != "arm64") { - # The UCRT files are needed for all non-arm64 builds because - # d3dcompiler_47.dll depends on them and they are missing on some Windows - # 7 machines. - data += [ - # Universal Windows 10 CRT files - "$root_out_dir/api-ms-win-core-console-l1-1-0.dll", - "$root_out_dir/api-ms-win-core-datetime-l1-1-0.dll", - "$root_out_dir/api-ms-win-core-debug-l1-1-0.dll", - "$root_out_dir/api-ms-win-core-errorhandling-l1-1-0.dll", - "$root_out_dir/api-ms-win-core-file-l1-1-0.dll", - "$root_out_dir/api-ms-win-core-file-l1-2-0.dll", - "$root_out_dir/api-ms-win-core-file-l2-1-0.dll", - "$root_out_dir/api-ms-win-core-handle-l1-1-0.dll", - "$root_out_dir/api-ms-win-core-heap-l1-1-0.dll", - "$root_out_dir/api-ms-win-core-interlocked-l1-1-0.dll", - "$root_out_dir/api-ms-win-core-libraryloader-l1-1-0.dll", - "$root_out_dir/api-ms-win-core-localization-l1-2-0.dll", - "$root_out_dir/api-ms-win-core-memory-l1-1-0.dll", - "$root_out_dir/api-ms-win-core-namedpipe-l1-1-0.dll", - "$root_out_dir/api-ms-win-core-processenvironment-l1-1-0.dll", - "$root_out_dir/api-ms-win-core-processthreads-l1-1-0.dll", - "$root_out_dir/api-ms-win-core-processthreads-l1-1-1.dll", - "$root_out_dir/api-ms-win-core-profile-l1-1-0.dll", - "$root_out_dir/api-ms-win-core-rtlsupport-l1-1-0.dll", - "$root_out_dir/api-ms-win-core-string-l1-1-0.dll", - "$root_out_dir/api-ms-win-core-synch-l1-1-0.dll", - "$root_out_dir/api-ms-win-core-synch-l1-2-0.dll", - "$root_out_dir/api-ms-win-core-sysinfo-l1-1-0.dll", - "$root_out_dir/api-ms-win-core-timezone-l1-1-0.dll", - "$root_out_dir/api-ms-win-core-util-l1-1-0.dll", - "$root_out_dir/api-ms-win-crt-conio-l1-1-0.dll", - "$root_out_dir/api-ms-win-crt-convert-l1-1-0.dll", - "$root_out_dir/api-ms-win-crt-environment-l1-1-0.dll", - "$root_out_dir/api-ms-win-crt-filesystem-l1-1-0.dll", - "$root_out_dir/api-ms-win-crt-heap-l1-1-0.dll", - "$root_out_dir/api-ms-win-crt-locale-l1-1-0.dll", - "$root_out_dir/api-ms-win-crt-math-l1-1-0.dll", - "$root_out_dir/api-ms-win-crt-multibyte-l1-1-0.dll", - "$root_out_dir/api-ms-win-crt-private-l1-1-0.dll", - "$root_out_dir/api-ms-win-crt-process-l1-1-0.dll", - "$root_out_dir/api-ms-win-crt-runtime-l1-1-0.dll", - "$root_out_dir/api-ms-win-crt-stdio-l1-1-0.dll", - "$root_out_dir/api-ms-win-crt-string-l1-1-0.dll", - "$root_out_dir/api-ms-win-crt-time-l1-1-0.dll", - "$root_out_dir/api-ms-win-crt-utility-l1-1-0.dll", - "$root_out_dir/ucrtbase.dll", - ] + if (current_cpu != "arm64") { + data += [ + # Universal Windows 10 CRT files + "$root_out_dir/api-ms-win-core-console-l1-1-0.dll", + "$root_out_dir/api-ms-win-core-datetime-l1-1-0.dll", + "$root_out_dir/api-ms-win-core-debug-l1-1-0.dll", + "$root_out_dir/api-ms-win-core-errorhandling-l1-1-0.dll", + "$root_out_dir/api-ms-win-core-file-l1-1-0.dll", + "$root_out_dir/api-ms-win-core-file-l1-2-0.dll", + "$root_out_dir/api-ms-win-core-file-l2-1-0.dll", + "$root_out_dir/api-ms-win-core-handle-l1-1-0.dll", + "$root_out_dir/api-ms-win-core-heap-l1-1-0.dll", + "$root_out_dir/api-ms-win-core-interlocked-l1-1-0.dll", + "$root_out_dir/api-ms-win-core-libraryloader-l1-1-0.dll", + "$root_out_dir/api-ms-win-core-localization-l1-2-0.dll", + "$root_out_dir/api-ms-win-core-memory-l1-1-0.dll", + "$root_out_dir/api-ms-win-core-namedpipe-l1-1-0.dll", + "$root_out_dir/api-ms-win-core-processenvironment-l1-1-0.dll", + "$root_out_dir/api-ms-win-core-processthreads-l1-1-0.dll", + "$root_out_dir/api-ms-win-core-processthreads-l1-1-1.dll", + "$root_out_dir/api-ms-win-core-profile-l1-1-0.dll", + "$root_out_dir/api-ms-win-core-rtlsupport-l1-1-0.dll", + "$root_out_dir/api-ms-win-core-string-l1-1-0.dll", + "$root_out_dir/api-ms-win-core-synch-l1-1-0.dll", + "$root_out_dir/api-ms-win-core-synch-l1-2-0.dll", + "$root_out_dir/api-ms-win-core-sysinfo-l1-1-0.dll", + "$root_out_dir/api-ms-win-core-timezone-l1-1-0.dll", + "$root_out_dir/api-ms-win-core-util-l1-1-0.dll", + "$root_out_dir/api-ms-win-crt-conio-l1-1-0.dll", + "$root_out_dir/api-ms-win-crt-convert-l1-1-0.dll", + "$root_out_dir/api-ms-win-crt-environment-l1-1-0.dll", + "$root_out_dir/api-ms-win-crt-filesystem-l1-1-0.dll", + "$root_out_dir/api-ms-win-crt-heap-l1-1-0.dll", + "$root_out_dir/api-ms-win-crt-locale-l1-1-0.dll", + "$root_out_dir/api-ms-win-crt-math-l1-1-0.dll", + "$root_out_dir/api-ms-win-crt-multibyte-l1-1-0.dll", + "$root_out_dir/api-ms-win-crt-private-l1-1-0.dll", + "$root_out_dir/api-ms-win-crt-process-l1-1-0.dll", + "$root_out_dir/api-ms-win-crt-runtime-l1-1-0.dll", + "$root_out_dir/api-ms-win-crt-stdio-l1-1-0.dll", + "$root_out_dir/api-ms-win-crt-string-l1-1-0.dll", + "$root_out_dir/api-ms-win-crt-time-l1-1-0.dll", + "$root_out_dir/api-ms-win-crt-utility-l1-1-0.dll", + ] + if (!is_debug) { + data += [ "$root_out_dir/ucrtbase.dll" ] + } + } } } }
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java index 93a90e2..9ee3ffb 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiController.java
@@ -20,8 +20,6 @@ import org.chromium.chrome.browser.customtabs.CustomTabActivity; import org.chromium.chrome.browser.snackbar.SnackbarManager.SnackbarController; import org.chromium.chrome.browser.tab.Tab; -import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; -import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.content_public.browser.WebContents; @@ -65,12 +63,13 @@ @CalledByNative private static AutofillAssistantUiController create( - ChromeActivity activity, long nativeUiController) { + ChromeActivity activity, boolean allowTabSwitching, long nativeUiController) { assert activity != null; - return new AutofillAssistantUiController(activity, nativeUiController); + return new AutofillAssistantUiController(activity, allowTabSwitching, nativeUiController); } - private AutofillAssistantUiController(ChromeActivity activity, long nativeUiController) { + private AutofillAssistantUiController( + ChromeActivity activity, boolean allowTabSwitching, long nativeUiController) { mNativeUiController = nativeUiController; mActivity = activity; mCoordinator = new AssistantCoordinator(activity, this); @@ -80,6 +79,15 @@ protected void onObservingDifferentTab(Tab tab) { if (mWebContents == null) return; + if (!allowTabSwitching) { + if (tab == null || tab.getWebContents() != mWebContents) { + safeNativeOnFatalError( + activity.getString(R.string.autofill_assistant_give_up), + DropOutReason.TAB_CHANGED); + } + return; + } + // Get rid of any undo snackbars right away before switching tabs, to avoid // confusion. dismissSnackbar(); @@ -106,32 +114,14 @@ if (mWebContents == null) return; if (!isAttached && tab.getWebContents() == mWebContents) { + if (!allowTabSwitching) { + safeNativeStop(DropOutReason.TAB_DETACHED); + return; + } AutofillAssistantClient.fromWebContents(mWebContents).destroyUi(); } } }; - - initForCustomTab(activity); - } - - private void initForCustomTab(ChromeActivity activity) { - if (!(activity instanceof CustomTabActivity)) { - return; - } - - // Shut down Autofill Assistant when the selected tab (foreground tab) is changed. - TabModel currentTabModel = activity.getTabModelSelector().getCurrentModel(); - currentTabModel.addObserver(new EmptyTabModelObserver() { - @Override - public void didSelectTab(Tab tab, int type, int lastId) { - // Shutdown the Autofill Assistant if the user switches to another tab. - if (tab.getWebContents() != mWebContents) { - currentTabModel.removeObserver(this); - safeNativeOnFatalError(activity.getString(R.string.autofill_assistant_give_up), - DropOutReason.TAB_CHANGED); - } - } - }); } // Java => native methods.
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/TouchEventFilterView.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/TouchEventFilterView.java index 85e7b37..9f59b47 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/TouchEventFilterView.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/overlay/TouchEventFilterView.java
@@ -6,7 +6,6 @@ import android.animation.TimeInterpolator; import android.animation.ValueAnimator; -import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; @@ -526,36 +525,33 @@ /** Returns the origin of the visual viewport in this view. */ @Override - @SuppressLint("CanvasSize") protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (mCurrentState == AssistantOverlayState.HIDDEN) { return; } - canvas.drawPaint(mBackground); - int width = canvas.getWidth(); - int yTop = getVisualViewportTop(); - if (yTop > 0) { - canvas.drawRect(0, 0, width, yTop, mClear); - } + int width = getWidth(); int yBottom = getVisualViewportBottom(); - if (yBottom > 0) { - canvas.drawRect(0, yBottom, width, canvas.getHeight(), mClear); + + // Don't draw over the top or bottom bars. + if (mFullscreenManager != null) { + canvas.clipRect(0, mFullscreenManager.getTopVisibleContentOffset() - mMarginTop, width, + yBottom); } + canvas.drawPaint(mBackground); if (mCurrentState != AssistantOverlayState.PARTIAL) { return; } + int yTop = getVisualViewportTop(); int height = yBottom - yTop; - float boxesAlpha = (mCurrentBoxesAnimator != null && mCurrentBoxesAnimator.isRunning()) ? ((float) mCurrentBoxesAnimator.getAnimatedValue()) : 0f; mBoxStroke.setAlpha((int) (0xff * (1.0 - boxesAlpha))); mBoxFill.setAlpha((int) (BACKGROUND_ALPHA * boxesAlpha)); - for (RectF rect : mTouchableArea) { mDrawRect.left = rect.left * width - mPaddingPx; mDrawRect.top =
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java index a061cc76..e490163c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
@@ -160,6 +160,7 @@ public static final String AUTOFILL_ENABLE_COMPANY_NAME = "AutofillEnableCompanyName"; public static final String ADJUST_WEBAPK_INSTALLATION_SPACE = "AdjustWebApkInstallationSpace"; public static final String ANDROID_NIGHT_MODE = "AndroidNightMode"; + public static final String ANDROID_NIGHT_MODE_CCT = "AndroidNightModeCCT"; public static final String ANDROID_PAY_INTEGRATION_V1 = "AndroidPayIntegrationV1"; public static final String ANDROID_PAY_INTEGRATION_V2 = "AndroidPayIntegrationV2"; public static final String ANDROID_PAYMENT_APPS = "AndroidPaymentApps"; @@ -298,7 +299,6 @@ public static final String SERVICE_WORKER_PAYMENT_APPS = "ServiceWorkerPaymentApps"; public static final String SHOW_TRUSTED_PUBLISHER_URL = "ShowTrustedPublisherURL"; public static final String SOLE_INTEGRATION = "SoleIntegration"; - public static final String SOUND_CONTENT_SETTING = "SoundContentSetting"; public static final String SSL_COMMITTED_INTERSTITIALS = "SSLCommittedInterstitials"; public static final String SPANNABLE_INLINE_AUTOCOMPLETE = "SpannableInlineAutocomplete"; public static final String SUBRESOURCE_FILTER = "SubresourceFilter";
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contacts_picker/TopView.java b/chrome/android/java/src/org/chromium/chrome/browser/contacts_picker/TopView.java index 3b28ef2..268d110 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contacts_picker/TopView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contacts_picker/TopView.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.contacts_picker; import android.content.Context; +import android.text.style.StyleSpan; import android.util.AttributeSet; import android.view.View; import android.widget.CheckBox; @@ -13,6 +14,7 @@ import android.widget.TextView; import org.chromium.chrome.R; +import org.chromium.ui.text.SpanApplier; import java.text.NumberFormat; @@ -70,9 +72,11 @@ * @param origin The origin string to display. */ public void setSiteString(String origin) { - String siteString = mContext.getString(R.string.disclaimer_sharing_contact_details, origin); TextView explanation = findViewById(R.id.explanation); - explanation.setText(siteString); + StyleSpan boldSpan = new StyleSpan(android.graphics.Typeface.BOLD); + explanation.setText(SpanApplier.applySpans( + mContext.getString(R.string.disclaimer_sharing_contact_details, origin), + new SpanApplier.SpanInfo("<b>", "</b>", boldSpan))); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java index 28971a1..5976cf92 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java
@@ -309,7 +309,7 @@ @Override protected NightModeStateProvider createNightModeStateProvider() { - return new CustomTabNightModeStateController(getDelegate()); + return new CustomTabNightModeStateController(getDelegate(), getIntent()); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java index 94bb88c0..51ff97cd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java
@@ -141,9 +141,9 @@ public static final String EXTRA_MODULE_PACKAGE_NAME = "org.chromium.chrome.browser.customtabs.EXTRA_MODULE_PACKAGE_NAME"; - /** The resource ID of the dex file that contains the module code. */ - private static final String EXTRA_MODULE_DEX_RESOURCE_ID = - "org.chromium.chrome.browser.customtabs.EXTRA_MODULE_DEX_RESOURCE_ID"; + /** The asset name of the dex file that contains the module code. */ + private static final String EXTRA_MODULE_DEX_ASSET_NAME = + "org.chromium.chrome.browser.customtabs.EXTRA_MODULE_DEX_ASSET_NAME"; /** The class name of the module entry point. */ @VisibleForTesting @@ -196,7 +196,8 @@ @Nullable private final String mModuleManagedUrlsHeaderValue; private final boolean mHideCctHeaderOnModuleManagedUrls; - private final int mModuleDexResourceId; + @Nullable + private final String mModuleDexAssetName; private final boolean mIsIncognito; @Nullable private final List<String> mTrustedWebActivityAdditionalOrigins; @@ -334,7 +335,8 @@ String moduleClassName = IntentUtils.safeGetStringExtra(intent, EXTRA_MODULE_CLASS_NAME); if (modulePackageName != null && moduleClassName != null) { mModuleComponentName = new ComponentName(modulePackageName, moduleClassName); - mModuleDexResourceId = intent.getIntExtra(EXTRA_MODULE_DEX_RESOURCE_ID, 0); + mModuleDexAssetName = + IntentUtils.safeGetStringExtra(intent, EXTRA_MODULE_DEX_ASSET_NAME); String moduleManagedUrlsRegex = IntentUtils.safeGetStringExtra(intent, EXTRA_MODULE_MANAGED_URLS_REGEX); mModuleManagedUrlsPattern = (moduleManagedUrlsRegex != null) @@ -349,7 +351,7 @@ mModuleManagedUrlsPattern = null; mModuleManagedUrlsHeaderValue = null; mHideCctHeaderOnModuleManagedUrls = false; - mModuleDexResourceId = 0; + mModuleDexAssetName = null; } } @@ -852,8 +854,9 @@ * @return The resource identifier for the dex that contains module code. {@code 0} if no dex * resource is provided. */ - public int getModuleDexResourceId() { - return mModuleDexResourceId; + @Nullable + public String getModuleDexAssetName() { + return mModuleDexAssetName; } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabNightModeStateController.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabNightModeStateController.java index 3e7d2dcf..c7448dd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabNightModeStateController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabNightModeStateController.java
@@ -4,35 +4,64 @@ package org.chromium.chrome.browser.customtabs; +import android.content.Intent; import android.support.annotation.NonNull; +import android.support.customtabs.CustomTabsIntent; import android.support.v7.app.AppCompatDelegate; import org.chromium.chrome.browser.night_mode.NightModeStateProvider; import org.chromium.chrome.browser.util.FeatureUtilities; +import org.chromium.chrome.browser.util.IntentUtils; /** * Maintains and provides the night mode state for {@link CustomTabActivity}. */ class CustomTabNightModeStateController implements NightModeStateProvider { - CustomTabNightModeStateController(AppCompatDelegate delegate) { - if (!FeatureUtilities.isNightModeAvailable()) return; - delegate.setLocalNightMode(AppCompatDelegate.MODE_NIGHT_NO); + /** + * The color scheme requested for the CCT. Only {@link CustomTabsIntent#COLOR_SCHEME_LIGHT} + * and {@link CustomTabsIntent#COLOR_SCHEME_DARK} should be considered - fall back to the + * system status for {@link CustomTabsIntent#COLOR_SCHEME_SYSTEM} when enabled. + */ + private final int mRequestedColorScheme; + + CustomTabNightModeStateController(AppCompatDelegate delegate, Intent intent) { + if (!FeatureUtilities.isNightModeForCustomTabsAvailable()) { + mRequestedColorScheme = CustomTabsIntent.COLOR_SCHEME_SYSTEM; + return; + } + + mRequestedColorScheme = IntentUtils.safeGetIntExtra( + intent, CustomTabsIntent.EXTRA_COLOR_SCHEME, CustomTabsIntent.COLOR_SCHEME_SYSTEM); + + switch (mRequestedColorScheme) { + case CustomTabsIntent.COLOR_SCHEME_LIGHT: + delegate.setLocalNightMode(AppCompatDelegate.MODE_NIGHT_NO); + break; + case CustomTabsIntent.COLOR_SCHEME_DARK: + delegate.setLocalNightMode(AppCompatDelegate.MODE_NIGHT_YES); + break; + default: + break; + } } // NightModeStateProvider implementation. @Override public boolean isInNightMode() { - // TODO(peconn): Implement this. - return false; + switch (mRequestedColorScheme) { + case CustomTabsIntent.COLOR_SCHEME_LIGHT: + return false; + case CustomTabsIntent.COLOR_SCHEME_DARK: + return true; + default: + // TODO(peter): Adhere to system status. + return false; + } } @Override - public void addObserver(@NonNull Observer observer) { - // TODO(peconn): Implement this. - } + public void addObserver(@NonNull Observer observer) {} @Override - public void removeObserver(@NonNull Observer observer) { - // TODO(peconn): Implement this. - } + public void removeObserver(@NonNull Observer observer) {} }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java index 8557349..55d5d1ce 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java
@@ -1454,19 +1454,29 @@ CustomTabsSessionToken session, String url, String origin, int referrerPolicy, @DetachedResourceRequestMotivation int motivation); - public ModuleLoader getModuleLoader(ComponentName componentName, int resourceId) { + // TODO(amalova): remove this method as soon as it is safe to do + public ModuleLoader getModuleLoader(ComponentName componentName, int dexResourceId) { + return getModuleLoader(componentName, null); + } + + public ModuleLoader getModuleLoader(ComponentName componentName, @Nullable String assetName) { if (!ChromeFeatureList.isEnabled(ChromeFeatureList.CCT_MODULE_DEX_LOADING)) { - resourceId = 0; + assetName = null; } - if (mModuleLoader != null && - (!componentName.equals(mModuleLoader.getComponentName()) || - resourceId != mModuleLoader.getDexResourceId())) { - mModuleLoader.destroyModule(ModuleMetrics.DestructionReason.MODULE_LOADER_CHANGED); - mModuleLoader = null; + if (mModuleLoader != null) { + boolean isComponentNameChanged = + !componentName.equals(mModuleLoader.getComponentName()); + boolean isAssetNameChanged = + !TextUtils.equals(assetName, mModuleLoader.getDexAssetName()); + + if (isComponentNameChanged || isAssetNameChanged) { + mModuleLoader.destroyModule(ModuleMetrics.DestructionReason.MODULE_LOADER_CHANGED); + mModuleLoader = null; + } } - if (mModuleLoader == null) mModuleLoader = new ModuleLoader(componentName, resourceId); + if (mModuleLoader == null) mModuleLoader = new ModuleLoader(componentName, assetName); return mModuleLoader; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/DynamicModuleCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/DynamicModuleCoordinator.java index 64dbdcf..9a121c9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/DynamicModuleCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/DynamicModuleCoordinator.java
@@ -223,8 +223,8 @@ private ModuleLoader getModuleLoader() { ComponentName componentName = mIntentDataProvider.getModuleComponentName(); - int dexResourceId = mIntentDataProvider.getModuleDexResourceId(); - return mConnection.getModuleLoader(componentName, dexResourceId); + String dexAssetName = mIntentDataProvider.getModuleDexAssetName(); + return mConnection.getModuleLoader(componentName, dexAssetName); } /* package */ Context getActivityContext() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ModuleLoader.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ModuleLoader.java index 36bfd84..302f39f4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ModuleLoader.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ModuleLoader.java
@@ -49,12 +49,21 @@ /** Specifies the module package name and entry point class name. */ private final ComponentName mComponentName; - private final int mDexResourceId; + @Nullable + private final String mDexAssetName; private final DexInputStreamProvider mDexInputStreamProvider; private final DexClassLoaderProvider mDexClassLoaderProvider; private final long mModuleLastUpdateTime; private final String mModuleId; + /** @param moduleContext The context for the package to load the class from. */ + private Context mModuleContext; + + @Nullable + private ClassLoader mClassLoader; + private boolean mIsClassLoaderCreating; + private boolean mNeedsToLoadModule; + /** * Tracks the number of usages of the module. If it is no longer used, it may be destroyed, but * the time of destruction depends on the caching policy. @@ -89,20 +98,20 @@ /** * Instantiates a new {@link ModuleLoader}. * @param componentName Specifies the module package name and entry point class name. - * @param dexResourceId Identifier for the resource that contains the dex file to load the - * module from. {@code 0} if the module should not be loaded from a dex file. + * @param dexAssetName Identifier for the asset that contains the dex file to load the + * module from. {@code null} if the module should not be loaded from a dex file. */ - public ModuleLoader(ComponentName componentName, int dexResourceId) { - this(componentName, dexResourceId, new DexInputStreamProviderImpl(), + public ModuleLoader(ComponentName componentName, @Nullable String dexAssetName) { + this(componentName, dexAssetName, new DexInputStreamProviderImpl(), new DexClassLoaderProviderImpl()); } @VisibleForTesting - /* package */ ModuleLoader(ComponentName componentName, int dexResourceId, + /* package */ ModuleLoader(ComponentName componentName, @Nullable String dexAssetName, DexInputStreamProvider dexInputStreamProvider, DexClassLoaderProvider dexClassLoaderProvider) { mComponentName = componentName; - mDexResourceId = dexResourceId; + mDexAssetName = dexAssetName; mDexInputStreamProvider = dexInputStreamProvider; mDexClassLoaderProvider = dexClassLoaderProvider; String packageName = componentName.getPackageName(); @@ -122,20 +131,30 @@ } mModuleLastUpdateTime = lastUpdateTime; mModuleId = String.format("%s v%s (%s)", packageName, versionCode, versionName); + + mModuleContext = createModuleContext( + mComponentName.getPackageName(), /* resourcesOnly = */ mDexAssetName != null); } public ComponentName getComponentName() { return mComponentName; } - public int getDexResourceId() { - return mDexResourceId; + @Nullable + public String getDexAssetName() { + return mDexAssetName; } /** * If the module is not loaded yet, dynamically loads the module entry point class. */ public void loadModule() { + if (mClassLoader == null) { + mNeedsToLoadModule = true; + if (!mIsClassLoaderCreating) createClassLoader(); + return; + } + if (mIsModuleLoading) return; // If module has been already loaded all callbacks must be notified synchronously. @@ -145,9 +164,7 @@ return; } - Context moduleContext = createModuleContext( - mComponentName.getPackageName(), /* resourcesOnly = */ mDexResourceId != 0); - if (moduleContext == null) { + if (mModuleContext == null) { runAndClearCallbacks(); return; } @@ -155,9 +172,16 @@ ModuleMetrics.registerLifecycleState(ModuleMetrics.LifecycleState.NOT_LOADED); mIsModuleLoading = true; - new LoadClassTask(moduleContext) - .executeWithTaskTraits( - new TaskTraits().taskPriority(TaskPriority.USER_VISIBLE).mayBlock(true)); + new LoadClassTask().executeWithTaskTraits( + new TaskTraits().taskPriority(TaskPriority.USER_VISIBLE).mayBlock(true)); + } + + public void createClassLoader() { + if (mClassLoader != null) return; + + mIsClassLoaderCreating = true; + new ClassLoaderTask().executeWithTaskTraits( + new TaskTraits().taskPriority(TaskPriority.USER_VISIBLE).mayBlock(true)); } /** @@ -310,35 +334,19 @@ } /** - * A task for loading the module entry point class on a background thread. + * A task for creating module {@link ClassLoader}. */ - private class LoadClassTask extends AsyncTask<Class<?>> { + private class ClassLoaderTask extends AsyncTask<ClassLoader> { /** Buffer size to use while copying an input stream into the disk. */ private static final int BUFFER_SIZE = 16 * 1024; - private final Context mModuleContext; - - /** - * Constructs the task. - * @param moduleContext The context for the package to load the class from. - */ - LoadClassTask(Context moduleContext) { - mModuleContext = moduleContext; - } - @Override @Nullable - protected Class<?> doInBackground() { + protected ClassLoader doInBackground() { try { boolean loadFromDex = updateModuleDexInDiskIfNeeded(); - long entryPointLoadClassStartTime = ModuleMetrics.now(); - Class<?> clazz = - getModuleClassLoader(loadFromDex).loadClass(mComponentName.getClassName()); - ModuleMetrics.recordLoadClassTime(entryPointLoadClassStartTime); - return clazz; - } catch (ClassNotFoundException e) { - Log.e(TAG, "Could not find class %s", mComponentName.getClassName(), e); - ModuleMetrics.recordLoadResult(ModuleMetrics.LoadResult.CLASS_NOT_FOUND_EXCEPTION); + mClassLoader = getModuleClassLoader(loadFromDex); + return mClassLoader; } catch (IOException e) { Log.e(TAG, "Could not copy dex to local storage", e); ModuleMetrics.recordLoadResult( @@ -347,6 +355,15 @@ return null; } + @Override + protected void onPostExecute(ClassLoader classLoader) { + mIsClassLoaderCreating = false; + if (mNeedsToLoadModule) { + mNeedsToLoadModule = false; + loadModule(); + } + } + /** * Updates the local copy of the module dex file in disk if necessary. * @@ -360,7 +377,7 @@ String dexLastUpdateTimePref = getDexLastUpdateTimePrefName(); long localDexLastUpdateTime = preferences.getLong(dexLastUpdateTimePref, -1); - if (mDexResourceId == 0) { + if (mDexAssetName == null) { if (localDexLastUpdateTime != -1) { // The module had a dex before but now it doesn't. Clean up previous local dex. cleanUpLocalDex(); @@ -368,7 +385,7 @@ return false; } else if (localDexLastUpdateTime != mModuleLastUpdateTime) { try { - copyDexToDisk(mDexResourceId); + copyDexToDisk(mDexAssetName); preferences.edit() .putLong(dexLastUpdateTimePref, mModuleLastUpdateTime) .apply(); @@ -383,22 +400,43 @@ } /** - * Copies the dex file with the given {@code dexResourceId} from the module's context + * Copies the dex file with the given {@code dexAssetName} from the module's context * into the local storage. */ - private void copyDexToDisk(int dexResourceId) throws IOException { + private void copyDexToDisk(String dexAssetName) throws IOException { InputStream in = - mDexInputStreamProvider.createInputStream(dexResourceId, mModuleContext); + mDexInputStreamProvider.createInputStream(dexAssetName, mModuleContext); FileUtils.copyFileStreamAtomicWithBuffer(in, getDexFile(), new byte[BUFFER_SIZE]); } private ClassLoader getModuleClassLoader(boolean loadFromDex) { - if (mDexResourceId == 0 || !loadFromDex) { + if (mDexAssetName == null || !loadFromDex) { // Load directly from the APK if an extra dex file is not provided. return mModuleContext.getClassLoader(); } return mDexClassLoaderProvider.createClassLoader(getDexFile()); } + } + + /** + * A task for loading the module entry point class on a background thread. + */ + private class LoadClassTask extends AsyncTask<Class<?>> { + @Override + @Nullable + protected Class<?> doInBackground() { + if (mClassLoader == null) return null; + try { + long entryPointLoadClassStartTime = ModuleMetrics.now(); + Class<?> clazz = mClassLoader.loadClass(mComponentName.getClassName()); + ModuleMetrics.recordLoadClassTime(entryPointLoadClassStartTime); + return clazz; + } catch (ClassNotFoundException e) { + Log.e(TAG, "Could not find class %s", mComponentName.getClassName(), e); + ModuleMetrics.recordLoadResult(ModuleMetrics.LoadResult.CLASS_NOT_FOUND_EXCEPTION); + } + return null; + } @Override protected void onPostExecute(@Nullable Class<?> clazz) { @@ -496,13 +534,15 @@ */ @VisibleForTesting public interface DexInputStreamProvider { - InputStream createInputStream(int dexResourceId, Context moduleContext); + InputStream createInputStream(@Nullable String dexAssetName, Context moduleContext) + throws IOException; } private static class DexInputStreamProviderImpl implements DexInputStreamProvider { @Override - public InputStream createInputStream(int dexResourceId, Context moduleContext) { - return moduleContext.getResources().openRawResource(dexResourceId); + public InputStream createInputStream(@Nullable String dexAssetName, Context moduleContext) + throws IOException { + return moduleContext.getResources().getAssets().open(dexAssetName); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceManager.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceManager.java index 761d73c..5db3d25 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceManager.java
@@ -198,6 +198,12 @@ public static final String NIGHT_MODE_AVAILABLE_KEY = "night_mode_available"; /** + * Whether or not night mode is available for custom tabs. + * Default value is false. + */ + public static final String NIGHT_MODE_CCT_AVAILABLE_KEY = "night_mode_cct_available"; + + /** * Whether or not night mode is enabled from user settings. * Default value is false. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SiteSettingsPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SiteSettingsPreferences.java index 596d0be2..8d01430 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SiteSettingsPreferences.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/SiteSettingsPreferences.java
@@ -102,9 +102,6 @@ if (!SiteSettingsCategory.adsCategoryEnabled()) { getPreferenceScreen().removePreference(findPreference(Type.ADS)); } - if (!ChromeFeatureList.isEnabled(ChromeFeatureList.SOUND_CONTENT_SETTING)) { - getPreferenceScreen().removePreference(findPreference(Type.SOUND)); - } if (!ChromeFeatureList.isEnabled(ChromeFeatureList.CLIPBOARD_CONTENT_SETTING)) { getPreferenceScreen().removePreference(findPreference(Type.CLIPBOARD)); } @@ -156,9 +153,7 @@ if (ChromeFeatureList.isEnabled(ChromeFeatureList.GENERIC_SENSOR_EXTRA_CLASSES)) { websitePrefs.add(Type.SENSORS); } - if (ChromeFeatureList.isEnabled(ChromeFeatureList.SOUND_CONTENT_SETTING)) { - websitePrefs.add(Type.SOUND); - } + websitePrefs.add(Type.SOUND); websitePrefs.add(Type.USB); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/util/FeatureUtilities.java b/chrome/android/java/src/org/chromium/chrome/browser/util/FeatureUtilities.java index 17912b7..45c28145 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/util/FeatureUtilities.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/util/FeatureUtilities.java
@@ -78,6 +78,7 @@ private static Boolean sIsAdaptiveToolbarEnabled; private static Boolean sShouldInflateToolbarOnBackgroundThread; private static Boolean sIsNightModeAvailable; + private static Boolean sIsNightModeForCustomTabsAvailable; private static Boolean sShouldPrioritizeBootstrapTasks; private static Boolean sIsTabGroupsAndroidEnabled; @@ -196,6 +197,7 @@ cacheAdaptiveToolbarEnabled(); cacheInflateToolbarOnBackgroundThread(); cacheNightModeAvailable(); + cacheNightModeForCustomTabsAvailable(); cacheDownloadAutoResumptionEnabledInNative(); cachePrioritizeBootstrapTasks(); @@ -428,6 +430,38 @@ } /** + * Cache whether or not night mode is available for custom tabs (i.e. night mode experiment is + * enabled), so the value is immediately available on next start-up. + */ + public static void cacheNightModeForCustomTabsAvailable() { + ChromePreferenceManager.getInstance().writeBoolean( + ChromePreferenceManager.NIGHT_MODE_CCT_AVAILABLE_KEY, + ChromeFeatureList.isEnabled(ChromeFeatureList.ANDROID_NIGHT_MODE_CCT)); + } + + /** + * @return Whether or not night mode experiment is enabled (i.e. night mode experiment is + * enabled) for custom tabs. + */ + public static boolean isNightModeForCustomTabsAvailable() { + if (sIsNightModeForCustomTabsAvailable == null) { + ChromePreferenceManager prefManager = ChromePreferenceManager.getInstance(); + + sIsNightModeForCustomTabsAvailable = prefManager.readBoolean( + ChromePreferenceManager.NIGHT_MODE_CCT_AVAILABLE_KEY, true); + } + return sIsNightModeForCustomTabsAvailable; + } + + /** + * Toggles whether the night mode for custom tabs experiment is enabled. Must only be used for + * testing. Should be reset back to NULL after the test has finished. + */ + public static void setNightModeForCustomTabsAvailableForTesting(Boolean available) { + sIsNightModeForCustomTabsAvailable = available; + } + + /** * Cache whether or not command line is enabled on non-rooted devices. */ private static void cacheCommandLineOnNonRootedEnabled() {
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd index 2d51c8a6..68e8433 100644 --- a/chrome/android/java/strings/android_chrome_strings.grd +++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -3649,7 +3649,7 @@ other { (+ # more)}} </message> <message name="IDS_DISCLAIMER_SHARING_CONTACT_DETAILS" desc="Label describing what will happen with the contact details that are being shared."> - The contacts you select below will be shared with the website <ph name="SITE">%1$s<ex>https://www.google.com</ex></ph>. + The contacts you select below will be shared with the website <ph name="BEGIN_BOLD"><b></ph><ph name="SITE">%1$s<ex>https://www.google.com</ex></ph><ph name="END_BOLD"></b></ph>. </message> <!-- Photo Picker strings -->
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contacts_picker/ContactsPickerDialogTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contacts_picker/ContactsPickerDialogTest.java index 9831abb..14bb5344 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contacts_picker/ContactsPickerDialogTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contacts_picker/ContactsPickerDialogTest.java
@@ -240,7 +240,7 @@ Assert.assertNotNull(topView); TextView explanation = (TextView) topView.findViewById(R.id.explanation); Assert.assertNotNull(explanation); - Assert.assertEquals(explanation.getText(), + Assert.assertEquals(explanation.getText().toString(), "The contacts you select below will be shared with the website example.com."); dismissDialog();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java index 52e5864b..567680b 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabActivityTest.java
@@ -108,6 +108,7 @@ import org.chromium.chrome.browser.test.ScreenShooter; import org.chromium.chrome.browser.toolbar.top.CustomTabToolbar; import org.chromium.chrome.browser.util.ColorUtils; +import org.chromium.chrome.browser.util.FeatureUtilities; import org.chromium.chrome.test.ChromeActivityTestRule; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.util.ChromeTabUtils; @@ -2309,6 +2310,46 @@ } @Test + @SmallTest + public void testLaunchCustomTabWithColorSchemeDark() throws Exception { + FeatureUtilities.setNightModeForCustomTabsAvailableForTesting(true); + + Intent intent = createMinimalCustomTabIntent(); + addColorSchemeToIntent(intent, CustomTabsIntent.COLOR_SCHEME_DARK); + + mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent); + + final CustomTabActivity cctActivity = mCustomTabActivityTestRule.getActivity(); + + Assert.assertNotNull(cctActivity.getNightModeStateProvider()); + Assert.assertTrue(cctActivity.getNightModeStateProvider().isInNightMode()); + + FeatureUtilities.setNightModeForCustomTabsAvailableForTesting(null); + } + + @Test + @SmallTest + public void testLaunchCustomTabWithColorSchemeLight() throws Exception { + FeatureUtilities.setNightModeForCustomTabsAvailableForTesting(true); + + Intent intent = createMinimalCustomTabIntent(); + addColorSchemeToIntent(intent, CustomTabsIntent.COLOR_SCHEME_LIGHT); + + mCustomTabActivityTestRule.startCustomTabActivityWithIntent(intent); + + final CustomTabActivity cctActivity = mCustomTabActivityTestRule.getActivity(); + + Assert.assertNotNull(cctActivity.getNightModeStateProvider()); + Assert.assertFalse(cctActivity.getNightModeStateProvider().isInNightMode()); + + FeatureUtilities.setNightModeForCustomTabsAvailableForTesting(null); + } + + private void addColorSchemeToIntent(Intent intent, int colorScheme) { + intent.putExtra(CustomTabsIntent.EXTRA_COLOR_SCHEME, colorScheme); + } + + @Test @MediumTest public void testLaunchIncognitoCustomTabForPaymentRequest() throws Exception { Intent intent = createMinimalCustomTabIntent();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/dynamicmodule/CustomTabsDynamicModuleLoaderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/dynamicmodule/CustomTabsDynamicModuleLoaderTest.java index 7ea1b77..7a6d65a1 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/dynamicmodule/CustomTabsDynamicModuleLoaderTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/dynamicmodule/CustomTabsDynamicModuleLoaderTest.java
@@ -13,7 +13,7 @@ import static org.chromium.base.ThreadUtils.runOnUiThreadBlocking; import static org.chromium.chrome.browser.customtabs.dynamicmodule.CustomTabsDynamicModuleTestUtils.FAKE_CLASS_LOADER_PROVIDER; import static org.chromium.chrome.browser.customtabs.dynamicmodule.CustomTabsDynamicModuleTestUtils.FAKE_MODULE_COMPONENT_NAME; -import static org.chromium.chrome.browser.customtabs.dynamicmodule.CustomTabsDynamicModuleTestUtils.FAKE_MODULE_DEX_RESOURCE_ID; +import static org.chromium.chrome.browser.customtabs.dynamicmodule.CustomTabsDynamicModuleTestUtils.FAKE_MODULE_DEX_ASSET_NAME; import android.support.test.filters.SmallTest; @@ -53,12 +53,12 @@ public void setUp() throws Exception { LibraryLoader.getInstance().ensureInitialized(LibraryProcessType.PROCESS_BROWSER); mDexInputStreamProvider = new FakeDexInputStreamProvider(); - mModuleLoaderFromApk = new ModuleLoader(FAKE_MODULE_COMPONENT_NAME, /* dexResourceId = */ 0, - mDexInputStreamProvider, FAKE_CLASS_LOADER_PROVIDER); + mModuleLoaderFromApk = new ModuleLoader(FAKE_MODULE_COMPONENT_NAME, + /* dexAssetName = */ null, mDexInputStreamProvider, FAKE_CLASS_LOADER_PROVIDER); mModuleLoaderFromDex = new ModuleLoader(FAKE_MODULE_COMPONENT_NAME, - FAKE_MODULE_DEX_RESOURCE_ID, mDexInputStreamProvider, FAKE_CLASS_LOADER_PROVIDER); + FAKE_MODULE_DEX_ASSET_NAME, mDexInputStreamProvider, FAKE_CLASS_LOADER_PROVIDER); mModuleLoaderFromDex2 = new ModuleLoader(FAKE_MODULE_COMPONENT_NAME, - FAKE_MODULE_DEX_RESOURCE_ID, mDexInputStreamProvider, FAKE_CLASS_LOADER_PROVIDER); + FAKE_MODULE_DEX_ASSET_NAME, mDexInputStreamProvider, FAKE_CLASS_LOADER_PROVIDER); } @After
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/dynamicmodule/CustomTabsDynamicModuleTestUtils.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/dynamicmodule/CustomTabsDynamicModuleTestUtils.java index bf9158c..ff4bca4 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/dynamicmodule/CustomTabsDynamicModuleTestUtils.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/dynamicmodule/CustomTabsDynamicModuleTestUtils.java
@@ -48,9 +48,9 @@ FAKE_MODULE_PACKAGE_NAME, FAKE_MODULE_CLASS_NAME); /** - * A resource ID used to load {@link #FAKE_MODULE_DEX}. + * A asset name used to load {@link #FAKE_MODULE_DEX}. */ - /* package */ final static int FAKE_MODULE_DEX_RESOURCE_ID = 42; + /* package */ final static String FAKE_MODULE_DEX_ASSET_NAME = "R.strings.forty_two"; /** * A fake "dex file" that consists of couple of bytes. @@ -307,9 +307,9 @@ private int mCallCount; @Override - public InputStream createInputStream(int dexResourceId, Context moduleContext) { - if (dexResourceId != FAKE_MODULE_DEX_RESOURCE_ID) { - throw new RuntimeException("Unknown resource ID: " + dexResourceId); + public InputStream createInputStream(@Nullable String dexAssetName, Context moduleContext) { + if (!FAKE_MODULE_DEX_ASSET_NAME.equals(dexAssetName)) { + throw new RuntimeException("Unknown resource ID: " + dexAssetName); } mCallCount++;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadMediaParserTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadMediaParserTest.java index f1ead97..dfa01d29 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadMediaParserTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadMediaParserTest.java
@@ -14,12 +14,12 @@ import org.junit.runner.RunWith; import org.chromium.base.ThreadUtils; -import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.MinAndroidSdkLevel; import org.chromium.base.test.util.Restriction; import org.chromium.base.test.util.UrlUtils; import org.chromium.chrome.browser.test.ChromeBrowserTestRule; +import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.content_public.browser.test.util.Criteria; import org.chromium.content_public.browser.test.util.CriteriaHelper; import org.chromium.ui.test.util.UiRestriction; @@ -36,7 +36,7 @@ * * Because each media parser call may perform multiple process and thread hops, it can be slow. */ -@RunWith(BaseJUnit4ClassRunner.class) +@RunWith(ChromeJUnit4ClassRunner.class) public class DownloadMediaParserTest { private static final long MAX_MEDIA_PARSER_POLL_TIME_MS = 10000; private static final long MEDIA_PARSER_POLL_INTERVAL_MS = 1000;
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 760a498..902d34f 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -1976,6 +1976,12 @@ <message name="IDS_AMBIENT_BADGE_INSTALL" desc="String for the ambient badge promoting an app installation"> Add <ph name="APP_NAME">$1<ex>Google Maps</ex></ph> to Home screen </message> + <message name="IDS_AMBIENT_BADGE_INSTALL_ALTERNATIVE" desc="String for the ambient badge promoting an app installation. Alternative used for experimentation."> + Install <ph name="APP_NAME">$1<ex>Google Maps</ex></ph> + </message> + <message name="IDS_AMBIENT_BADGE_INSTALL_ALTERNATIVE_NO_DOWNLOAD_REQUIRED" desc="String for the ambient badge promoting an app installation. Alternative used for experimentation."> + Install <ph name="APP_NAME">$1<ex>Google Maps</ex></ph> (no download required) + </message> </if> <!-- Desktop omnibox PWA install icon -->
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 34e3132..2cf51abe 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -1891,6 +1891,7 @@ "//components/keyed_service/content", "//components/language/content/browser", "//components/language/core/browser", + "//components/language/core/common", "//components/leveldb_proto/content:factory", "//components/live_tab_count_metrics", "//components/metrics:call_stack_profile_collector", @@ -1936,6 +1937,7 @@ "//components/renderer_context_menu", "//components/resources", "//components/safe_search_api", + "//components/safe_search_api:safe_search_client", "//components/search", "//components/search_engines", "//components/search_provider_logos",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 953ca53..1ce55a3b 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -1128,9 +1128,6 @@ {"enable-webrtc-stun-origin", flag_descriptions::kWebrtcStunOriginName, flag_descriptions::kWebrtcStunOriginDescription, kOsAll, SINGLE_VALUE_TYPE(switches::kEnableWebRtcStunOrigin)}, - {"WebRtcUseEchoCanceller3", flag_descriptions::kWebrtcEchoCanceller3Name, - flag_descriptions::kWebrtcEchoCanceller3Description, kOsAll, - FEATURE_VALUE_TYPE(features::kWebRtcUseEchoCanceller3)}, {"enable-webrtc-hybrid-agc", flag_descriptions::kWebrtcHybridAgcName, flag_descriptions::kWebrtcHybridAgcDescription, kOsAll, FEATURE_VALUE_TYPE(features::kWebRtcHybridAgc)}, @@ -3047,10 +3044,6 @@ FEATURE_VALUE_TYPE(features::kRemoveNtpFakebox)}, #endif // !defined(OS_ANDROID) - {"sound-content-setting", flag_descriptions::kSoundContentSettingName, - flag_descriptions::kSoundContentSettingDescription, kOsAll, - FEATURE_VALUE_TYPE(features::kSoundContentSetting)}, - #if defined(DCHECK_IS_CONFIGURABLE) {"dcheck-is-fatal", flag_descriptions::kDcheckIsFatalName, flag_descriptions::kDcheckIsFatalDescription, kOsWin,
diff --git a/chrome/browser/android/autofill_assistant/ui_controller_android.cc b/chrome/browser/android/autofill_assistant/ui_controller_android.cc index 65c52b1..9ae616f 100644 --- a/chrome/browser/android/autofill_assistant/ui_controller_android.cc +++ b/chrome/browser/android/autofill_assistant/ui_controller_android.cc
@@ -26,6 +26,7 @@ #include "components/autofill/core/browser/autofill_profile.h" #include "components/autofill/core/browser/credit_card.h" #include "components/autofill_assistant/browser/controller.h" +#include "components/autofill_assistant/browser/features.h" #include "components/autofill_assistant/browser/metrics.h" #include "components/autofill_assistant/browser/rectf.h" #include "components/signin/core/browser/account_info.h" @@ -79,7 +80,10 @@ payment_request_delegate_(this), weak_ptr_factory_(this) { java_object_ = Java_AutofillAssistantUiController_create( - env, jactivity, reinterpret_cast<intptr_t>(this)); + env, jactivity, + /* allowTabSwitching= */ + base::FeatureList::IsEnabled(features::kAutofillAssistantChromeEntry), + reinterpret_cast<intptr_t>(this)); // Register overlay_delegate_ as delegate for the overlay. Java_AssistantOverlayModel_setDelegate(env, GetOverlayModel(),
diff --git a/chrome/browser/android/chrome_feature_list.cc b/chrome/browser/android/chrome_feature_list.cc index cd54389..a72e0d7 100644 --- a/chrome/browser/android/chrome_feature_list.cc +++ b/chrome/browser/android/chrome_feature_list.cc
@@ -80,7 +80,6 @@ &features::kPrioritizeBootstrapTasks, &features::kServiceWorkerPaymentApps, &features::kShowTrustedPublisherURL, - &features::kSoundContentSetting, &features::kSSLCommittedInterstitials, &features::kUserActivationV2, &features::kWebAuth, @@ -91,6 +90,7 @@ &kAllowNewIncognitoTabIntents, &kAllowRemoteContextForNotifications, &kAndroidNightMode, + &kAndroidNightModeCCT, &kAndroidPayIntegrationV1, &kAndroidPayIntegrationV2, &kAndroidPaymentApps, @@ -222,6 +222,9 @@ const base::Feature kAndroidNightMode{"AndroidNightMode", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kAndroidNightModeCCT{"AndroidNightModeCCT", + base::FEATURE_ENABLED_BY_DEFAULT}; + // TODO(rouslan): Remove this. const base::Feature kAndroidPayIntegrationV1{"AndroidPayIntegrationV1", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/chrome/browser/android/chrome_feature_list.h b/chrome/browser/android/chrome_feature_list.h index 1c0ba3e..d7ef866 100644 --- a/chrome/browser/android/chrome_feature_list.h +++ b/chrome/browser/android/chrome_feature_list.h
@@ -16,6 +16,7 @@ extern const base::Feature kAllowNewIncognitoTabIntents; extern const base::Feature kAllowRemoteContextForNotifications; extern const base::Feature kAndroidNightMode; +extern const base::Feature kAndroidNightModeCCT; extern const base::Feature kAndroidPayIntegrationV1; extern const base::Feature kAndroidPayIntegrationV2; extern const base::Feature kAndroidPaymentApps;
diff --git a/chrome/browser/android/preferences/pref_service_bridge.cc b/chrome/browser/android/preferences/pref_service_bridge.cc index 165290f3..bc9712b 100644 --- a/chrome/browser/android/preferences/pref_service_bridge.cc +++ b/chrome/browser/android/preferences/pref_service_bridge.cc
@@ -42,6 +42,7 @@ #include "components/content_settings/core/common/content_settings_pattern.h" #include "components/content_settings/core/common/pref_names.h" #include "components/language/core/browser/pref_names.h" +#include "components/language/core/common/language_util.h" #include "components/metrics/metrics_pref_names.h" #include "components/password_manager/core/common/password_manager_pref_names.h" #include "components/prefs/pref_service.h" @@ -50,7 +51,6 @@ #include "components/strings/grit/components_locale_settings.h" #include "components/translate/core/browser/translate_pref_names.h" #include "components/translate/core/browser/translate_prefs.h" -#include "components/translate/core/common/translate_util.h" #include "components/version_info/version_info.h" #include "components/web_resource/web_resource_pref_names.h" #include "content/public/browser/browser_thread.h" @@ -1204,12 +1204,12 @@ translate_prefs->GetLanguageInfoList( app_locale, translate_prefs->IsTranslateAllowedByPolicy(), &languages); - translate::ToTranslateLanguageSynonym(&app_locale); + language::ToTranslateLanguageSynonym(&app_locale); for (const auto& info : languages) { // If the language comes from the same language family as the app locale, // translate for this language won't be supported on this device. std::string lang_code = info.code; - translate::ToTranslateLanguageSynonym(&lang_code); + language::ToTranslateLanguageSynonym(&lang_code); bool supports_translate = info.supports_translate && lang_code != app_locale; @@ -1284,11 +1284,11 @@ ChromeTranslateClient::CreateTranslatePrefs(GetPrefService()); std::string language_code(ConvertJavaStringToUTF8(env, language)); - translate::ToTranslateLanguageSynonym(&language_code); + language::ToTranslateLanguageSynonym(&language_code); // Application language is always blocked. std::string app_locale = g_browser_process->GetApplicationLocale(); - translate::ToTranslateLanguageSynonym(&app_locale); + language::ToTranslateLanguageSynonym(&app_locale); if (app_locale == language_code) return true;
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index a439d19..9b5206c 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -2587,6 +2587,7 @@ ":arc_test_support", ":attestation_proto", ":test_support", + ":time_limit_tests", ":user_activity_event_proto", "//ash", "//ash/system/message_center/arc:test_support", @@ -2757,3 +2758,37 @@ seed_corpus = "smb_client/fuzzer_data/smb_url_corpus" } + +# Build target related to the time limit processor tests. Must be kept +# separated from the other unit tests because it is the only one allowed +# to use the :protobuf_full dependency. +source_set("time_limit_tests") { + testonly = true + check_includes = false + + sources = [ + "child_accounts/time_limit_consistency_test/consistency_golden_converter.cc", + "child_accounts/time_limit_consistency_test/consistency_golden_converter_unittest.cc", + "child_accounts/time_limit_consistency_test/consistency_golden_loader.cc", + "child_accounts/time_limit_consistency_test/consistency_golden_loader_unittest.cc", + ] + deps = [ + ":chromeos", + ":consistency_golden_proto", + "//base", + "//testing/gmock", + "//testing/gtest", + "//third_party/protobuf:protobuf_full", + ] + data = [ + "child_accounts/time_limit_consistency_test/goldens/", + "child_accounts/time_limit_consistency_test/test_goldens/", + ] +} + +proto_library("consistency_golden_proto") { + sources = [ + "child_accounts/time_limit_consistency_test/goldens/consistency_golden.proto", + ] + generate_python = false +}
diff --git a/chrome/browser/chromeos/arc/arc_session_manager_browsertest.cc b/chrome/browser/chromeos/arc/arc_session_manager_browsertest.cc index 1852a9d..d5e7303 100644 --- a/chrome/browser/chromeos/arc/arc_session_manager_browsertest.cc +++ b/chrome/browser/chromeos/arc/arc_session_manager_browsertest.cc
@@ -20,6 +20,7 @@ #include "chrome/browser/chromeos/arc/arc_session_manager.h" #include "chrome/browser/chromeos/arc/arc_util.h" #include "chrome/browser/chromeos/arc/test/arc_data_removed_waiter.h" +#include "chrome/browser/chromeos/login/test/local_policy_test_server_mixin.h" #include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" @@ -28,7 +29,6 @@ #include "chrome/browser/extensions/extension_tab_util.h" #include "chrome/browser/policy/profile_policy_connector.h" #include "chrome/browser/policy/profile_policy_connector_factory.h" -#include "chrome/browser/policy/test/local_policy_test_server.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/signin/identity_test_environment_profile_adaptor.h" #include "chrome/test/base/in_process_browser_test.h" @@ -100,31 +100,20 @@ DISALLOW_COPY_AND_ASSIGN(ArcPlayStoreDisabledWaiter); }; -class ArcSessionManagerTest : public InProcessBrowserTest { +class ArcSessionManagerTest : public chromeos::MixinBasedInProcessBrowserTest { protected: ArcSessionManagerTest() {} - // InProcessBrowserTest: + // MixinBasedInProcessBrowserTest: ~ArcSessionManagerTest() override {} void SetUpCommandLine(base::CommandLine* command_line) override { + chromeos::MixinBasedInProcessBrowserTest::SetUpCommandLine(command_line); arc::SetArcAvailableCommandLineForTesting(command_line); } - void SetUpInProcessBrowserTestFixture() override { - // Start test device management server. - test_server_.reset(new policy::LocalPolicyTestServer()); - ASSERT_TRUE(test_server_->Start()); - - // Specify device management server URL. - std::string url = test_server_->GetServiceURL().spec(); - base::CommandLine* const command_line = - base::CommandLine::ForCurrentProcess(); - command_line->AppendSwitchASCII(policy::switches::kDeviceManagementUrl, - url); - } - void SetUpOnMainThread() override { + chromeos::MixinBasedInProcessBrowserTest::SetUpOnMainThread(); user_manager_enabler_ = std::make_unique<user_manager::ScopedUserManager>( std::make_unique<chromeos::FakeChromeUserManager>()); // Init ArcSessionManager for testing. @@ -188,8 +177,8 @@ profile_.reset(); base::RunLoop().RunUntilIdle(); user_manager_enabler_.reset(); - test_server_.reset(); chromeos::ProfileHelper::SetAlwaysReturnPrimaryUserForTesting(false); + chromeos::MixinBasedInProcessBrowserTest::TearDownOnMainThread(); } chromeos::FakeChromeUserManager* GetFakeUserManager() const { @@ -214,7 +203,7 @@ } private: - std::unique_ptr<policy::LocalPolicyTestServer> test_server_; + chromeos::LocalPolicyTestServerMixin local_policy_mixin_{&mixin_host_}; std::unique_ptr<user_manager::ScopedUserManager> user_manager_enabler_; std::unique_ptr<IdentityTestEnvironmentProfileAdaptor> identity_test_environment_adaptor_;
diff --git a/chrome/browser/chromeos/child_accounts/time_limit_consistency_test/consistency_golden_converter.cc b/chrome/browser/chromeos/child_accounts/time_limit_consistency_test/consistency_golden_converter.cc new file mode 100644 index 0000000..802d286 --- /dev/null +++ b/chrome/browser/chromeos/child_accounts/time_limit_consistency_test/consistency_golden_converter.cc
@@ -0,0 +1,110 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/child_accounts/time_limit_consistency_test/consistency_golden_converter.h" + +#include "base/time/time.h" +#include "base/values.h" +#include "chrome/browser/chromeos/child_accounts/time_limit_test_utils.h" + +namespace chromeos { + +namespace utils = time_limit_test_utils; + +namespace time_limit_consistency { +namespace { + +// Converts a ActivePolicies object from the time limit processor to a +// ConsistencyGoldenPolicy used by the goldens. +ConsistencyGoldenPolicy ConvertProcessorPolicyToGoldenPolicy( + usage_time_limit::ActivePolicies processor_policy) { + switch (processor_policy) { + case usage_time_limit::ActivePolicies::kOverride: + return OVERRIDE; + case usage_time_limit::ActivePolicies::kFixedLimit: + return FIXED_LIMIT; + case usage_time_limit::ActivePolicies::kUsageLimit: + return USAGE_LIMIT; + case usage_time_limit::ActivePolicies::kNoActivePolicy: + return NO_ACTIVE_POLICY; + } + + NOTREACHED(); + return UNSPECIFIED_POLICY; +} + +// Converts the representation of a day of week used by the goldens to the one +// used by the time limit processor. +const char* ConvertGoldenDayToProcessorDay(ConsistencyGoldenEffectiveDay day) { + switch (day) { + case MONDAY: + return utils::kMonday; + case TUESDAY: + return utils::kTuesday; + case WEDNESDAY: + return utils::kWednesday; + case THURSDAY: + return utils::kThursday; + case FRIDAY: + return utils::kFriday; + case SATURDAY: + return utils::kSaturday; + case SUNDAY: + return utils::kSunday; + default: + NOTREACHED(); + return nullptr; + } +} + +} // namespace + +std::unique_ptr<base::DictionaryValue> ConvertGoldenInputToProcessorInput( + ConsistencyGoldenInput input) { + // Random date representing the last time the policies were updated, + // since the tests won't take this into account for now. + base::Time last_updated = utils::TimeFromString("1 Jan 2018 10:00 GMT+0300"); + + std::unique_ptr<base::DictionaryValue> policy = + utils::CreateTimeLimitPolicy(base::TimeDelta::FromHours(6)); + + /* Begin Window Limits data */ + + if (input.window_limits_size() > 0) { + for (ConsistencyGoldenWindowLimitEntry window_limit : + input.window_limits()) { + utils::AddTimeWindowLimit( + policy.get(), + ConvertGoldenDayToProcessorDay(window_limit.effective_day()), + utils::CreateTime(window_limit.starts_at().hour(), + window_limit.starts_at().minute()), + utils::CreateTime(window_limit.ends_at().hour(), + window_limit.ends_at().minute()), + last_updated); + } + } + + /* End Window Limits data */ + + return policy; +} + +ConsistencyGoldenOutput ConvertProcessorOutputToGoldenOutput( + usage_time_limit::State state) { + ConsistencyGoldenOutput golden_output; + + golden_output.set_is_locked(state.is_locked); + golden_output.set_active_policy( + ConvertProcessorPolicyToGoldenPolicy(state.active_policy)); + + if (state.is_locked) { + golden_output.set_next_unlocking_time_millis( + state.next_unlock_time.ToJavaTime()); + } + + return golden_output; +} + +} // namespace time_limit_consistency +} // namespace chromeos
diff --git a/chrome/browser/chromeos/child_accounts/time_limit_consistency_test/consistency_golden_converter.h b/chrome/browser/chromeos/child_accounts/time_limit_consistency_test/consistency_golden_converter.h new file mode 100644 index 0000000..5d55e1a --- /dev/null +++ b/chrome/browser/chromeos/child_accounts/time_limit_consistency_test/consistency_golden_converter.h
@@ -0,0 +1,36 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Utilities for converting goldens to and from the structures used by the time +// limit processor. + +#ifndef CHROME_BROWSER_CHROMEOS_CHILD_ACCOUNTS_TIME_LIMIT_CONSISTENCY_TEST_CONSISTENCY_GOLDEN_CONVERTER_H_ +#define CHROME_BROWSER_CHROMEOS_CHILD_ACCOUNTS_TIME_LIMIT_CONSISTENCY_TEST_CONSISTENCY_GOLDEN_CONVERTER_H_ + +#include <memory> + +#include "chrome/browser/chromeos/child_accounts/time_limit_consistency_test/goldens/consistency_golden.pb.h" +#include "chrome/browser/chromeos/child_accounts/usage_time_limit_processor.h" + +namespace base { +class DictionaryValue; +} // namespace base + +namespace chromeos { +namespace time_limit_consistency { + +// Converts the input part of a consistency golden case to the structure used by +// the time limit processor. +std::unique_ptr<base::DictionaryValue> ConvertGoldenInputToProcessorInput( + ConsistencyGoldenInput input); + +// Converts the output struct generated by the time limit processor to the +// consistency golden output proto. +ConsistencyGoldenOutput ConvertProcessorOutputToGoldenOutput( + usage_time_limit::State state); + +} // namespace time_limit_consistency +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_CHILD_ACCOUNTS_TIME_LIMIT_CONSISTENCY_TEST_CONSISTENCY_GOLDEN_CONVERTER_H_
diff --git a/chrome/browser/chromeos/child_accounts/time_limit_consistency_test/consistency_golden_converter_unittest.cc b/chrome/browser/chromeos/child_accounts/time_limit_consistency_test/consistency_golden_converter_unittest.cc new file mode 100644 index 0000000..ea9ce85 --- /dev/null +++ b/chrome/browser/chromeos/child_accounts/time_limit_consistency_test/consistency_golden_converter_unittest.cc
@@ -0,0 +1,106 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/child_accounts/time_limit_consistency_test/consistency_golden_converter.h" + +#include "base/time/time.h" +#include "chrome/browser/chromeos/child_accounts/time_limit_consistency_test/proto_matcher.h" +#include "chrome/browser/chromeos/child_accounts/time_limit_test_utils.h" +#include "chrome/browser/chromeos/child_accounts/usage_time_limit_processor.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace chromeos { + +namespace utils = time_limit_test_utils; + +namespace time_limit_consistency { + +using ConsistencyGoldenConverterTest = testing::Test; + +// A timestamp used during the tests. Nothing special about the date it +// points to. +constexpr int64_t kTestTimestamp = 1548709200000L; + +TEST_F(ConsistencyGoldenConverterTest, ConvertInputWhenEmpty) { + ConsistencyGoldenInput input; + + std::unique_ptr<base::DictionaryValue> actual_output = + ConvertGoldenInputToProcessorInput(input); + + std::unique_ptr<base::DictionaryValue> expected_output = + utils::CreateTimeLimitPolicy(base::TimeDelta::FromHours(6)); + + EXPECT_TRUE(*actual_output == *expected_output); +} + +TEST_F(ConsistencyGoldenConverterTest, ConvertInputWithBedtimes) { + base::Time last_updated = utils::TimeFromString("1 Jan 2018 10:00 GMT+0300"); + + ConsistencyGoldenInput input; + std::unique_ptr<base::DictionaryValue> expected_output = + utils::CreateTimeLimitPolicy(base::TimeDelta::FromHours(6)); + + // First window: Wednesday, 22:30 to 8:00 + ConsistencyGoldenWindowLimitEntry* window_one = input.add_window_limits(); + window_one->mutable_starts_at()->set_hour(22); + window_one->mutable_starts_at()->set_minute(30); + window_one->mutable_ends_at()->set_hour(8); + window_one->mutable_ends_at()->set_minute(0); + window_one->set_effective_day(WEDNESDAY); + utils::AddTimeWindowLimit(expected_output.get(), utils::kWednesday, + utils::CreateTime(22, 30), utils::CreateTime(8, 0), + last_updated); + + // Second window: Saturday, 18:45 to 22:30 + ConsistencyGoldenWindowLimitEntry* window_two = input.add_window_limits(); + window_two->mutable_starts_at()->set_hour(18); + window_two->mutable_starts_at()->set_minute(45); + window_two->mutable_ends_at()->set_hour(22); + window_two->mutable_ends_at()->set_minute(30); + window_two->set_effective_day(SATURDAY); + utils::AddTimeWindowLimit(expected_output.get(), utils::kSaturday, + utils::CreateTime(18, 45), + utils::CreateTime(22, 30), last_updated); + + std::unique_ptr<base::DictionaryValue> actual_output = + ConvertGoldenInputToProcessorInput(input); + + EXPECT_TRUE(*actual_output == *expected_output); +} + +TEST_F(ConsistencyGoldenConverterTest, ConvertOutputWhenUnlocked) { + usage_time_limit::State state; + state.is_locked = false; + state.active_policy = usage_time_limit::ActivePolicies::kNoActivePolicy; + state.next_unlock_time = base::Time::FromJavaTime(kTestTimestamp); + + ConsistencyGoldenOutput actual_output = + ConvertProcessorOutputToGoldenOutput(state); + + ConsistencyGoldenOutput expected_output; + expected_output.set_is_locked(false); + expected_output.set_active_policy(NO_ACTIVE_POLICY); + + EXPECT_THAT(actual_output, EqualsProto(expected_output)); +} + +TEST_F(ConsistencyGoldenConverterTest, ConvertOutputWhenLocked) { + usage_time_limit::State state; + state.is_locked = true; + state.active_policy = usage_time_limit::ActivePolicies::kFixedLimit; + state.next_unlock_time = base::Time::FromJavaTime(kTestTimestamp); + + ConsistencyGoldenOutput actual_output = + ConvertProcessorOutputToGoldenOutput(state); + + ConsistencyGoldenOutput expected_output; + expected_output.set_is_locked(true); + expected_output.set_active_policy(FIXED_LIMIT); + expected_output.set_next_unlocking_time_millis(kTestTimestamp); + + EXPECT_THAT(actual_output, EqualsProto(expected_output)); +} + +} // namespace time_limit_consistency +} // namespace chromeos
diff --git a/chrome/browser/chromeos/child_accounts/time_limit_consistency_test/consistency_golden_loader.cc b/chrome/browser/chromeos/child_accounts/time_limit_consistency_test/consistency_golden_loader.cc new file mode 100644 index 0000000..d9b9c5a --- /dev/null +++ b/chrome/browser/chromeos/child_accounts/time_limit_consistency_test/consistency_golden_loader.cc
@@ -0,0 +1,71 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/child_accounts/time_limit_consistency_test/consistency_golden_loader.h" + +#include "base/files/dir_reader_posix.h" +#include "base/files/file.h" +#include "base/files/file_util.h" +#include "base/path_service.h" +#include "base/strings/strcat.h" +#include "base/strings/string_util.h" +#include "third_party/protobuf/src/google/protobuf/io/zero_copy_stream_impl.h" +#include "third_party/protobuf/src/google/protobuf/text_format.h" + +namespace chromeos { +namespace time_limit_consistency { +namespace { + +base::FilePath GetGoldensPath() { + base::FilePath path; + base::PathService::Get(base::DIR_SOURCE_ROOT, &path); + + return path.Append( + FILE_PATH_LITERAL("chrome/browser/chromeos/child_accounts/" + "time_limit_consistency_test/goldens")); +} + +} // namespace + +std::vector<GoldenParam> LoadGoldenCases() { + return LoadGoldenCasesFromPath(GetGoldensPath()); +} + +std::vector<GoldenParam> LoadGoldenCasesFromPath( + const base::FilePath& directory_path) { + std::vector<GoldenParam> golden_params_list; + base::DirReaderPosix dir_reader(directory_path.value().c_str()); + + while (dir_reader.Next()) { + if (!base::EndsWith(dir_reader.name(), ".textproto", + base::CompareCase::INSENSITIVE_ASCII)) { + continue; + } + + ConsistencyGolden golden_suite; + base::File golden_file(directory_path.Append(dir_reader.name()), + base::File::FLAG_OPEN | base::File::FLAG_READ); + google::protobuf::io::FileInputStream stream(golden_file.GetPlatformFile()); + google::protobuf::TextFormat::Parse(&stream, &golden_suite); + + // Ignore suites that don't include CHROME_OS as a supported platform. + bool chromeos_supported = + std::count(golden_suite.supported_platforms().begin(), + golden_suite.supported_platforms().end(), CHROME_OS) > 0; + if (!chromeos_supported) + continue; + + std::string suite_name = dir_reader.name(); + base::ReplaceFirstSubstringAfterOffset(&suite_name, 0, ".textproto", ""); + for (int i = 0; i < golden_suite.cases_size(); i++) { + golden_params_list.push_back( + GoldenParam({suite_name, i, golden_suite.cases(i)})); + } + } + + return golden_params_list; +} + +} // namespace time_limit_consistency +} // namespace chromeos
diff --git a/chrome/browser/chromeos/child_accounts/time_limit_consistency_test/consistency_golden_loader.h b/chrome/browser/chromeos/child_accounts/time_limit_consistency_test/consistency_golden_loader.h new file mode 100644 index 0000000..a9aac373 --- /dev/null +++ b/chrome/browser/chromeos/child_accounts/time_limit_consistency_test/consistency_golden_loader.h
@@ -0,0 +1,41 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// A utility for loading golden files to be used by the time limit processor +// consistency tests. + +#ifndef CHROME_BROWSER_CHROMEOS_CHILD_ACCOUNTS_TIME_LIMIT_CONSISTENCY_TEST_CONSISTENCY_GOLDEN_LOADER_H_ +#define CHROME_BROWSER_CHROMEOS_CHILD_ACCOUNTS_TIME_LIMIT_CONSISTENCY_TEST_CONSISTENCY_GOLDEN_LOADER_H_ + +#include <string> +#include <vector> + +#include "base/files/file_path.h" +#include "chrome/browser/chromeos/child_accounts/time_limit_consistency_test/goldens/consistency_golden.pb.h" + +namespace chromeos { +namespace time_limit_consistency { + +// Holds information for one golden case and metadata used to generate the name +// for its test case (i.e. the name of the golden file it belongs and its index +// inside it). +struct GoldenParam { + const std::string suite_name; + const int index; + const ConsistencyGoldenCase golden_case; +}; + +// Loads all cases from all available golden files into a list of GoldenParams. +std::vector<GoldenParam> LoadGoldenCases(); + +// Loads all cases from all golden files from a given path into a list of +// GoldenParams. LoadGoldenCases() uses this function under the hood. Should not +// be called directly except for testing the golden loader itself. +std::vector<GoldenParam> LoadGoldenCasesFromPath( + const base::FilePath& directory_path); + +} // namespace time_limit_consistency +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_CHILD_ACCOUNTS_TIME_LIMIT_CONSISTENCY_TEST_CONSISTENCY_GOLDEN_LOADER_H_
diff --git a/chrome/browser/chromeos/child_accounts/time_limit_consistency_test/consistency_golden_loader_unittest.cc b/chrome/browser/chromeos/child_accounts/time_limit_consistency_test/consistency_golden_loader_unittest.cc new file mode 100644 index 0000000..b5c7f16 --- /dev/null +++ b/chrome/browser/chromeos/child_accounts/time_limit_consistency_test/consistency_golden_loader_unittest.cc
@@ -0,0 +1,47 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/child_accounts/time_limit_consistency_test/consistency_golden_loader.h" + +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/path_service.h" +#include "chrome/browser/chromeos/child_accounts/time_limit_consistency_test/proto_matcher.h" +#include "chrome/browser/chromeos/child_accounts/time_limit_test_utils.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace chromeos { + +namespace utils = time_limit_test_utils; + +namespace time_limit_consistency { + +using ConsistencyGoldenLoaderTest = testing::Test; + +base::FilePath GetTestGoldensPath() { + base::FilePath path; + base::PathService::Get(base::DIR_SOURCE_ROOT, &path); + + return path.Append( + FILE_PATH_LITERAL("chrome/browser/chromeos/child_accounts/" + "time_limit_consistency_test/test_goldens")); +} + +// Expected outcome is to ignore the test_golden_unsupported suite and return +// only the case within test_golden. +TEST_F(ConsistencyGoldenLoaderTest, LoadTestGoldenCases) { + std::vector<GoldenParam> goldens_list = + LoadGoldenCasesFromPath(GetTestGoldensPath()); + + ConsistencyGoldenCase golden_case; + golden_case.mutable_current_state()->set_time_millis(42); + + ASSERT_EQ(goldens_list.size(), 1ul); + EXPECT_EQ(goldens_list[0].suite_name, "test_golden"); + EXPECT_EQ(goldens_list[0].index, 0); + EXPECT_THAT(goldens_list[0].golden_case, EqualsProto(golden_case)); +} + +} // namespace time_limit_consistency +} // namespace chromeos
diff --git a/chrome/browser/chromeos/child_accounts/time_limit_consistency_test/goldens/consistency_golden.proto b/chrome/browser/chromeos/child_accounts/time_limit_consistency_test/goldens/consistency_golden.proto new file mode 100644 index 0000000..c3cec2e --- /dev/null +++ b/chrome/browser/chromeos/child_accounts/time_limit_consistency_test/goldens/consistency_golden.proto
@@ -0,0 +1,108 @@ +syntax = "proto2"; + +// Used to generate the ChromeOS C++ namespace +package chromeos.time_limit_consistency; + +// Used to generate the Java package +option java_package = "com.google.kids.timelimit.consistency"; +option java_multiple_files = true; + +// The platforms where the test suite may be supported. +enum SupportedPlatform { + UNSPECIFIED_PLATFORM = 0; + ANDROID = 1; + CHROME_OS = 2; +} + +// Policies which may be active. +enum ConsistencyGoldenPolicy { + UNSPECIFIED_POLICY = 0; + NO_ACTIVE_POLICY = 1; + OVERRIDE = 2; + FIXED_LIMIT = 3; + USAGE_LIMIT = 4; +} + +// Days of the week. +enum ConsistencyGoldenEffectiveDay { + UNSPECIFIED_EFFECTIVE_DAY = 0; + MONDAY = 1; + TUESDAY = 2; + WEDNESDAY = 3; + THURSDAY = 4; + FRIDAY = 5; + SATURDAY = 6; + SUNDAY = 7; +} + +// The main object, represents one test suite (and one golden file). +message ConsistencyGolden { + // The platforms where the test is supported. Required + repeated SupportedPlatform supported_platforms = 1; + + // A list of test cases. Required + repeated ConsistencyGoldenCase cases = 2; +} + +// Message representing one test case +message ConsistencyGoldenCase { + // Input policy data. Required + optional ConsistencyGoldenInput input = 1; + + // Simulates the current state when executing. Required + optional ConsistencyGoldenCurrentState current_state = 2; + + // The test's output, used for both the expected and the actual results. + // Required + optional ConsistencyGoldenOutput output = 3; +} + +// The policies configured by the parent. +message ConsistencyGoldenInput { + // List of bedtime configurations for different days of the week. + repeated ConsistencyGoldenWindowLimitEntry window_limits = 1; +} + +// Bedtime configuration for a given day. +message ConsistencyGoldenWindowLimitEntry { + // Which day of the week this configuration relates to. Required + optional ConsistencyGoldenEffectiveDay effective_day = 1; + + // At which hour and minute this bedtime should start. Required + optional ConsistencyGoldenTimeOfDay starts_at = 2; + + // At which hour and minute this bedtime should end. Required + optional ConsistencyGoldenTimeOfDay ends_at = 3; +} + +// Represents a moment of a day. +message ConsistencyGoldenTimeOfDay { + // A given hour. [0-23]. Required + optional int32 hour = 1; + + // A given minute. [0-59]. Required + optional int32 minute = 2; +} + +// Information to represent the current state when executing. +message ConsistencyGoldenCurrentState { + // A timestamp for the desired current time. Required + optional int64 time_millis = 1; + + // String representing the desired timezone, formatted like "GMT+2"/"GMT-3" + // or "America/Sao_Paulo". Required + optional string timezone = 2; +} + +// Information on the output. +message ConsistencyGoldenOutput { + // Whether the device is locked. Required + optional bool is_locked = 1; + + // What is the policy currently taking place. Required + optional ConsistencyGoldenPolicy active_policy = 2; + + // Timestamp of when is the device supposed to unlock. + // This field must be present if and only if the device is locked. + optional int64 next_unlocking_time_millis = 3; +}
diff --git a/chrome/browser/chromeos/child_accounts/time_limit_consistency_test/proto_matcher.h b/chrome/browser/chromeos/child_accounts/time_limit_consistency_test/proto_matcher.h new file mode 100644 index 0000000..8bea859 --- /dev/null +++ b/chrome/browser/chromeos/child_accounts/time_limit_consistency_test/proto_matcher.h
@@ -0,0 +1,43 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// A gMock matcher for comparing protos and producing a human-readable +// message if the assertion fails. + +#ifndef CHROME_BROWSER_CHROMEOS_CHILD_ACCOUNTS_TIME_LIMIT_CONSISTENCY_TEST_PROTO_MATCHER_H_ +#define CHROME_BROWSER_CHROMEOS_CHILD_ACCOUNTS_TIME_LIMIT_CONSISTENCY_TEST_PROTO_MATCHER_H_ + +#include <string> + +#include "testing/gmock/include/gmock/gmock.h" +#include "third_party/protobuf/src/google/protobuf/text_format.h" + +namespace chromeos { +namespace time_limit_consistency { + +MATCHER_P(EqualsProto, message, "equals golden proto") { + std::string expected_serialized, actual_serialized; + message.SerializeToString(&expected_serialized); + arg.SerializeToString(&actual_serialized); + + if (expected_serialized == actual_serialized) { + return true; + } + + std::string expected_readable, actual_readable; + google::protobuf::TextFormat::PrintToString(message, &expected_readable); + google::protobuf::TextFormat::PrintToString(arg, &actual_readable); + + *result_listener << "\n\noutput parses to: \n----------\n" + << actual_readable + << "---------\n\n and should be: \n----------\n" + << expected_readable << "----------"; + + return expected_serialized == actual_serialized; +} + +} // namespace time_limit_consistency +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_CHILD_ACCOUNTS_TIME_LIMIT_CONSISTENCY_TEST_PROTO_MATCHER_H_
diff --git a/chrome/browser/chromeos/child_accounts/time_limit_consistency_test/test_goldens/test_golden.textproto b/chrome/browser/chromeos/child_accounts/time_limit_consistency_test/test_goldens/test_golden.textproto new file mode 100644 index 0000000..aefe7d7 --- /dev/null +++ b/chrome/browser/chromeos/child_accounts/time_limit_consistency_test/test_goldens/test_golden.textproto
@@ -0,0 +1,6 @@ +supported_platforms: CHROME_OS +cases { + current_state { + time_millis: 42 + } +}
diff --git a/chrome/browser/chromeos/child_accounts/time_limit_consistency_test/test_goldens/test_golden_unsupported.textproto b/chrome/browser/chromeos/child_accounts/time_limit_consistency_test/test_goldens/test_golden_unsupported.textproto new file mode 100644 index 0000000..86c65f4 --- /dev/null +++ b/chrome/browser/chromeos/child_accounts/time_limit_consistency_test/test_goldens/test_golden_unsupported.textproto
@@ -0,0 +1,6 @@ +supported_platforms: ANDROID +cases { + current_state { + time_millis: 43 + } +}
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc index bd7ce7b47..2edcaf5 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
@@ -931,8 +931,7 @@ TestCase("myFilesFolderRename"), TestCase("myFilesFolderRename").EnableMyFilesVolume(), TestCase("myFilesUpdatesChildren"), - TestCase("myFilesUpdatesChildren").EnableMyFilesVolume(), - TestCase("myFilesExpandWhenSelected").EnableMyFilesVolume())); + TestCase("myFilesUpdatesChildren").EnableMyFilesVolume())); WRAPPED_INSTANTIATE_TEST_SUITE_P( InstallLinuxPackageDialog, /* install_linux_package_dialog.js */
diff --git a/chrome/browser/chromeos/login/existing_user_controller.cc b/chrome/browser/chromeos/login/existing_user_controller.cc index c9241c3..5c53b35 100644 --- a/chrome/browser/chromeos/login/existing_user_controller.cc +++ b/chrome/browser/chromeos/login/existing_user_controller.cc
@@ -64,6 +64,7 @@ #include "chrome/browser/ui/aura/accessibility/automation_manager_aura.h" #include "chrome/browser/ui/webui/chromeos/login/l10n_util.h" #include "chrome/common/channel_info.h" +#include "chrome/common/chrome_features.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/url_constants.h" #include "chrome/grit/generated_resources.h" @@ -966,7 +967,9 @@ } ClearRecordedNames(); - if (public_session_auto_login_account_id_.is_valid() && + if (base::FeatureList::IsEnabled( + features::kManagedGuestSessionNotification) && + public_session_auto_login_account_id_.is_valid() && public_session_auto_login_account_id_ == user_context.GetAccountId() && last_login_attempt_was_auto_login_) { const std::string& user_id = user_context.GetAccountId().GetUserEmail();
diff --git a/chrome/browser/chromeos/login/saml/saml_browsertest.cc b/chrome/browser/chromeos/login/saml/saml_browsertest.cc index ff0d7e6..d1f5a66 100644 --- a/chrome/browser/chromeos/login/saml/saml_browsertest.cc +++ b/chrome/browser/chromeos/login/saml/saml_browsertest.cc
@@ -35,6 +35,7 @@ #include "chrome/browser/chromeos/login/test/fake_gaia_mixin.h" #include "chrome/browser/chromeos/login/test/https_forwarder.h" #include "chrome/browser/chromeos/login/test/js_checker.h" +#include "chrome/browser/chromeos/login/test/local_policy_test_server_mixin.h" #include "chrome/browser/chromeos/login/test/oobe_base_test.h" #include "chrome/browser/chromeos/login/test/oobe_screen_waiter.h" #include "chrome/browser/chromeos/login/ui/login_display_host.h" @@ -47,7 +48,6 @@ #include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h" -#include "chrome/browser/policy/test/local_policy_test_server.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/webui/signin/signin_utils.h" #include "chrome/common/chrome_constants.h" @@ -157,7 +157,6 @@ constexpr char kTestUserinfoToken[] = "fake-userinfo-token"; constexpr char kTestRefreshToken[] = "fake-refresh-token"; -constexpr char kPolicy[] = "{\"managed_users\": [\"*\"]}"; constexpr char kAffiliationID[] = "some-affiliation-id"; @@ -855,8 +854,6 @@ ~SAMLEnrollmentTest() override; // SamlTest: - void SetUp() override; - void SetUpCommandLine(base::CommandLine* command_line) override; void SetUpOnMainThread() override; void StartSamlAndWaitForIdpPageLoad(const std::string& gaia_email) override; @@ -869,7 +866,7 @@ content::WebContents* GetEnrollmentContents(); private: - std::unique_ptr<policy::LocalPolicyTestServer> test_server_; + LocalPolicyTestServerMixin local_policy_mixin_{&mixin_host_}; base::ScopedTempDir temp_dir_; std::unique_ptr<base::RunLoop> run_loop_; @@ -887,26 +884,6 @@ SAMLEnrollmentTest::~SAMLEnrollmentTest() {} -void SAMLEnrollmentTest::SetUp() { - ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); - const base::FilePath policy_file = - temp_dir_.GetPath().AppendASCII("policy.json"); - ASSERT_EQ(static_cast<int>(strlen(kPolicy)), - base::WriteFile(policy_file, kPolicy, strlen(kPolicy))); - - test_server_.reset(new policy::LocalPolicyTestServer(policy_file)); - ASSERT_TRUE(test_server_->Start()); - - SamlTest::SetUp(); -} - -void SAMLEnrollmentTest::SetUpCommandLine(base::CommandLine* command_line) { - command_line->AppendSwitchASCII(policy::switches::kDeviceManagementUrl, - test_server_->GetServiceURL().spec()); - - SamlTest::SetUpCommandLine(command_line); -} - void SAMLEnrollmentTest::SetUpOnMainThread() { FakeGaia::AccessTokenInfo token_info; token_info.token = kTestUserinfoToken;
diff --git a/chrome/browser/chromeos/login/test/local_policy_test_server_mixin.cc b/chrome/browser/chromeos/login/test/local_policy_test_server_mixin.cc new file mode 100644 index 0000000..87c1290 --- /dev/null +++ b/chrome/browser/chromeos/login/test/local_policy_test_server_mixin.cc
@@ -0,0 +1,66 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/login/test/local_policy_test_server_mixin.h" + +#include <utility> + +#include "components/policy/core/common/cloud/cloud_policy_constants.h" +#include "components/policy/core/common/cloud/policy_builder.h" +#include "components/policy/core/common/policy_switches.h" + +namespace chromeos { + +namespace { + +base::Value GetDefaultConfig() { + base::Value config(base::Value::Type::DICTIONARY); + + base::Value managed_users(base::Value::Type::LIST); + managed_users.GetList().emplace_back("*"); + config.SetKey("managed_users", std::move(managed_users)); + + return config; +} + +} // namespace + +LocalPolicyTestServerMixin::LocalPolicyTestServerMixin( + InProcessBrowserTestMixinHost* host) + : InProcessBrowserTestMixin(host) { + server_config_ = GetDefaultConfig(); +} + +void LocalPolicyTestServerMixin::SetUp() { + policy_test_server_ = std::make_unique<policy::LocalPolicyTestServer>(); + policy_test_server_->SetConfig(server_config_); + policy_test_server_->RegisterClient(policy::PolicyBuilder::kFakeToken, + policy::PolicyBuilder::kFakeDeviceId, + {} /* state_keys */); + + ASSERT_TRUE(policy_test_server_->SetSigningKeyAndSignature( + policy::PolicyBuilder::CreateTestSigningKey().get(), + policy::PolicyBuilder::GetTestSigningKeySignature())); + + ASSERT_TRUE(policy_test_server_->Start()); +} + +void LocalPolicyTestServerMixin::SetUpCommandLine( + base::CommandLine* command_line) { + // Specify device management server URL. + command_line->AppendSwitchASCII(policy::switches::kDeviceManagementUrl, + policy_test_server_->GetServiceURL().spec()); +} + +bool LocalPolicyTestServerMixin::UpdateDevicePolicy( + const enterprise_management::ChromeDeviceSettingsProto& policy) { + DCHECK(policy_test_server_); + return policy_test_server_->UpdatePolicy( + policy::dm_protocol::kChromeDevicePolicyType, + std::string() /* entity_id */, policy.SerializeAsString()); +} + +LocalPolicyTestServerMixin::~LocalPolicyTestServerMixin() = default; + +} // namespace chromeos
diff --git a/chrome/browser/chromeos/login/test/local_policy_test_server_mixin.h b/chrome/browser/chromeos/login/test/local_policy_test_server_mixin.h new file mode 100644 index 0000000..d5085ea --- /dev/null +++ b/chrome/browser/chromeos/login/test/local_policy_test_server_mixin.h
@@ -0,0 +1,44 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_LOGIN_TEST_LOCAL_POLICY_TEST_SERVER_MIXIN_H_ +#define CHROME_BROWSER_CHROMEOS_LOGIN_TEST_LOCAL_POLICY_TEST_SERVER_MIXIN_H_ + +#include <memory> + +#include "base/macros.h" +#include "base/values.h" +#include "chrome/browser/chromeos/login/mixin_based_in_process_browser_test.h" +#include "chrome/browser/policy/test/local_policy_test_server.h" +#include "components/policy/proto/chrome_device_policy.pb.h" + +namespace chromeos { + +// This test mixin covers setting up LocalPolicyTestServer and adding a +// command-line flag to use it. Please see SetUp function for default settings. +// Server is started after SetUp execution. +class LocalPolicyTestServerMixin : public InProcessBrowserTestMixin { + public: + explicit LocalPolicyTestServerMixin(InProcessBrowserTestMixinHost* host); + ~LocalPolicyTestServerMixin() override; + + policy::LocalPolicyTestServer* server() { return policy_test_server_.get(); } + + // InProcessBrowserTestMixin: + void SetUp() override; + void SetUpCommandLine(base::CommandLine* command_line) override; + + bool UpdateDevicePolicy( + const enterprise_management::ChromeDeviceSettingsProto& policy); + + private: + std::unique_ptr<policy::LocalPolicyTestServer> policy_test_server_; + base::Value server_config_; + + DISALLOW_COPY_AND_ASSIGN(LocalPolicyTestServerMixin); +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_LOGIN_TEST_LOCAL_POLICY_TEST_SERVER_MIXIN_H_
diff --git a/chrome/browser/chromeos/login/webview_login_browsertest.cc b/chrome/browser/chromeos/login/webview_login_browsertest.cc index f048597..8851bb9 100644 --- a/chrome/browser/chromeos/login/webview_login_browsertest.cc +++ b/chrome/browser/chromeos/login/webview_login_browsertest.cc
@@ -21,6 +21,7 @@ #include "chrome/browser/chromeos/login/signin_partition_manager.h" #include "chrome/browser/chromeos/login/test/fake_gaia_mixin.h" #include "chrome/browser/chromeos/login/test/js_checker.h" +#include "chrome/browser/chromeos/login/test/local_policy_test_server_mixin.h" #include "chrome/browser/chromeos/login/test/oobe_base_test.h" #include "chrome/browser/chromeos/login/test/oobe_screen_waiter.h" #include "chrome/browser/chromeos/login/ui/login_display_host.h" @@ -30,7 +31,6 @@ #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/chromeos/settings/scoped_testing_cros_settings.h" #include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h" -#include "chrome/browser/policy/test/local_policy_test_server.h" #include "chrome/browser/ui/login/login_handler.h" #include "chrome/browser/ui/webui/signin/signin_utils.h" #include "chromeos/constants/chromeos_switches.h" @@ -842,16 +842,7 @@ .set_public_key_version(1); device_policy_test_helper_.device_policy()->Build(); - // Start policy server. Use the DMToken and DeviceId from PolicyBuilder. - // These also used in |device_policy_test_helper_| and was passed to - // |fake_session_manager_client_| above, so the device will request policy - // with these identifiers. - policy_test_server_.RegisterClient(policy::PolicyBuilder::kFakeToken, - policy::PolicyBuilder::kFakeDeviceId, - {} /* state_keys */); UpdateServedPolicyFromDevicePolicyTestHelper(); - ASSERT_TRUE(policy_test_server_.Start()); - WebviewLoginTest::SetUp(); } @@ -859,8 +850,6 @@ command_line->AppendSwitchASCII( ::switches::kProxyServer, auth_proxy_server_->host_port_pair().ToString()); - command_line->AppendSwitchASCII(policy::switches::kDeviceManagementUrl, - policy_test_server_.GetServiceURL().spec()); WebviewLoginTest::SetUpCommandLine(command_line); } @@ -933,10 +922,7 @@ } void UpdateServedPolicyFromDevicePolicyTestHelper() { - policy_test_server_.UpdatePolicy( - policy::dm_protocol::kChromeDevicePolicyType, - std::string() /* entity_id */, - device_policy_builder()->payload().SerializeAsString()); + local_policy_mixin_.UpdateDevicePolicy(device_policy_builder()->payload()); } policy::DevicePolicyBuilder* device_policy_builder() { @@ -956,7 +942,7 @@ // A proxy server which requires authentication using the 'Basic' // authentication method. std::unique_ptr<net::SpawnedTestServer> auth_proxy_server_; - policy::LocalPolicyTestServer policy_test_server_; + LocalPolicyTestServerMixin local_policy_mixin_{&mixin_host_}; policy::DevicePolicyCrosTestHelper device_policy_test_helper_; // FakeDBusThreadManager uses FakeSessionManagerClient.
diff --git a/chrome/browser/chromeos/policy/device_cloud_policy_browsertest.cc b/chrome/browser/chromeos/policy/device_cloud_policy_browsertest.cc index b12de81..d506e6fd 100644 --- a/chrome/browser/chromeos/policy/device_cloud_policy_browsertest.cc +++ b/chrome/browser/chromeos/policy/device_cloud_policy_browsertest.cc
@@ -17,6 +17,7 @@ #include "base/values.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part.h" +#include "chrome/browser/chromeos/login/test/local_policy_test_server_mixin.h" #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" #include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h" #include "chrome/browser/chromeos/policy/device_policy_builder.h" @@ -25,7 +26,6 @@ #include "chrome/browser/chromeos/settings/device_settings_service.h" #include "chrome/browser/extensions/chrome_test_extension_loader.h" #include "chrome/browser/extensions/extension_service.h" -#include "chrome/browser/policy/test/local_policy_test_server.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/common/chrome_constants.h" @@ -109,14 +109,9 @@ void SetUp() override { UpdateBuiltTestPolicyValue(kTestPolicyValue); - StartPolicyTestServer(); DevicePolicyCrosBrowserTest::SetUp(); - } - - void SetUpCommandLine(base::CommandLine* command_line) override { - DevicePolicyCrosBrowserTest::SetUpCommandLine(command_line); - command_line->AppendSwitchASCII(policy::switches::kDeviceManagementUrl, - policy_test_server_.GetServiceURL().spec()); + local_policy_mixin_.server()->EnableAutomaticRotationOfSigningKeys(); + UpdateServedTestPolicy(); } void SetUpInProcessBrowserTestFixture() override { @@ -149,9 +144,8 @@ } void UpdateServedTestPolicy() { - EXPECT_TRUE(policy_test_server_.UpdatePolicy( - dm_protocol::kChromeDevicePolicyType, std::string() /* entity_id */, - device_policy()->payload().SerializeAsString())); + EXPECT_TRUE( + local_policy_mixin_.UpdateDevicePolicy(device_policy()->payload())); } int GetTestPolicyValue() { @@ -182,15 +176,6 @@ } private: - void StartPolicyTestServer() { - policy_test_server_.RegisterClient(PolicyBuilder::kFakeToken, - PolicyBuilder::kFakeDeviceId, - {} /* state_keys */); - UpdateServedTestPolicy(); - policy_test_server_.EnableAutomaticRotationOfSigningKeys(); - EXPECT_TRUE(policy_test_server_.Start()); - } - void SetFakeDevicePolicy() { device_policy() ->payload() @@ -222,7 +207,7 @@ } } - LocalPolicyTestServer policy_test_server_; + chromeos::LocalPolicyTestServerMixin local_policy_mixin_{&mixin_host_}; std::unique_ptr<PolicyChangeRegistrar> policy_change_registrar_; int awaited_policy_value_ = -1; std::unique_ptr<base::RunLoop> policy_change_waiting_run_loop_; @@ -286,7 +271,6 @@ ~SigninExtensionsDeviceCloudPolicyBrowserTest() override = default; void SetUp() override { - StartPolicyTestServer(); ASSERT_TRUE(embedded_test_server()->InitializeAndListen()); DevicePolicyCrosBrowserTest::SetUp(); } @@ -295,8 +279,6 @@ DevicePolicyCrosBrowserTest::SetUpCommandLine(command_line); command_line->AppendSwitch(chromeos::switches::kLoginManager); command_line->AppendSwitch(chromeos::switches::kForceLoginManagerInTests); - command_line->AppendSwitchASCII(policy::switches::kDeviceManagementUrl, - policy_test_server_.GetServiceURL().spec()); // The test app has to be whitelisted for sign-in screen. command_line->AppendSwitchASCII( extensions::switches::kWhitelistedExtensionID, kTestExtensionId); @@ -308,10 +290,9 @@ MarkAsEnterpriseOwned(); SetFakeDevicePolicy(); - EXPECT_TRUE(policy_test_server_.UpdatePolicy( - dm_protocol::kChromeDevicePolicyType, std::string() /* entity_id */, - device_policy()->payload().SerializeAsString())); - EXPECT_TRUE(policy_test_server_.UpdatePolicy( + EXPECT_TRUE( + local_policy_mixin_.UpdateDevicePolicy(device_policy()->payload())); + EXPECT_TRUE(local_policy_mixin_.server()->UpdatePolicy( dm_protocol::kChromeSigninExtensionPolicyType, kTestExtensionId, BuildTestComponentPolicyPayload().SerializeAsString())); } @@ -375,17 +356,6 @@ return response; } - void StartPolicyTestServer() { - std::unique_ptr<crypto::RSAPrivateKey> signing_key( - PolicyBuilder::CreateTestSigningKey()); - EXPECT_TRUE(policy_test_server_.SetSigningKeyAndSignature( - signing_key.get(), PolicyBuilder::GetTestSigningKeySignature())); - policy_test_server_.RegisterClient(PolicyBuilder::kFakeToken, - PolicyBuilder::kFakeDeviceId, - {} /* state_keys */); - EXPECT_TRUE(policy_test_server_.Start()); - } - void SetFakeDevicePolicy() { device_policy()->policy_data().set_public_key_version( kFakePolicyPublicKeyVersion); @@ -421,7 +391,7 @@ builder->Build(); } - LocalPolicyTestServer policy_test_server_; + chromeos::LocalPolicyTestServerMixin local_policy_mixin_{&mixin_host_}; DISALLOW_COPY_AND_ASSIGN(SigninExtensionsDeviceCloudPolicyBrowserTest); };
diff --git a/chrome/browser/chromeos/policy/device_local_account_browsertest.cc b/chrome/browser/chromeos/policy/device_local_account_browsertest.cc index 44a1076c..6ff9284 100644 --- a/chrome/browser/chromeos/policy/device_local_account_browsertest.cc +++ b/chrome/browser/chromeos/policy/device_local_account_browsertest.cc
@@ -48,6 +48,7 @@ #include "chrome/browser/chromeos/login/session/user_session_manager.h" #include "chrome/browser/chromeos/login/session/user_session_manager_test_api.h" #include "chrome/browser/chromeos/login/signin_specifics.h" +#include "chrome/browser/chromeos/login/test/local_policy_test_server_mixin.h" #include "chrome/browser/chromeos/login/ui/login_display_host.h" #include "chrome/browser/chromeos/login/ui/webui_login_view.h" #include "chrome/browser/chromeos/login/users/avatar/user_image_manager.h" @@ -71,7 +72,6 @@ #include "chrome/browser/lifetime/application_lifetime.h" #include "chrome/browser/policy/profile_policy_connector.h" #include "chrome/browser/policy/profile_policy_connector_factory.h" -#include "chrome/browser/policy/test/local_policy_test_server.h" #include "chrome/browser/prefs/session_startup_pref.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" @@ -456,17 +456,6 @@ ~DeviceLocalAccountTest() override {} void SetUp() override { - // Configure and start the test server. - std::unique_ptr<crypto::RSAPrivateKey> signing_key( - PolicyBuilder::CreateTestSigningKey()); - ASSERT_TRUE(test_server_.SetSigningKeyAndSignature( - signing_key.get(), PolicyBuilder::GetTestSigningKeySignature())); - signing_key.reset(); - test_server_.RegisterClient(PolicyBuilder::kFakeToken, - PolicyBuilder::kFakeDeviceId, - {} /* state_keys */); - ASSERT_TRUE(test_server_.Start()); - BrowserList::AddObserver(this); DevicePolicyCrosBrowserTest::SetUp(); @@ -477,8 +466,6 @@ command_line->AppendSwitch(chromeos::switches::kLoginManager); command_line->AppendSwitch(chromeos::switches::kForceLoginManagerInTests); command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile, "user"); - command_line->AppendSwitchASCII(policy::switches::kDeviceManagementUrl, - test_server_.GetServiceURL().spec()); } void SetUpInProcessBrowserTestFixture() override { @@ -539,6 +526,7 @@ base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&chrome::AttemptExit)); base::RunLoop().RunUntilIdle(); + DevicePolicyCrosBrowserTest::TearDownOnMainThread(); } void LocalStateChanged(user_manager::UserManager* user_manager) override { @@ -586,7 +574,7 @@ void UploadDeviceLocalAccountPolicy() { BuildDeviceLocalAccountPolicy(); - ASSERT_TRUE(test_server_.UpdatePolicy( + ASSERT_TRUE(local_policy_mixin_.server()->UpdatePolicy( dm_protocol::kChromePublicAccountPolicyType, kAccountId1, device_local_account_policy_.payload().SerializeAsString())); } @@ -618,9 +606,7 @@ account->set_type( em::DeviceLocalAccountInfoProto::ACCOUNT_TYPE_PUBLIC_SESSION); RefreshDevicePolicy(); - ASSERT_TRUE(test_server_.UpdatePolicy(dm_protocol::kChromeDevicePolicyType, - std::string(), - proto.SerializeAsString())); + ASSERT_TRUE(local_policy_mixin_.UpdateDevicePolicy(proto)); } void SetManagedSessionsEnabled(bool managed_sessions_enabled) { @@ -637,9 +623,7 @@ device_local_accounts->set_auto_login_id(kAccountId1); device_local_accounts->set_auto_login_delay(0); RefreshDevicePolicy(); - ASSERT_TRUE(test_server_.UpdatePolicy(dm_protocol::kChromeDevicePolicyType, - std::string(), - proto.SerializeAsString())); + ASSERT_TRUE(local_policy_mixin_.UpdateDevicePolicy(proto)); } void CheckPublicSessionPresent(const AccountId& account_id) { @@ -801,7 +785,7 @@ std::unique_ptr<base::RunLoop> run_loop_; UserPolicyBuilder device_local_account_policy_; - LocalPolicyTestServer test_server_; + chromeos::LocalPolicyTestServerMixin local_policy_mixin_{&mixin_host_}; content::WebContents* contents_; @@ -1023,8 +1007,7 @@ account1->set_type( em::DeviceLocalAccountInfoProto::ACCOUNT_TYPE_PUBLIC_SESSION); - test_server_.UpdatePolicy(dm_protocol::kChromeDevicePolicyType, std::string(), - policy.SerializeAsString()); + local_policy_mixin_.UpdateDevicePolicy(policy); g_browser_process->policy_service()->RefreshPolicies(base::Closure()); // Make sure the second device-local account disappears. @@ -2295,7 +2278,7 @@ // Note that the policy for the device-local account will be fetched before // the session is started, so the policy for the app must be installed before // the first device policy fetch. - ASSERT_TRUE(test_server_.UpdatePolicyData( + ASSERT_TRUE(local_policy_mixin_.server()->UpdatePolicyData( dm_protocol::kChromeExtensionPolicyType, kShowManagedStorageID, "{" " \"string\": {" @@ -2343,7 +2326,7 @@ *policy_service->GetPolicies(ns).GetValue("string")); // Now update the policy at the server. - ASSERT_TRUE(test_server_.UpdatePolicyData( + ASSERT_TRUE(local_policy_mixin_.server()->UpdatePolicyData( dm_protocol::kChromeExtensionPolicyType, kShowManagedStorageID, "{" " \"string\": {"
diff --git a/chrome/browser/chromeos/policy/device_policy_cros_browser_test.cc b/chrome/browser/chromeos/policy/device_policy_cros_browser_test.cc index d4ba619b..8b64b6b 100644 --- a/chrome/browser/chromeos/policy/device_policy_cros_browser_test.cc +++ b/chrome/browser/chromeos/policy/device_policy_cros_browser_test.cc
@@ -96,7 +96,7 @@ std::vector<std::string> state_keys; state_keys.push_back("1"); fake_session_manager_client_->set_server_backed_state_keys(state_keys); - InProcessBrowserTest::SetUp(); + chromeos::MixinBasedInProcessBrowserTest::SetUp(); } void DevicePolicyCrosBrowserTest::SetUpInProcessBrowserTestFixture() { @@ -106,6 +106,7 @@ dbus_setter_->SetSessionManagerClient( std::unique_ptr<chromeos::SessionManagerClient>( fake_session_manager_client_)); + chromeos::MixinBasedInProcessBrowserTest::SetUpInProcessBrowserTestFixture(); } void DevicePolicyCrosBrowserTest::MarkOwnership() {
diff --git a/chrome/browser/chromeos/policy/device_policy_cros_browser_test.h b/chrome/browser/chromeos/policy/device_policy_cros_browser_test.h index c316f4c..210c74ba 100644 --- a/chrome/browser/chromeos/policy/device_policy_cros_browser_test.h +++ b/chrome/browser/chromeos/policy/device_policy_cros_browser_test.h
@@ -9,8 +9,8 @@ #include "base/compiler_specific.h" #include "base/macros.h" +#include "chrome/browser/chromeos/login/mixin_based_in_process_browser_test.h" #include "chrome/browser/chromeos/policy/device_policy_builder.h" -#include "chrome/test/base/in_process_browser_test.h" #include "chromeos/dbus/dbus_thread_manager.h" namespace chromeos { @@ -47,11 +47,13 @@ }; // Used to test Device policy changes in Chrome OS. -class DevicePolicyCrosBrowserTest : public InProcessBrowserTest { +class DevicePolicyCrosBrowserTest + : public chromeos::MixinBasedInProcessBrowserTest { protected: DevicePolicyCrosBrowserTest(); ~DevicePolicyCrosBrowserTest() override; + // MixinBasedInProcessBrowserTest: void SetUp() override; void SetUpInProcessBrowserTestFixture() override;
diff --git a/chrome/browser/chromeos/policy/user_network_configuration_updater_factory_browsertest.cc b/chrome/browser/chromeos/policy/user_network_configuration_updater_factory_browsertest.cc index 7df0be67..adfba60 100644 --- a/chrome/browser/chromeos/policy/user_network_configuration_updater_factory_browsertest.cc +++ b/chrome/browser/chromeos/policy/user_network_configuration_updater_factory_browsertest.cc
@@ -15,6 +15,7 @@ #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chromeos/login/existing_user_controller.h" #include "chrome/browser/chromeos/login/screens/gaia_view.h" +#include "chrome/browser/chromeos/login/test/local_policy_test_server_mixin.h" #include "chrome/browser/chromeos/login/ui/login_display_host.h" #include "chrome/browser/chromeos/login/wizard_controller.h" #include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h" @@ -23,7 +24,6 @@ #include "chrome/browser/chromeos/policy/user_network_configuration_updater_factory.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/net/nss_context.h" -#include "chrome/browser/policy/test/local_policy_test_server.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_list.h" @@ -437,21 +437,6 @@ } protected: - void SetUp() override { - // Configure and start the test server. - std::unique_ptr<crypto::RSAPrivateKey> signing_key( - PolicyBuilder::CreateTestSigningKey()); - ASSERT_TRUE(policy_server_.SetSigningKeyAndSignature( - signing_key.get(), PolicyBuilder::GetTestSigningKeySignature())); - signing_key.reset(); - policy_server_.RegisterClient(PolicyBuilder::kFakeToken, - PolicyBuilder::kFakeDeviceId, - {} /* state_keys */); - ASSERT_TRUE(policy_server_.Start()); - - DevicePolicyCrosBrowserTest::SetUp(); - } - virtual void SetupDevicePolicy() = 0; void SetUpInProcessBrowserTestFixture() override { @@ -475,8 +460,6 @@ command_line->AppendSwitch(chromeos::switches::kForceLoginManagerInTests); command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile, "user"); command_line->AppendSwitch(chromeos::switches::kOobeSkipPostLogin); - command_line->AppendSwitchASCII(switches::kDeviceManagementUrl, - policy_server_.GetServiceURL().spec()); } void WaitForSessionStart() { @@ -487,7 +470,7 @@ .Wait(); } - LocalPolicyTestServer policy_server_; + chromeos::LocalPolicyTestServerMixin local_policy_mixin_{&mixin_host_}; const AccountId device_local_account_id_ = AccountId::FromUserEmail(GenerateDeviceLocalAccountUserId( @@ -514,9 +497,7 @@ account->set_type( em::DeviceLocalAccountInfoProto::ACCOUNT_TYPE_PUBLIC_SESSION); RefreshDevicePolicy(); - ASSERT_TRUE( - policy_server_.UpdatePolicy(dm_protocol::kChromeDevicePolicyType, - std::string(), proto.SerializeAsString())); + ASSERT_TRUE(local_policy_mixin_.UpdateDevicePolicy(proto)); } void StartLogin() {
diff --git a/chrome/browser/chromeos/power/auto_screen_brightness/als_reader_impl.cc b/chrome/browser/chromeos/power/auto_screen_brightness/als_reader_impl.cc index ac2dadc..fa270185 100644 --- a/chrome/browser/chromeos/power/auto_screen_brightness/als_reader_impl.cc +++ b/chrome/browser/chromeos/power/auto_screen_brightness/als_reader_impl.cc
@@ -41,32 +41,6 @@ return exit_code == 0; } -// Returns whether the ALS step config is what we need. This function is only -// called if an ALS is enabled. This should run in another thread to be -// non-blocking to the main thread. -// TODO(jiameng): we assume one specific device now, and only check if the -// number of steps is 7. -bool VerifyAlsConfig() { - DCHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); - base::CommandLine command_line{ - base::FilePath(FILE_PATH_LITERAL("check_powerd_config"))}; - command_line.AppendArg("--internal_backlight_ambient_light_steps"); - int exit_code = 0; - std::string output; - const bool result = - base::GetAppOutputWithExitCode(command_line, &output, &exit_code); - - if (!result || exit_code != 0) { - LOG(ERROR) << "Cannot run check_powerd_config " - "--internal_backlight_ambient_light_steps"; - return false; - } - - const std::vector<base::StringPiece> num_steps = base::SplitStringPiece( - output, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); - return num_steps.size() == 7; -} - // Returns ALS path. This should run in another thread to be non-blocking to the // main thread. std::string GetAlsPath() { @@ -158,7 +132,6 @@ } void AlsReaderImpl::FailForTesting() { - OnAlsConfigCheckDone(false); OnAlsEnableCheckDone(false); for (int i = 0; i <= kMaxInitialAttempts; i++) OnAlsPathReadAttempted(""); @@ -172,20 +145,6 @@ return; } - base::PostTaskAndReplyWithResult( - blocking_task_runner_.get(), FROM_HERE, base::BindOnce(&VerifyAlsConfig), - base::BindOnce(&AlsReaderImpl::OnAlsConfigCheckDone, - weak_ptr_factory_.GetWeakPtr())); -} - -void AlsReaderImpl::OnAlsConfigCheckDone(const bool is_config_valid) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!is_config_valid) { - status_ = AlsInitStatus::kIncorrectConfig; - OnInitializationComplete(); - return; - } - RetryAlsPath(); }
diff --git a/chrome/browser/chromeos/power/auto_screen_brightness/als_reader_impl.h b/chrome/browser/chromeos/power/auto_screen_brightness/als_reader_impl.h index 4ba92484..2e0d951 100644 --- a/chrome/browser/chromeos/power/auto_screen_brightness/als_reader_impl.h +++ b/chrome/browser/chromeos/power/auto_screen_brightness/als_reader_impl.h
@@ -66,9 +66,6 @@ // Called when we've checked whether ALS is enabled. void OnAlsEnableCheckDone(bool is_enabled); - // Called when we've checked whether ALS config is valid. - void OnAlsConfigCheckDone(bool is_config_valid); - // Called when we've tried to read ALS path. If |path| is empty, it would // reschedule another attempt up to |kMaxInitialAttempts|. void OnAlsPathReadAttempted(const std::string& path);
diff --git a/chrome/browser/chromeos/power/auto_screen_brightness/als_reader_impl_unittest.cc b/chrome/browser/chromeos/power/auto_screen_brightness/als_reader_impl_unittest.cc index 8c96de07..0b22575 100644 --- a/chrome/browser/chromeos/power/auto_screen_brightness/als_reader_impl_unittest.cc +++ b/chrome/browser/chromeos/power/auto_screen_brightness/als_reader_impl_unittest.cc
@@ -109,12 +109,9 @@ histogram_tester_.ExpectBucketCount( histogram, static_cast<int>(AlsReader::AlsInitStatus::kDisabled), 1); histogram_tester_.ExpectBucketCount( - histogram, static_cast<int>(AlsReader::AlsInitStatus::kIncorrectConfig), - 1); - histogram_tester_.ExpectBucketCount( histogram, static_cast<int>(AlsReader::AlsInitStatus::kMissingPath), 1); - // Expect 3 errors from above + 1 success from before |FailForTesting|. - histogram_tester_.ExpectTotalCount(histogram, 4); + // Expect 2 errors from above + 1 success from before |FailForTesting|. + histogram_tester_.ExpectTotalCount(histogram, 3); } TEST_F(AlsReaderImplTest, OneAlsValue) {
diff --git a/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc b/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc index a51781f..2611f3f 100644 --- a/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc +++ b/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.cc
@@ -55,22 +55,14 @@ namespace bookmark_keys = bookmark_api_constants; namespace bookmark_manager_private = api::bookmark_manager_private; -namespace CanPaste = api::bookmark_manager_private::CanPaste; namespace Copy = api::bookmark_manager_private::Copy; -namespace CreateWithMetaInfo = - api::bookmark_manager_private::CreateWithMetaInfo; namespace Cut = api::bookmark_manager_private::Cut; namespace Drop = api::bookmark_manager_private::Drop; namespace GetSubtree = api::bookmark_manager_private::GetSubtree; -namespace GetMetaInfo = api::bookmark_manager_private::GetMetaInfo; namespace Paste = api::bookmark_manager_private::Paste; -namespace RedoInfo = api::bookmark_manager_private::GetRedoInfo; namespace RemoveTrees = api::bookmark_manager_private::RemoveTrees; -namespace SetMetaInfo = api::bookmark_manager_private::SetMetaInfo; namespace SortChildren = api::bookmark_manager_private::SortChildren; namespace StartDrag = api::bookmark_manager_private::StartDrag; -namespace UndoInfo = api::bookmark_manager_private::GetUndoInfo; -namespace UpdateMetaInfo = api::bookmark_manager_private::UpdateMetaInfo; namespace { @@ -200,58 +192,9 @@ bookmark_model_ = NULL; } -void BookmarkManagerPrivateEventRouter::OnWillChangeBookmarkMetaInfo( - BookmarkModel* model, - const BookmarkNode* node) { - DCHECK(prev_meta_info_.empty()); - if (node->GetMetaInfoMap()) - prev_meta_info_ = *node->GetMetaInfoMap(); -} - -void BookmarkManagerPrivateEventRouter::BookmarkMetaInfoChanged( - BookmarkModel* model, - const BookmarkNode* node) { - const BookmarkNode::MetaInfoMap* new_meta_info = node->GetMetaInfoMap(); - bookmark_manager_private::MetaInfoFields changes; - - // Identify changed/removed fields: - for (BookmarkNode::MetaInfoMap::const_iterator it = prev_meta_info_.begin(); - it != prev_meta_info_.end(); - ++it) { - if (!new_meta_info) { - changes.additional_properties[it->first] = ""; - } else { - auto new_meta_field = new_meta_info->find(it->first); - if (new_meta_field == new_meta_info->end()) { - changes.additional_properties[it->first] = ""; - } else if (it->second != new_meta_field->second) { - changes.additional_properties[it->first] = new_meta_field->second; - } - } - } - - // Identify added fields: - if (new_meta_info) { - for (auto it = new_meta_info->cbegin(); it != new_meta_info->cend(); ++it) { - auto prev_meta_field = prev_meta_info_.find(it->first); - if (prev_meta_field == prev_meta_info_.end()) - changes.additional_properties[it->first] = it->second; - } - } - - prev_meta_info_.clear(); - DispatchEvent(events::BOOKMARK_MANAGER_PRIVATE_ON_META_INFO_CHANGED, - bookmark_manager_private::OnMetaInfoChanged::kEventName, - bookmark_manager_private::OnMetaInfoChanged::Create( - base::NumberToString(node->id()), changes)); -} - BookmarkManagerPrivateAPI::BookmarkManagerPrivateAPI( content::BrowserContext* browser_context) : browser_context_(browser_context) { - EventRouter* event_router = EventRouter::Get(browser_context); - event_router->RegisterObserver( - this, bookmark_manager_private::OnMetaInfoChanged::kEventName); } BookmarkManagerPrivateAPI::~BookmarkManagerPrivateAPI() {} @@ -424,28 +367,6 @@ return true; } -bool BookmarkManagerPrivateCanPasteFunction::RunOnReady() { - std::unique_ptr<CanPaste::Params> params(CanPaste::Params::Create(*args_)); - EXTENSION_FUNCTION_VALIDATE(params); - - PrefService* prefs = user_prefs::UserPrefs::Get(GetProfile()); - if (!prefs->GetBoolean(bookmarks::prefs::kEditBookmarksEnabled)) { - SetResult(std::make_unique<base::Value>(false)); - return true; - } - - BookmarkModel* model = - BookmarkModelFactory::GetForBrowserContext(GetProfile()); - const BookmarkNode* parent_node = GetNodeFromString(model, params->parent_id); - if (!parent_node) { - error_ = bookmark_keys::kNoParentError; - return false; - } - bool can_paste = bookmarks::CanPasteFromClipboard(model, parent_node); - SetResult(std::make_unique<base::Value>(can_paste)); - return true; -} - bool BookmarkManagerPrivateSortChildrenFunction::RunOnReady() { if (!EditBookmarksEnabled()) return false; @@ -568,153 +489,6 @@ return true; } -bool BookmarkManagerPrivateCanEditFunction::RunOnReady() { - PrefService* prefs = user_prefs::UserPrefs::Get(GetProfile()); - SetResult(std::make_unique<base::Value>( - prefs->GetBoolean(bookmarks::prefs::kEditBookmarksEnabled))); - return true; -} - -bool BookmarkManagerPrivateRecordLaunchFunction::RunOnReady() { - RecordBookmarkLaunch(NULL, BOOKMARK_LAUNCH_LOCATION_MANAGER); - return true; -} - -bool BookmarkManagerPrivateCreateWithMetaInfoFunction::RunOnReady() { - if (!EditBookmarksEnabled()) - return false; - - std::unique_ptr<CreateWithMetaInfo::Params> params( - CreateWithMetaInfo::Params::Create(*args_)); - EXTENSION_FUNCTION_VALIDATE(params); - - BookmarkModel* model = - BookmarkModelFactory::GetForBrowserContext(GetProfile()); - const BookmarkNode* node = CreateBookmarkNode( - model, params->bookmark, ¶ms->meta_info.additional_properties); - if (!node) - return false; - - api::bookmarks::BookmarkTreeNode result_node = - bookmark_api_helpers::GetBookmarkTreeNode(GetManagedBookmarkService(), - node, false, false); - results_ = CreateWithMetaInfo::Results::Create(result_node); - - return true; -} - -bool BookmarkManagerPrivateGetMetaInfoFunction::RunOnReady() { - std::unique_ptr<GetMetaInfo::Params> params( - GetMetaInfo::Params::Create(*args_)); - EXTENSION_FUNCTION_VALIDATE(params); - - if (params->id) { - const BookmarkNode* node = GetBookmarkNodeFromId(*params->id); - if (!node) - return false; - - if (params->key) { - std::string value; - if (node->GetMetaInfo(*params->key, &value)) { - GetMetaInfo::Results::Value result; - result.as_string.reset(new std::string(value)); - results_ = GetMetaInfo::Results::Create(result); - } - } else { - GetMetaInfo::Results::Value result; - result.as_object.reset(new GetMetaInfo::Results::Value::Object); - - const BookmarkNode::MetaInfoMap* meta_info = node->GetMetaInfoMap(); - if (meta_info) { - BookmarkNode::MetaInfoMap::const_iterator itr; - base::DictionaryValue& temp = result.as_object->additional_properties; - for (itr = meta_info->begin(); itr != meta_info->end(); itr++) { - temp.SetKey(itr->first, base::Value(itr->second)); - } - } - results_ = GetMetaInfo::Results::Create(result); - } - } else { - if (params->key) { - error_ = bookmark_api_constants::kInvalidParamError; - return true; - } - - BookmarkModel* model = - BookmarkModelFactory::GetForBrowserContext(GetProfile()); - const BookmarkNode* node = model->root_node(); - - GetMetaInfo::Results::Value result; - result.as_object.reset(new GetMetaInfo::Results::Value::Object); - - bookmark_api_helpers::GetMetaInfo(*node, - &result.as_object->additional_properties); - - results_ = GetMetaInfo::Results::Create(result); - } - - return true; -} - -bool BookmarkManagerPrivateSetMetaInfoFunction::RunOnReady() { - if (!EditBookmarksEnabled()) - return false; - - std::unique_ptr<SetMetaInfo::Params> params( - SetMetaInfo::Params::Create(*args_)); - EXTENSION_FUNCTION_VALIDATE(params); - - const BookmarkNode* node = GetBookmarkNodeFromId(params->id); - if (!node) - return false; - - if (!CanBeModified(node)) - return false; - - BookmarkModel* model = - BookmarkModelFactory::GetForBrowserContext(GetProfile()); - if (model->is_permanent_node(node)) { - error_ = bookmark_keys::kModifySpecialError; - return false; - } - - model->SetNodeMetaInfo(node, params->key, params->value); - return true; -} - -bool BookmarkManagerPrivateUpdateMetaInfoFunction::RunOnReady() { - if (!EditBookmarksEnabled()) - return false; - - std::unique_ptr<UpdateMetaInfo::Params> params( - UpdateMetaInfo::Params::Create(*args_)); - EXTENSION_FUNCTION_VALIDATE(params); - - const BookmarkNode* node = GetBookmarkNodeFromId(params->id); - if (!node) - return false; - - if (!CanBeModified(node)) - return false; - - BookmarkModel* model = - BookmarkModelFactory::GetForBrowserContext(GetProfile()); - if (model->is_permanent_node(node)) { - error_ = bookmark_keys::kModifySpecialError; - return false; - } - - BookmarkNode::MetaInfoMap new_meta_info( - params->meta_info_changes.additional_properties); - if (node->GetMetaInfoMap()) { - new_meta_info.insert(node->GetMetaInfoMap()->begin(), - node->GetMetaInfoMap()->end()); - } - model->SetNodeMetaInfoMap(node, new_meta_info); - - return true; -} - bool BookmarkManagerPrivateRemoveTreesFunction::RunOnReady() { if (!EditBookmarksEnabled()) return false; @@ -755,30 +529,6 @@ return true; } -bool BookmarkManagerPrivateGetUndoInfoFunction::RunOnReady() { - UndoManager* undo_manager = - BookmarkUndoServiceFactory::GetForProfile(GetProfile())->undo_manager(); - - UndoInfo::Results::Result result; - result.enabled = undo_manager->undo_count() > 0; - result.label = base::UTF16ToUTF8(undo_manager->GetUndoLabel()); - - results_ = UndoInfo::Results::Create(result); - return true; -} - -bool BookmarkManagerPrivateGetRedoInfoFunction::RunOnReady() { - UndoManager* undo_manager = - BookmarkUndoServiceFactory::GetForProfile(GetProfile())->undo_manager(); - - RedoInfo::Results::Result result; - result.enabled = undo_manager->redo_count() > 0; - result.label = base::UTF16ToUTF8(undo_manager->GetRedoLabel()); - - results_ = RedoInfo::Results::Create(result); - return true; -} - WEB_CONTENTS_USER_DATA_KEY_IMPL(BookmarkManagerPrivateDragEventRouter) } // namespace extensions
diff --git a/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.h b/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.h index e24bc87..b73ca17 100644 --- a/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.h +++ b/chrome/browser/extensions/api/bookmark_manager_private/bookmark_manager_private_api.h
@@ -43,11 +43,6 @@ // bookmarks::BaseBookmarkModelObserver: void BookmarkModelChanged() override; void BookmarkModelBeingDeleted(bookmarks::BookmarkModel* model) override; - void OnWillChangeBookmarkMetaInfo( - bookmarks::BookmarkModel* model, - const bookmarks::BookmarkNode* node) override; - void BookmarkMetaInfoChanged(bookmarks::BookmarkModel* model, - const bookmarks::BookmarkNode* node) override; private: // Helper to actually dispatch an event to extension listeners. @@ -178,19 +173,6 @@ bool RunOnReady() override; }; -class BookmarkManagerPrivateCanPasteFunction - : public extensions::BookmarksFunction { - public: - DECLARE_EXTENSION_FUNCTION("bookmarkManagerPrivate.canPaste", - BOOKMARKMANAGERPRIVATE_CANPASTE) - - protected: - ~BookmarkManagerPrivateCanPasteFunction() override {} - - // ExtensionFunction: - bool RunOnReady() override; -}; - class BookmarkManagerPrivateSortChildrenFunction : public extensions::BookmarksFunction { public: @@ -243,84 +225,6 @@ bool RunOnReady() override; }; -class BookmarkManagerPrivateCanEditFunction - : public extensions::BookmarksFunction { - public: - DECLARE_EXTENSION_FUNCTION("bookmarkManagerPrivate.canEdit", - BOOKMARKMANAGERPRIVATE_CANEDIT) - - protected: - ~BookmarkManagerPrivateCanEditFunction() override {} - - // ExtensionFunction: - bool RunOnReady() override; -}; - -class BookmarkManagerPrivateRecordLaunchFunction - : public extensions::BookmarksFunction { - public: - DECLARE_EXTENSION_FUNCTION("bookmarkManagerPrivate.recordLaunch", - BOOKMARKMANAGERPRIVATE_RECORDLAUNCH) - - protected: - ~BookmarkManagerPrivateRecordLaunchFunction() override {} - - // ExtensionFunction: - bool RunOnReady() override; -}; - -class BookmarkManagerPrivateCreateWithMetaInfoFunction - : public extensions::BookmarksFunction { - public: - DECLARE_EXTENSION_FUNCTION("bookmarkManagerPrivate.createWithMetaInfo", - BOOKMARKMANAGERPRIVATE_CREATEWITHMETAINFO) - - protected: - ~BookmarkManagerPrivateCreateWithMetaInfoFunction() override {} - - // ExtensionFunction: - bool RunOnReady() override; -}; - -class BookmarkManagerPrivateGetMetaInfoFunction - : public extensions::BookmarksFunction { - public: - DECLARE_EXTENSION_FUNCTION("bookmarkManagerPrivate.getMetaInfo", - BOOKMARKMANAGERPRIVATE_GETMETAINFO) - - protected: - ~BookmarkManagerPrivateGetMetaInfoFunction() override {} - - // ExtensionFunction: - bool RunOnReady() override; -}; - -class BookmarkManagerPrivateSetMetaInfoFunction - : public extensions::BookmarksFunction { - public: - DECLARE_EXTENSION_FUNCTION("bookmarkManagerPrivate.setMetaInfo", - BOOKMARKMANAGERPRIVATE_SETMETAINFO) - - protected: - ~BookmarkManagerPrivateSetMetaInfoFunction() override {} - - // ExtensionFunction: - bool RunOnReady() override; -}; - -class BookmarkManagerPrivateUpdateMetaInfoFunction - : public extensions::BookmarksFunction { - public: - DECLARE_EXTENSION_FUNCTION("bookmarkManagerPrivate.updateMetaInfo", - BOOKMARKMANAGERPRIVATE_UPDATEMETAINFO) - - protected: - ~BookmarkManagerPrivateUpdateMetaInfoFunction() override {} - - // ExtensionFunction: - bool RunOnReady() override; -}; - class BookmarkManagerPrivateRemoveTreesFunction : public extensions::BookmarksFunction { public: @@ -360,32 +264,6 @@ bool RunOnReady() override; }; -class BookmarkManagerPrivateGetUndoInfoFunction - : public extensions::BookmarksFunction { - public: - DECLARE_EXTENSION_FUNCTION("bookmarkManagerPrivate.getUndoInfo", - BOOKMARKMANAGERPRIVATE_UNDOINFO) - - protected: - ~BookmarkManagerPrivateGetUndoInfoFunction() override {} - - // ExtensionFunction: - bool RunOnReady() override; -}; - -class BookmarkManagerPrivateGetRedoInfoFunction - : public extensions::BookmarksFunction { - public: - DECLARE_EXTENSION_FUNCTION("bookmarkManagerPrivate.getRedoInfo", - BOOKMARKMANAGERPRIVATE_REDOINFO) - - protected: - ~BookmarkManagerPrivateGetRedoInfoFunction() override {} - - // ExtensionFunction: - bool RunOnReady() override; -}; - } // namespace extensions #endif // CHROME_BROWSER_EXTENSIONS_API_BOOKMARK_MANAGER_PRIVATE_BOOKMARK_MANAGER_PRIVATE_API_H_
diff --git a/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.cc b/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.cc index b19f25d..be7b9253 100644 --- a/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.cc +++ b/chrome/browser/extensions/api/language_settings_private/language_settings_private_api.cc
@@ -34,11 +34,11 @@ #include "chrome/common/pref_names.h" #include "components/language/core/browser/language_model_manager.h" #include "components/language/core/browser/pref_names.h" +#include "components/language/core/common/language_util.h" #include "components/language/core/common/locale_util.h" #include "components/spellcheck/common/spellcheck_common.h" #include "components/translate/core/browser/translate_download_manager.h" #include "components/translate/core/browser/translate_prefs.h" -#include "components/translate/core/common/translate_util.h" #include "third_party/icu/source/i18n/unicode/coll.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util_collator.h" @@ -288,7 +288,7 @@ std::vector<std::string> languages; translate_prefs->GetLanguageList(&languages); std::string chrome_language = language_code; - translate::ToChromeLanguageSynonym(&chrome_language); + language::ToChromeLanguageSynonym(&chrome_language); if (base::ContainsValue(languages, chrome_language)) { LOG(ERROR) << "Language " << chrome_language << " already enabled"; @@ -321,7 +321,7 @@ std::vector<std::string> languages; translate_prefs->GetLanguageList(&languages); std::string chrome_language = language_code; - translate::ToChromeLanguageSynonym(&chrome_language); + language::ToChromeLanguageSynonym(&chrome_language); if (!base::ContainsValue(languages, chrome_language)) { LOG(ERROR) << "Language " << chrome_language << " not enabled";
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index a3a9f40..2654ceb 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -48,11 +48,6 @@ "expiry_milestone": 76 }, { - "name": "WebRtcUseEchoCanceller3", - "owners": [ "peah@chromium.org", "gustaf@chromium.org" ], - "expiry_milestone": 76 - }, - { "name": "account-consistency", "owners": [ "droger", "msarda" ], "expiry_milestone": 80 @@ -500,8 +495,8 @@ }, { "name": "debug-packed-apps", - // "owners": [ "your-team" ], - "expiry_milestone": 76 + "owners": [ "benwells", "raymes" ], + "expiry_milestone": 88 }, { "name": "device-discovery-notifications", @@ -2905,11 +2900,6 @@ "expiry_milestone": 80 }, { - "name": "sound-content-setting", - // "owners": [ "your-team" ], - "expiry_milestone": 76 - }, - { "name": "spannable-inline-autocomplete", // "owners": [ "your-team" ], "expiry_milestone": 76
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index d1f02ab8..678e3ed1 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -1783,10 +1783,6 @@ "Enable Sole integration for browser customization. You must restart " "the browser twice for changes to take effect."; -const char kSoundContentSettingName[] = "Sound content setting"; -const char kSoundContentSettingDescription[] = - "Enable site-wide muting in content settings and tab strip context menu."; - const char kSpeculativeServiceWorkerStartOnQueryInputName[] = "Enable speculative start of a service worker when a search is predicted."; const char kSpeculativeServiceWorkerStartOnQueryInputDescription[] = @@ -2025,10 +2021,6 @@ const char kWebMidiName[] = "Web MIDI API"; const char kWebMidiDescription[] = "Enable Web MIDI API experimental support."; -const char kWebrtcEchoCanceller3Name[] = "WebRTC Echo Canceller 3."; -const char kWebrtcEchoCanceller3Description[] = - "Experimental WebRTC echo canceller (AEC3)."; - const char kWebrtcH264WithOpenh264FfmpegName[] = "WebRTC H.264 software video encoder/decoder"; const char kWebrtcH264WithOpenh264FfmpegDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index bf75c77..1dff92a13 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -1056,9 +1056,6 @@ extern const char kSoleIntegrationName[]; extern const char kSoleIntegrationDescription[]; -extern const char kSoundContentSettingName[]; -extern const char kSoundContentSettingDescription[]; - extern const char kSpeculativeServiceWorkerStartOnQueryInputName[]; extern const char kSpeculativeServiceWorkerStartOnQueryInputDescription[]; @@ -1199,9 +1196,6 @@ extern const char kWebMidiName[]; extern const char kWebMidiDescription[]; -extern const char kWebrtcEchoCanceller3Name[]; -extern const char kWebrtcEchoCanceller3Description[]; - extern const char kWebrtcH264WithOpenh264FfmpegName[]; extern const char kWebrtcH264WithOpenh264FfmpegDescription[];
diff --git a/chrome/browser/installable/installable_ambient_badge_infobar_delegate.cc b/chrome/browser/installable/installable_ambient_badge_infobar_delegate.cc index 66f2fe56..d973b28e 100644 --- a/chrome/browser/installable/installable_ambient_badge_infobar_delegate.cc +++ b/chrome/browser/installable/installable_ambient_badge_infobar_delegate.cc
@@ -6,13 +6,16 @@ #include <memory> +#include "base/feature_list.h" +#include "base/metrics/field_trial_params.h" #include "chrome/browser/infobars/infobar_service.h" #include "chrome/browser/ui/android/infobars/installable_ambient_badge_infobar.h" +#include "chrome/common/chrome_features.h" #include "chrome/grit/generated_resources.h" #include "ui/base/l10n/l10n_util.h" InstallableAmbientBadgeInfoBarDelegate:: - ~InstallableAmbientBadgeInfoBarDelegate() {} + ~InstallableAmbientBadgeInfoBarDelegate() = default; // static void InstallableAmbientBadgeInfoBarDelegate::Create( @@ -37,7 +40,18 @@ const base::string16 InstallableAmbientBadgeInfoBarDelegate::GetMessageText() const { - return l10n_util::GetStringFUTF16(IDS_AMBIENT_BADGE_INSTALL, app_name_); + if (!base::FeatureList::IsEnabled(features::kAddToHomescreenMessaging)) + return l10n_util::GetStringFUTF16(IDS_AMBIENT_BADGE_INSTALL, app_name_); + + bool include_no_download_required = base::GetFieldTrialParamByFeatureAsBool( + features::kAddToHomescreenMessaging, "include_no_download_required", + /* default_value= */ false); + + return l10n_util::GetStringFUTF16( + include_no_download_required + ? IDS_AMBIENT_BADGE_INSTALL_ALTERNATIVE_NO_DOWNLOAD_REQUIRED + : IDS_AMBIENT_BADGE_INSTALL_ALTERNATIVE, + app_name_); } const SkBitmap& InstallableAmbientBadgeInfoBarDelegate::GetPrimaryIcon() const {
diff --git a/chrome/browser/page_load_metrics/observers/amp_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/amp_page_load_metrics_observer.cc index 2e3ff51e..a276f66d 100644 --- a/chrome/browser/page_load_metrics/observers/amp_page_load_metrics_observer.cc +++ b/chrome/browser/page_load_metrics/observers/amp_page_load_metrics_observer.cc
@@ -16,6 +16,9 @@ #include "content/public/browser/navigation_handle.h" #include "content/public/browser/render_frame_host.h" #include "net/base/url_util.h" +#include "services/metrics/public/cpp/metrics_utils.h" +#include "services/metrics/public/cpp/ukm_builders.h" +#include "services/metrics/public/cpp/ukm_recorder.h" #include "url/gurl.h" namespace { @@ -341,10 +344,12 @@ } } - current_main_frame_nav_info_ = base::WrapUnique( - new MainFrameNavigationInfo{navigation_handle->GetURL(), subframe_rfh, - navigation_handle->NavigationStart(), - navigation_handle->IsSameDocument()}); + current_main_frame_nav_info_ = base::WrapUnique(new MainFrameNavigationInfo{ + navigation_handle->GetURL(), + ukm::ConvertToSourceId(navigation_handle->GetNavigationId(), + ukm::SourceIdType::NAVIGATION_ID), + subframe_rfh, navigation_handle->NavigationStart(), + navigation_handle->IsSameDocument()}); } void AMPPageLoadMetricsObserver::MaybeRecordAmpDocumentMetrics() { @@ -372,6 +377,11 @@ current_main_frame_nav_info_->navigation_start - subframe_info.navigation_start; + ukm::builders::AmpPageLoad builder( + current_main_frame_nav_info_->ukm_source_id); + builder.SetSubFrame_MainFrameToSubFrameNavigationDelta( + -navigation_input_delta.InMilliseconds()); + if (!current_main_frame_nav_info_->is_same_document_navigation) { // For non same document navigations, we expect the main frame navigation // to be before the subframe navigation. This measures the time from main @@ -402,6 +412,10 @@ if (!subframe_info.timing.is_null()) { if (subframe_info.timing->paint_timing->first_contentful_paint .has_value()) { + builder.SetSubFrame_PaintTiming_NavigationToFirstContentfulPaint( + subframe_info.timing->paint_timing->first_contentful_paint.value() + .InMilliseconds()); + base::TimeDelta first_contentful_paint = ClampToZero( subframe_info.timing->paint_timing->first_contentful_paint.value() - navigation_input_delta); @@ -425,6 +439,9 @@ if (AssignTimeAndSizeForLargestContentfulPaint( subframe_info.timing->paint_timing, &largest_content_paint_time, &largest_content_paint_size, &largest_content_type)) { + builder.SetSubFrame_PaintTiming_NavigationToLargestContentPaint( + largest_content_paint_time.value().InMilliseconds()); + // Adjust by the navigation_input_delta. largest_content_paint_time = ClampToZero( largest_content_paint_time.value() - navigation_input_delta); @@ -443,6 +460,10 @@ if (subframe_info.timing->interactive_timing->first_input_delay .has_value()) { + builder.SetSubFrame_InteractiveTiming_FirstInputDelay3( + subframe_info.timing->interactive_timing->first_input_delay.value() + .InMilliseconds()); + if (current_main_frame_nav_info_->is_same_document_navigation) { UMA_HISTOGRAM_CUSTOM_TIMES( std::string(kHistogramPrefix) @@ -460,6 +481,8 @@ } } } + + builder.Record(ukm::UkmRecorder::Get()); } // static
diff --git a/chrome/browser/page_load_metrics/observers/amp_page_load_metrics_observer.h b/chrome/browser/page_load_metrics/observers/amp_page_load_metrics_observer.h index 408e969c..30d28cf8 100644 --- a/chrome/browser/page_load_metrics/observers/amp_page_load_metrics_observer.h +++ b/chrome/browser/page_load_metrics/observers/amp_page_load_metrics_observer.h
@@ -96,6 +96,8 @@ struct MainFrameNavigationInfo { GURL url; + ukm::SourceId ukm_source_id = ukm::kInvalidSourceId; + // Pointer to the RenderViewHost for the iframe hosting the AMP document // associated with the main frame AMP navigation. content::RenderFrameHost* subframe_rfh = nullptr;
diff --git a/chrome/browser/page_load_metrics/observers/amp_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/amp_page_load_metrics_observer_unittest.cc index 21b2d05d..028ce4e0 100644 --- a/chrome/browser/page_load_metrics/observers/amp_page_load_metrics_observer_unittest.cc +++ b/chrome/browser/page_load_metrics/observers/amp_page_load_metrics_observer_unittest.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/page_load_metrics/observers/amp_page_load_metrics_observer.h" #include <string> +#include <utility> #include "base/macros.h" #include "base/optional.h" @@ -16,6 +17,9 @@ #include "content/public/browser/web_contents.h" #include "content/public/test/navigation_simulator.h" #include "content/public/test/test_utils.h" +#include "services/metrics/public/cpp/metrics_utils.h" +#include "services/metrics/public/cpp/ukm_builders.h" +#include "services/metrics/public/cpp/ukm_source.h" #include "url/gurl.h" using content::NavigationSimulator; @@ -101,6 +105,16 @@ 1); } + ukm::mojom::UkmEntryPtr GetAmpPageLoadUkmEntry() { + std::map<ukm::SourceId, ukm::mojom::UkmEntryPtr> entries = + test_ukm_recorder().GetMergedEntriesByName( + ukm::builders::AmpPageLoad::kEntryName); + if (entries.size() != 1ul) { + return nullptr; + } + return std::move(entries.begin()->second); + } + protected: void RegisterObservers(page_load_metrics::PageLoadTracker* tracker) override { tracker->AddObserver(base::WrapUnique(new AMPPageLoadMetricsObserver())); @@ -143,31 +157,49 @@ TEST_F(AMPPageLoadMetricsObserverTest, AMPCachePage) { RunTest(GURL("https://cdn.ampproject.org/page")); ValidateHistograms(true, "AmpCache."); + EXPECT_TRUE(test_ukm_recorder() + .GetEntriesByName(ukm::builders::AmpPageLoad::kEntryName) + .empty()); } TEST_F(AMPPageLoadMetricsObserverTest, GoogleSearchAMPCachePage) { RunTest(GURL("https://www.google.com/amp/page")); ValidateHistograms(true, "GoogleSearch."); + EXPECT_TRUE(test_ukm_recorder() + .GetEntriesByName(ukm::builders::AmpPageLoad::kEntryName) + .empty()); } TEST_F(AMPPageLoadMetricsObserverTest, GoogleSearchAMPCachePageBaseURL) { RunTest(GURL("https://www.google.com/amp/")); ValidateHistograms(false, ""); + EXPECT_TRUE(test_ukm_recorder() + .GetEntriesByName(ukm::builders::AmpPageLoad::kEntryName) + .empty()); } TEST_F(AMPPageLoadMetricsObserverTest, GoogleNewsAMPCachePage) { RunTest(GURL("https://news.google.com/news/amp?page")); ValidateHistograms(true, "GoogleNews."); + EXPECT_TRUE(test_ukm_recorder() + .GetEntriesByName(ukm::builders::AmpPageLoad::kEntryName) + .empty()); } TEST_F(AMPPageLoadMetricsObserverTest, GoogleNewsAMPCachePageBaseURL) { RunTest(GURL("https://news.google.com/news/amp")); ValidateHistograms(false, ""); + EXPECT_TRUE(test_ukm_recorder() + .GetEntriesByName(ukm::builders::AmpPageLoad::kEntryName) + .empty()); } TEST_F(AMPPageLoadMetricsObserverTest, NonAMPPage) { RunTest(GURL("https://www.google.com/not-amp/page")); ValidateHistograms(false, ""); + EXPECT_TRUE(test_ukm_recorder() + .GetEntriesByName(ukm::builders::AmpPageLoad::kEntryName) + .empty()); } TEST_F(AMPPageLoadMetricsObserverTest, GoogleSearchAMPViewerSameDocument) { @@ -219,6 +251,10 @@ "PageLoad.Clients.AMP.Experimental.PageTiming." "MainFrameToSubFrameNavigationDelta.Subframe", 0); + + EXPECT_TRUE(test_ukm_recorder() + .GetEntriesByName(ukm::builders::AmpPageLoad::kEntryName) + .empty()); } TEST_F(AMPPageLoadMetricsObserverTest, GoogleNewsAMPCacheRedirect) { @@ -247,6 +283,8 @@ } TEST_F(AMPPageLoadMetricsObserverTest, SubFrameInputBeforeNavigation) { + GURL amp_url("https://www.google.com/amp/page"); + // This emulates the AMP subframe non-prerender flow: first we perform a // same-document navigation in the main frame to the AMP viewer URL, then we // create and navigate the subframe to an AMP cache URL. @@ -254,8 +292,7 @@ GURL("https://www.google.com/search"), main_rfh()) ->Commit(); - NavigationSimulator::CreateRendererInitiated( - GURL("https://www.google.com/amp/page"), main_rfh()) + NavigationSimulator::CreateRendererInitiated(amp_url, main_rfh()) ->CommitSameDocument(); NavigationSimulator::NavigateAndCommitFromDocument( @@ -279,9 +316,20 @@ "PageLoad.Clients.AMP.Experimental.PageTiming." "MainFrameToSubFrameNavigationDelta.Subframe", 0); + + // We expect a source with a negative NavigationDelta metric, since the main + // frame navigation occurred before the AMP subframe navigation. + ukm::mojom::UkmEntryPtr entry = GetAmpPageLoadUkmEntry(); + test_ukm_recorder().ExpectEntrySourceHasUrl(entry.get(), amp_url); + const int64_t* nav_delta_metric = test_ukm_recorder().GetEntryMetric( + entry.get(), "SubFrame.MainFrameToSubFrameNavigationDelta"); + EXPECT_NE(nullptr, nav_delta_metric); + EXPECT_GE(*nav_delta_metric, 0ll); } TEST_F(AMPPageLoadMetricsObserverTest, SubFrameNavigationBeforeInput) { + GURL amp_url("https://www.google.com/amp/page"); + // This emulates the AMP subframe prerender flow: first we create and navigate // the subframe to an AMP cache URL, then we perform a same-document // navigation in the main frame to the AMP viewer URL. @@ -295,8 +343,7 @@ content::RenderFrameHostTester::For(web_contents()->GetMainFrame()) ->AppendChild("subframe")); - NavigationSimulator::CreateRendererInitiated( - GURL("https://www.google.com/amp/page"), main_rfh()) + NavigationSimulator::CreateRendererInitiated(amp_url, main_rfh()) ->CommitSameDocument(); // Navigate the main frame to trigger metrics recording. @@ -314,15 +361,25 @@ "PageLoad.Clients.AMP.Experimental.PageTiming." "MainFrameToSubFrameNavigationDelta.Subframe", 0); + + // We expect a source with a positive NavigationDelta metric, since the main + // frame navigation occurred after the AMP subframe navigation. + ukm::mojom::UkmEntryPtr entry = GetAmpPageLoadUkmEntry(); + test_ukm_recorder().ExpectEntrySourceHasUrl(entry.get(), amp_url); + const int64_t* nav_delta_metric = test_ukm_recorder().GetEntryMetric( + entry.get(), "SubFrame.MainFrameToSubFrameNavigationDelta"); + EXPECT_NE(nullptr, nav_delta_metric); + EXPECT_LE(*nav_delta_metric, 0ll); } TEST_F(AMPPageLoadMetricsObserverTest, SubFrameMetrics) { + GURL amp_url("https://www.google.com/amp/page"); + NavigationSimulator::CreateRendererInitiated( GURL("https://www.google.com/search"), main_rfh()) ->Commit(); - NavigationSimulator::CreateRendererInitiated( - GURL("https://www.google.com/amp/page"), main_rfh()) + NavigationSimulator::CreateRendererInitiated(amp_url, main_rfh()) ->CommitSameDocument(); content::RenderFrameHost* subframe = @@ -361,12 +418,21 @@ 1); histogram_tester().ExpectTotalCount( "PageLoad.Clients.AMP.InteractiveTiming.FirstInputDelay3.Subframe", 1); + + ukm::mojom::UkmEntryPtr entry = GetAmpPageLoadUkmEntry(); + test_ukm_recorder().ExpectEntrySourceHasUrl(entry.get(), amp_url); + test_ukm_recorder().ExpectEntryMetric( + entry.get(), "SubFrame.InteractiveTiming.FirstInputDelay3", 3); + test_ukm_recorder().ExpectEntryMetric( + entry.get(), "SubFrame.PaintTiming.NavigationToFirstContentfulPaint", 5); + test_ukm_recorder().ExpectEntryMetric( + entry.get(), "SubFrame.PaintTiming.NavigationToLargestContentPaint", 10); } TEST_F(AMPPageLoadMetricsObserverTest, SubFrameMetricsFullNavigation) { - NavigationSimulator::CreateRendererInitiated( - GURL("https://www.google.com/amp/page"), main_rfh()) - ->Commit(); + GURL amp_url("https://www.google.com/amp/page"); + + NavigationSimulator::CreateRendererInitiated(amp_url, main_rfh())->Commit(); content::RenderFrameHost* subframe = NavigationSimulator::NavigateAndCommitFromDocument( @@ -408,15 +474,25 @@ "PageLoad.Clients.AMP.InteractiveTiming.FirstInputDelay3.Subframe." "FullNavigation", 1); + + ukm::mojom::UkmEntryPtr entry = GetAmpPageLoadUkmEntry(); + test_ukm_recorder().ExpectEntrySourceHasUrl(entry.get(), amp_url); + test_ukm_recorder().ExpectEntryMetric( + entry.get(), "SubFrame.InteractiveTiming.FirstInputDelay3", 3); + test_ukm_recorder().ExpectEntryMetric( + entry.get(), "SubFrame.PaintTiming.NavigationToFirstContentfulPaint", 5); + test_ukm_recorder().ExpectEntryMetric( + entry.get(), "SubFrame.PaintTiming.NavigationToLargestContentPaint", 10); } TEST_F(AMPPageLoadMetricsObserverTest, SubFrameRecordOnFullNavigation) { + GURL amp_url("https://www.google.com/amp/page"); + NavigationSimulator::CreateRendererInitiated( GURL("https://www.google.com/search"), main_rfh()) ->Commit(); - NavigationSimulator::CreateRendererInitiated( - GURL("https://www.google.com/amp/page"), main_rfh()) + NavigationSimulator::CreateRendererInitiated(amp_url, main_rfh()) ->CommitSameDocument(); NavigationSimulator::NavigateAndCommitFromDocument( @@ -433,15 +509,25 @@ histogram_tester().ExpectTotalCount( "PageLoad.Clients.AMP.Experimental.PageTiming.InputToNavigation.Subframe", 1); + + // We expect a source with a negative NavigationDelta metric, since the main + // frame navigation occurred before the AMP subframe navigation. + ukm::mojom::UkmEntryPtr entry = GetAmpPageLoadUkmEntry(); + test_ukm_recorder().ExpectEntrySourceHasUrl(entry.get(), amp_url); + const int64_t* nav_delta_metric = test_ukm_recorder().GetEntryMetric( + entry.get(), "SubFrame.MainFrameToSubFrameNavigationDelta"); + EXPECT_NE(nullptr, nav_delta_metric); + EXPECT_GE(*nav_delta_metric, 0ll); } TEST_F(AMPPageLoadMetricsObserverTest, SubFrameRecordOnFrameDeleted) { + GURL amp_url("https://www.google.com/amp/page"); + NavigationSimulator::CreateRendererInitiated( GURL("https://www.google.com/search"), main_rfh()) ->Commit(); - NavigationSimulator::CreateRendererInitiated( - GURL("https://www.google.com/amp/page"), main_rfh()) + NavigationSimulator::CreateRendererInitiated(amp_url, main_rfh()) ->CommitSameDocument(); content::RenderFrameHost* subframe = @@ -461,9 +547,21 @@ histogram_tester().ExpectTotalCount( "PageLoad.Clients.AMP.Experimental.PageTiming.InputToNavigation.Subframe", 1); + + // We expect a source with a negative NavigationDelta metric, since the main + // frame navigation occurred before the AMP subframe navigation. + ukm::mojom::UkmEntryPtr entry = GetAmpPageLoadUkmEntry(); + test_ukm_recorder().ExpectEntrySourceHasUrl(entry.get(), amp_url); + const int64_t* nav_delta_metric = test_ukm_recorder().GetEntryMetric( + entry.get(), "SubFrame.MainFrameToSubFrameNavigationDelta"); + EXPECT_NE(nullptr, nav_delta_metric); + EXPECT_GE(*nav_delta_metric, 0ll); } TEST_F(AMPPageLoadMetricsObserverTest, SubFrameMultipleFrames) { + GURL amp_url1("https://www.google.com/amp/page"); + GURL amp_url2("https://www.google.com/amp/page2"); + NavigationSimulator::CreateRendererInitiated( GURL("https://www.google.com/search"), main_rfh()) ->Commit(); @@ -477,8 +575,7 @@ // Perform a main-frame navigation to a different AMP document (not the // prerender). - NavigationSimulator::CreateRendererInitiated( - GURL("https://www.google.com/amp/page"), main_rfh()) + NavigationSimulator::CreateRendererInitiated(amp_url1, main_rfh()) ->CommitSameDocument(); // Load the associated AMP document in an iframe. @@ -507,8 +604,7 @@ // Now navigate to the main-frame URL for the prerendered AMP document. This // should trigger metrics recording for that document. - NavigationSimulator::CreateRendererInitiated( - GURL("https://www.google.com/amp/page2"), main_rfh()) + NavigationSimulator::CreateRendererInitiated(amp_url2, main_rfh()) ->CommitSameDocument(); // Navigate the main frame to trigger metrics recording. @@ -528,13 +624,53 @@ "PageLoad.Clients.AMP.Experimental.PageTiming." "MainFrameToSubFrameNavigationDelta.Subframe", 0); + + std::map<ukm::SourceId, ukm::mojom::UkmEntryPtr> entries = + test_ukm_recorder().GetMergedEntriesByName( + ukm::builders::AmpPageLoad::kEntryName); + EXPECT_EQ(2ull, entries.size()); + + const ukm::UkmSource* source1 = nullptr; + const ukm::UkmSource* source2 = nullptr; + for (const auto& kv : entries) { + const ukm::UkmSource* candidate = + test_ukm_recorder().GetSourceForSourceId(kv.first); + ASSERT_NE(nullptr, candidate); + if (candidate->url() == amp_url1) { + source1 = candidate; + } else if (candidate->url() == amp_url2) { + source2 = candidate; + } else { + FAIL() << "Encountered unexpected source for: " << candidate->url(); + } + } + EXPECT_NE(source1, source2); + + const ukm::mojom::UkmEntry* entry1 = entries.at(source1->id()).get(); + EXPECT_NE(nullptr, entry1); + const ukm::mojom::UkmEntry* entry2 = entries.at(source2->id()).get(); + EXPECT_NE(nullptr, entry2); + + // The entry for amp_url1 should have a negative NavigationDelta metric, since + // the main frame navigation occurred before the AMP subframe navigation. + const int64_t* entry1_nav_delta_metric = test_ukm_recorder().GetEntryMetric( + entry1, "SubFrame.MainFrameToSubFrameNavigationDelta"); + EXPECT_NE(nullptr, entry1_nav_delta_metric); + EXPECT_GE(*entry1_nav_delta_metric, 0ll); + + // The entry for amp_url2 should have a positive NavigationDelta metric, since + // the main frame navigation occurred after the AMP subframe navigation. + const int64_t* entry2_nav_delta_metric = test_ukm_recorder().GetEntryMetric( + entry2, "SubFrame.MainFrameToSubFrameNavigationDelta"); + EXPECT_NE(nullptr, entry2_nav_delta_metric); + EXPECT_LE(*entry2_nav_delta_metric, 0ll); } TEST_F(AMPPageLoadMetricsObserverTest, SubFrameWithNonSameDocumentMainFrameNavigation) { - NavigationSimulator::CreateRendererInitiated( - GURL("https://www.google.com/amp/page"), main_rfh()) - ->Commit(); + GURL amp_url("https://www.google.com/amp/page"); + + NavigationSimulator::CreateRendererInitiated(amp_url, main_rfh())->Commit(); // Load the associated AMP document in an iframe. NavigationSimulator::NavigateAndCommitFromDocument( @@ -559,6 +695,15 @@ "PageLoad.Clients.AMP.Experimental.PageTiming." "MainFrameToSubFrameNavigationDelta.Subframe", 1); + + // We expect a source with a negative NavigationDelta metric, since the main + // frame navigation occurred before the AMP subframe navigation. + ukm::mojom::UkmEntryPtr entry = GetAmpPageLoadUkmEntry(); + test_ukm_recorder().ExpectEntrySourceHasUrl(entry.get(), amp_url); + const int64_t* nav_delta_metric = test_ukm_recorder().GetEntryMetric( + entry.get(), "SubFrame.MainFrameToSubFrameNavigationDelta"); + EXPECT_NE(nullptr, nav_delta_metric); + EXPECT_GE(*nav_delta_metric, 0ll); } TEST_F(AMPPageLoadMetricsObserverTest, @@ -592,6 +737,10 @@ "PageLoad.Clients.AMP.Experimental.PageTiming." "MainFrameToSubFrameNavigationDelta.Subframe", 0); + + EXPECT_TRUE(test_ukm_recorder() + .GetEntriesByName(ukm::builders::AmpPageLoad::kEntryName) + .empty()); } TEST_F(AMPPageLoadMetricsObserverTest, @@ -624,4 +773,8 @@ "PageLoad.Clients.AMP.Experimental.PageTiming." "MainFrameToSubFrameNavigationDelta.Subframe", 0); + + EXPECT_TRUE(test_ukm_recorder() + .GetEntriesByName(ukm::builders::AmpPageLoad::kEntryName) + .empty()); }
diff --git a/chrome/browser/pdf/pdf_extension_test.cc b/chrome/browser/pdf/pdf_extension_test.cc index c7abd4c..ca4d8c2 100644 --- a/chrome/browser/pdf/pdf_extension_test.cc +++ b/chrome/browser/pdf/pdf_extension_test.cc
@@ -678,7 +678,7 @@ #if defined(OS_CHROMEOS) // TODO(https://crbug.com/920684): Test times out. #if defined(MEMORY_SANITIZER) || defined(LEAK_SANITIZER) || \ - defined(ADDRESS_SANITIZER) + defined(ADDRESS_SANITIZER) || defined(_DEBUG) #define MAYBE_AnnotationsFeatureEnabled DISABLED_AnnotationsFeatureEnabled #else #define MAYBE_AnnotationsFeatureEnabled AnnotationsFeatureEnabled
diff --git a/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.html b/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.html index 97ea9b2..965e0e57f 100644 --- a/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.html +++ b/chrome/browser/resources/pdf/elements/viewer-pdf-toolbar/viewer-pdf-toolbar.html
@@ -50,11 +50,20 @@ } paper-icon-button { - margin-inline-end: 12px; + height: 36px; + margin: 6px; + padding: 8px; + width: 36px; } - viewer-toolbar-dropdown { - margin-inline-end: 4px; + paper-icon-button:hover { + background: rgba(255, 255, 255, 0.08); + border-radius: 50%; + } + + paper-icon-button:focus { + --paper-icon-button-ink-color:white; + --paper-ripple-opacity: 0.24; } paper-progress { @@ -100,33 +109,45 @@ --dropdown-width: 346px; } - #eraser:not([selected]), - #pen:not([selected]), - #highlighter:not([selected]) { - --pen-tip-fill: currentcolor !important; - --pen-tip-border: currentcolor !important; - } - #pen, #highlighter { --dropdown-open-background: rgb(50, 54, 57); } - #eraser[selected] { - background-color: rgb(50, 54, 57); - border-radius: 4px; + #eraser { + opacity: 0.38; + } + + #eraser[selected], + #eraser:focus, + #eraser:hover { + opacity: 1; } #annotation-separator { - background: rgb(151, 152, 152); + background: white; height: 30px; margin-inline-end: 12px; + margin-inline-start: 12px; + opacity: 0.38; width: 1px; } :host([annotation-mode]) #annotate { - background-color: rgb(25, 27, 29); - border-radius: 4px; + background-color: rgba(255, 255, 255, 0.24); + border-radius: 50%; + } + + #bookmarks { + margin-inline-start: 8px; + } + + #pen { + margin-inline-end: 10px; + } + + #highlighter { + margin-inline-end: 6px; } .invisible { @@ -200,6 +221,7 @@ </paper-icon-button> <viewer-toolbar-dropdown id="bookmarks" + selected metrics-id="bookmarks" hidden$="[[!bookmarks.length]]" open-icon="pdf:bookmark"
diff --git a/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.html b/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.html index 1568f0c..af6a8b1e 100644 --- a/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.html +++ b/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.html
@@ -1,6 +1,6 @@ <link rel="import" href="chrome://resources/html/polymer.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> <link rel="import" href="chrome://resources/cr_elements/icons.html"> <link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> @@ -8,6 +8,7 @@ <template> <style> :host { + display: inline-block; position: relative; text-align: start; --dropdown-width: 260px; @@ -43,20 +44,37 @@ padding: 6px 0 4px 0; } - #icon { + #button { + border-radius: 4px; cursor: pointer; display: inline-block; + height: 32px; + margin: 0; + min-width: 48px; + opacity: 0.38; + padding-bottom: 6px; + padding-inline-end: 2px; + padding-inline-start: 6px; + padding-top: 6px; + width: 48px; } - :host([dropdown-open]) #icon, - :host([selected]) #icon { - background-color: var(--dropdown-open-background, rgb(25, 27, 29)); - border-radius: 4px; + #button:focus { + background-color: rgba(255, 255, 255, 0.24); + opacity: 1; } - #arrow { - margin-inline-start: -8px; - padding-inline-end: 4px; + #button:hover { + background-color: rgba(255, 255, 255, 0.08); + opacity: 1; + } + + :host([selected]) #button { + opacity: 1; + + } + :host([dropdown-open]) #button { + background-color: rgba(255, 255, 255, 0.24); } h1 { @@ -67,12 +85,11 @@ padding: 14px 28px; } </style> - <div on-click="toggleDropdown" id="icon"> - <paper-icon-button id="main-icon" icon="[[dropdownIcon]]" + <paper-button on-click="toggleDropdown" id="button" aria-label$="{{header}}" title$="{{header}}"> - </paper-icon-button> - <iron-icon icon="cr:arrow-drop-down" id="arrow"></iron-icon> - </div> + <iron-icon icon="[[dropdownIcon]]"></iron-icon> + <iron-icon icon="cr:arrow-drop-down"></iron-icon> + </paper-button> <div id="container"> <div id="dropdown" style="display: none">
diff --git a/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.js b/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.js index 0ce8ebd..05f044a 100644 --- a/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.js +++ b/chrome/browser/resources/pdf/elements/viewer-toolbar-dropdown/viewer-toolbar-dropdown.js
@@ -101,6 +101,7 @@ } if (this.dropdownOpen) { this.toggleDropdown(); + this.blur(); } // Clean up the handler. The dropdown may already be closed. window.removeEventListener('pointerdown', listener);
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_page.html b/chrome/browser/resources/settings/privacy_page/privacy_page.html index eb8897a..750900df 100644 --- a/chrome/browser/resources/settings/privacy_page/privacy_page.html +++ b/chrome/browser/resources/settings/privacy_page/privacy_page.html
@@ -368,33 +368,30 @@ </category-setting-exceptions> </settings-subpage> </template> - <template is="dom-if" if="[[enableSoundContentSetting_]]" - no-search> - <template is="dom-if" route-path="/content/sound" no-search> - <settings-subpage page-title="$i18n{siteSettingsSound}" - search-label="$i18n{siteSettingsAllSitesSearch}" - search-term="{{searchFilter_}}"> - <category-default-setting - toggle-off-label="$i18n{siteSettingsSoundBlock}" - toggle-on-label="$i18n{siteSettingsSoundAllowRecommended}" - category="{{ContentSettingsTypes.SOUND}}"> - </category-default-setting> - <settings-toggle-button - id="block-autoplay-setting" - label="$i18n{siteSettingsBlockAutoplaySetting}" - pref="{{blockAutoplayStatus_.pref}}" - disabled="[[!blockAutoplayStatus_.enabled]]" - hidden="[[!enableBlockAutoplayContentSetting_]]" - on-settings-boolean-control-change="onBlockAutoplayToggleChange_" - no-set-pref> - </settings-toggle-button> - <category-setting-exceptions - category="{{ContentSettingsTypes.SOUND}}" - block-header="$i18n{siteSettingsBlockSound}" - search-filter="[[searchFilter_]]"> - </category-setting-exceptions> - </settings-subpage> - </template> + <template is="dom-if" route-path="/content/sound" no-search> + <settings-subpage page-title="$i18n{siteSettingsSound}" + search-label="$i18n{siteSettingsAllSitesSearch}" + search-term="{{searchFilter_}}"> + <category-default-setting + toggle-off-label="$i18n{siteSettingsSoundBlock}" + toggle-on-label="$i18n{siteSettingsSoundAllowRecommended}" + category="{{ContentSettingsTypes.SOUND}}"> + </category-default-setting> + <settings-toggle-button + id="block-autoplay-setting" + label="$i18n{siteSettingsBlockAutoplaySetting}" + pref="{{blockAutoplayStatus_.pref}}" + disabled="[[!blockAutoplayStatus_.enabled]]" + hidden="[[!enableBlockAutoplayContentSetting_]]" + on-settings-boolean-control-change="onBlockAutoplayToggleChange_" + no-set-pref> + </settings-toggle-button> + <category-setting-exceptions + category="{{ContentSettingsTypes.SOUND}}" + block-header="$i18n{siteSettingsBlockSound}" + search-filter="[[searchFilter_]]"> + </category-setting-exceptions> + </settings-subpage> </template> <template is="dom-if" route-path="/content/microphone" no-search> <settings-subpage page-title="$i18n{siteSettingsCategoryMicrophone}"
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_page.js b/chrome/browser/resources/settings/privacy_page/privacy_page.js index 25f9482..7b09438 100644 --- a/chrome/browser/resources/settings/privacy_page/privacy_page.js +++ b/chrome/browser/resources/settings/privacy_page/privacy_page.js
@@ -95,14 +95,6 @@ }, /** @private */ - enableSoundContentSetting_: { - type: Boolean, - value: function() { - return loadTimeData.getBoolean('enableSoundContentSetting'); - } - }, - - /** @private */ enableBlockAutoplayContentSetting_: { type: Boolean, value: function() {
diff --git a/chrome/browser/resources/settings/site_settings/site_settings_behavior.js b/chrome/browser/resources/settings/site_settings/site_settings_behavior.js index 9da594f..75bb6d5 100644 --- a/chrome/browser/resources/settings/site_settings/site_settings_behavior.js +++ b/chrome/browser/resources/settings/site_settings/site_settings_behavior.js
@@ -198,8 +198,6 @@ settings.ContentSettingsTypes.ADS, 'enableSafeBrowsingSubresourceFilter'); addOrRemoveSettingWithFlag( - settings.ContentSettingsTypes.SOUND, 'enableSoundContentSetting'); - addOrRemoveSettingWithFlag( settings.ContentSettingsTypes.CLIPBOARD, 'enableClipboardContentSetting'); addOrRemoveSettingWithFlag(
diff --git a/chrome/browser/resources/settings/site_settings_page/site_settings_page.html b/chrome/browser/resources/settings/site_settings_page/site_settings_page.html index cad7ce8e..3109d09 100644 --- a/chrome/browser/resources/settings/site_settings_page/site_settings_page.html +++ b/chrome/browser/resources/settings/site_settings_page/site_settings_page.html
@@ -137,15 +137,13 @@ '$i18nPolymer{siteSettingsAllowRecentlyClosedSites}', '$i18nPolymer{siteSettingsBackgroundSyncBlocked}')]]"></cr-link-row> - <template is="dom-if" if="[[enableSoundContentSetting_]]"> - <cr-link-row class="hr two-line" data-route="SITE_SETTINGS_SOUND" - id="sound" label="$i18n{siteSettingsSound}" on-click="onTapNavigate_" - start-icon="settings:volume-up" - sub-label="[[defaultSettingLabel_( - default_.sound, - '$i18nPolymer{siteSettingsSoundAllow}', - '$i18nPolymer{siteSettingsSoundBlock}')]]"></cr-link-row> - </template> + <cr-link-row class="hr two-line" data-route="SITE_SETTINGS_SOUND" + id="sound" label="$i18n{siteSettingsSound}" on-click="onTapNavigate_" + start-icon="settings:volume-up" + sub-label="[[defaultSettingLabel_( + default_.sound, + '$i18nPolymer{siteSettingsSoundAllow}', + '$i18nPolymer{siteSettingsSoundBlock}')]]"></cr-link-row> <cr-link-row class="hr two-line" data-route="SITE_SETTINGS_AUTOMATIC_DOWNLOADS" id="automatic-downloads"
diff --git a/chrome/browser/resources/settings/site_settings_page/site_settings_page.js b/chrome/browser/resources/settings/site_settings_page/site_settings_page.js index 685ad1a..0905c39 100644 --- a/chrome/browser/resources/settings/site_settings_page/site_settings_page.js +++ b/chrome/browser/resources/settings/site_settings_page/site_settings_page.js
@@ -60,14 +60,6 @@ }, /** @private */ - enableSoundContentSetting_: { - type: Boolean, - value: function() { - return loadTimeData.getBoolean('enableSoundContentSetting'); - } - }, - - /** @private */ enableSensorsContentSetting_: { type: Boolean, readOnly: true,
diff --git a/chrome/browser/signin/identity_test_environment_profile_adaptor.cc b/chrome/browser/signin/identity_test_environment_profile_adaptor.cc index 5c856bd..5de5dcd5 100644 --- a/chrome/browser/signin/identity_test_environment_profile_adaptor.cc +++ b/chrome/browser/signin/identity_test_environment_profile_adaptor.cc
@@ -12,24 +12,11 @@ #include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" #include "chrome/browser/signin/signin_manager_factory.h" -#include "components/signin/core/browser/fake_account_fetcher_service.h" #include "components/signin/core/browser/fake_profile_oauth2_token_service.h" +#include "components/signin/core/browser/test_image_decoder.h" namespace { -// Testing factory that creates a FakeAccountFetcherService. -std::unique_ptr<KeyedService> BuildFakeAccountFetcherService( - content::BrowserContext* context) { - Profile* profile = Profile::FromBrowserContext(context); - auto account_fetcher_service = std::make_unique<FakeAccountFetcherService>(); - account_fetcher_service->Initialize( - ChromeSigninClientFactory::GetForProfile(profile), - ProfileOAuth2TokenServiceFactory::GetForProfile(profile), - AccountTrackerServiceFactory::GetForProfile(profile), - std::make_unique<TestImageDecoder>()); - return account_fetcher_service; -} - // Testing factory that creates a FakeProfileOAuth2TokenService. std::unique_ptr<KeyedService> BuildFakeProfileOAuth2TokenService( content::BrowserContext* context) { @@ -94,9 +81,7 @@ // static TestingProfile::TestingFactories IdentityTestEnvironmentProfileAdaptor::GetIdentityTestEnvironmentFactories() { - return {{AccountFetcherServiceFactory::GetInstance(), - base::BindRepeating(&BuildFakeAccountFetcherService)}, - {ProfileOAuth2TokenServiceFactory::GetInstance(), + return {{ProfileOAuth2TokenServiceFactory::GetInstance(), base::BindRepeating(&BuildFakeProfileOAuth2TokenService)}}; } @@ -120,11 +105,9 @@ : identity_test_env_( profile->GetPrefs(), AccountTrackerServiceFactory::GetForProfile(profile), - static_cast<FakeAccountFetcherService*>( - AccountFetcherServiceFactory::GetForProfile(profile)), + AccountFetcherServiceFactory::GetForProfile(profile), static_cast<FakeProfileOAuth2TokenService*>( ProfileOAuth2TokenServiceFactory::GetForProfile(profile)), SigninManagerFactory::GetForProfile(profile), GaiaCookieManagerServiceFactory::GetForProfile(profile), - IdentityManagerFactory::GetForProfile(profile)) { -} + IdentityManagerFactory::GetForProfile(profile)) {}
diff --git a/chrome/browser/supervised_user/supervised_user_url_filter.cc b/chrome/browser/supervised_user/supervised_user_url_filter.cc index 84812cb6..adcb55a8 100644 --- a/chrome/browser/supervised_user/supervised_user_url_filter.cc +++ b/chrome/browser/supervised_user/supervised_user_url_filter.cc
@@ -26,6 +26,7 @@ #include "chrome/browser/supervised_user/experimental/supervised_user_blacklist.h" #include "components/policy/core/browser/url_blacklist_manager.h" #include "components/policy/core/browser/url_util.h" +#include "components/safe_search_api/safe_search/safe_search_url_checker_client.h" #include "components/url_matcher/url_matcher.h" #include "components/variations/service/variations_service.h" #include "content/public/browser/browser_thread.h" @@ -551,7 +552,8 @@ country = variations_service->GetLatestCountry(); } async_url_checker_ = std::make_unique<safe_search_api::URLChecker>( - std::move(url_loader_factory), traffic_annotation, country); + std::make_unique<safe_search_api::SafeSearchURLCheckerClient>( + std::move(url_loader_factory), traffic_annotation, country)); } void SupervisedUserURLFilter::ClearAsyncURLChecker() {
diff --git a/chrome/browser/sync/sync_ui_util.cc b/chrome/browser/sync/sync_ui_util.cc index 978acbda..ffd4bd9 100644 --- a/chrome/browser/sync/sync_ui_util.cc +++ b/chrome/browser/sync/sync_ui_util.cc
@@ -24,21 +24,19 @@ namespace { // Returns the message that should be displayed when the user is authenticated -// and can connect to the sync server. If the user hasn't yet authenticated, an -// empty string is returned. +// and can connect to the sync server. If Sync hasn't finished initializing yet, +// an empty string is returned. base::string16 GetSyncedStateStatusLabel(const syncer::SyncService* service) { DCHECK(service); if (service->HasDisableReason( syncer::SyncService::DISABLE_REASON_ENTERPRISE_POLICY)) { - // User is signed in, but sync is disabled. return l10n_util::GetStringUTF16(IDS_SIGNED_IN_WITH_SYNC_DISABLED); } if (!service->GetUserSettings()->IsSyncRequested()) { - // User is signed in, but sync has been stopped. return l10n_util::GetStringUTF16(IDS_SIGNED_IN_WITH_SYNC_SUPPRESSED); } if (!service->IsSyncFeatureActive()) { - // User is not signed in, or sync is still initializing. + // Sync is still initializing. return base::string16(); } @@ -53,7 +51,6 @@ base::string16* status_label, base::string16* link_label, ActionType* action_type) { - DCHECK(action_type); switch (action) { case syncer::UPGRADE_CLIENT: if (status_label) { @@ -63,7 +60,9 @@ *link_label = l10n_util::GetStringUTF16(IDS_SYNC_UPGRADE_CLIENT_LINK_LABEL); } - *action_type = UPGRADE_CLIENT; + if (action_type) { + *action_type = UPGRADE_CLIENT; + } return true; case syncer::ENABLE_SYNC_ON_ACCOUNT: if (status_label) { @@ -89,21 +88,28 @@ // unrecoverable error message. if (!GetStatusForActionableError(action, status_label, link_label, action_type)) { - *action_type = REAUTHENTICATE; - *link_label = l10n_util::GetStringUTF16(IDS_SYNC_RELOGIN_LINK_LABEL); + if (action_type) { + *action_type = REAUTHENTICATE; + } + if (link_label) { + *link_label = l10n_util::GetStringUTF16(IDS_SYNC_RELOGIN_LINK_LABEL); + } + if (status_label) { #if !defined(OS_CHROMEOS) - *status_label = - l10n_util::GetStringUTF16(IDS_SYNC_STATUS_UNRECOVERABLE_ERROR); - // The message for managed accounts is the same as that of the cros. - if (!is_user_signout_allowed) { + if (is_user_signout_allowed) { + *status_label = + l10n_util::GetStringUTF16(IDS_SYNC_STATUS_UNRECOVERABLE_ERROR); + } else { + // The message for managed accounts is the same as that on ChromeOS. + *status_label = l10n_util::GetStringUTF16( + IDS_SYNC_STATUS_UNRECOVERABLE_ERROR_NEEDS_SIGNOUT); + } +#else *status_label = l10n_util::GetStringUTF16( IDS_SYNC_STATUS_UNRECOVERABLE_ERROR_NEEDS_SIGNOUT); - } -#else - *status_label = l10n_util::GetStringUTF16( - IDS_SYNC_STATUS_UNRECOVERABLE_ERROR_NEEDS_SIGNOUT); #endif + } } } @@ -113,17 +119,20 @@ base::string16* status_label, base::string16* link_label, ActionType* action_type) { - DCHECK(status_label); - DCHECK(link_label); switch (auth_error.state()) { case GoogleServiceAuthError::NONE: NOTREACHED(); break; case GoogleServiceAuthError::SERVICE_UNAVAILABLE: - *status_label = l10n_util::GetStringUTF16(IDS_SYNC_SERVICE_UNAVAILABLE); + if (status_label) { + *status_label = l10n_util::GetStringUTF16(IDS_SYNC_SERVICE_UNAVAILABLE); + } break; case GoogleServiceAuthError::CONNECTION_FAILED: - *status_label = l10n_util::GetStringUTF16(IDS_SYNC_SERVER_IS_UNREACHABLE); + if (status_label) { + *status_label = + l10n_util::GetStringUTF16(IDS_SYNC_SERVER_IS_UNREACHABLE); + } // Note that there is little the user can do if the server is not // reachable. Since attempting to re-connect is done automatically by // the Syncer, we do not show the (re)login link. @@ -133,14 +142,19 @@ case GoogleServiceAuthError::ACCOUNT_DELETED: case GoogleServiceAuthError::ACCOUNT_DISABLED: default: - *status_label = l10n_util::GetStringUTF16(IDS_SYNC_RELOGIN_ERROR); - *link_label = l10n_util::GetStringUTF16(IDS_SYNC_RELOGIN_LINK_LABEL); - *action_type = REAUTHENTICATE; + if (status_label) { + *status_label = l10n_util::GetStringUTF16(IDS_SYNC_RELOGIN_ERROR); + } + if (link_label) { + *link_label = l10n_util::GetStringUTF16(IDS_SYNC_RELOGIN_LINK_LABEL); + } + if (action_type) { + *action_type = REAUTHENTICATE; + } break; } } -// status_label and link_label must either be both null or both non-null. MessageType GetStatusLabelsImpl( const syncer::SyncService* service, bool is_user_signout_allowed, @@ -149,7 +163,6 @@ base::string16* link_label, ActionType* action_type) { DCHECK(service); - DCHECK_EQ(status_label == nullptr, link_label == nullptr); if (!service->IsAuthenticatedAccountPrimary()) { return PRE_SYNCED; @@ -164,11 +177,16 @@ // First check for an unrecoverable error. if (service->HasUnrecoverableError()) { - if (status_label && link_label) { - GetStatusForUnrecoverableError(is_user_signout_allowed, - status.sync_protocol_error.action, - status_label, link_label, action_type); - } + GetStatusForUnrecoverableError(is_user_signout_allowed, + status.sync_protocol_error.action, + status_label, link_label, action_type); + return SYNC_ERROR; + } + + // Then check for an auth error. + if (auth_error.state() != GoogleServiceAuthError::NONE && + auth_error.state() != GoogleServiceAuthError::TWO_FACTOR) { + GetStatusForAuthError(auth_error, status_label, link_label, action_type); return SYNC_ERROR; } @@ -178,19 +196,7 @@ !service->GetUserSettings()->IsSyncRequested() || service->HasDisableReason( syncer::SyncService::DISABLE_REASON_ENTERPRISE_POLICY)) { - // The order or priority is going to be: - // 1. Auth errors. 2. Actionable protocol errors. 3. Passphrase errors. - - // Check for an auth error first. - if (auth_error.state() != GoogleServiceAuthError::NONE) { - if (status_label && link_label) { - GetStatusForAuthError(auth_error, status_label, link_label, - action_type); - } - return SYNC_ERROR; - } - - // We don't have an auth error. Check for an actionable protocol error. + // Check for an actionable protocol error. if (GetStatusForActionableError(status.sync_protocol_error.action, status_label, link_label, action_type)) { return SYNC_ERROR; @@ -198,16 +204,24 @@ // Check for a passphrase error. if (service->GetUserSettings()->IsPassphraseRequiredForDecryption()) { - if (status_label && link_label) { + if (status_label) { *status_label = l10n_util::GetStringUTF16(IDS_SYNC_STATUS_NEEDS_PASSWORD); + } + if (link_label) { *link_label = l10n_util::GetStringUTF16( IDS_SYNC_STATUS_NEEDS_PASSWORD_LINK_LABEL); + } + if (action_type) { *action_type = ENTER_PASSPHRASE; } return SYNC_ERROR; } + // At this point, there is no Sync error, but there might still be a message + // we want to show. + // TODO(crbug.com/911153): This also covers the "disabled by policy" and + // "not requested" cases, which doesn't seem right. if (status_label) { *status_label = GetSyncedStateStatusLabel(service); } @@ -222,18 +236,8 @@ return SYNCED; } - // If first setup is in progress, either show auth error information or just - // an "in progress" message. + // If first setup is in progress, show an "in progress" message. if (service->IsFirstSetupInProgress()) { - if (auth_error.state() != GoogleServiceAuthError::NONE && - auth_error.state() != GoogleServiceAuthError::TWO_FACTOR) { - if (status_label && link_label) { - GetStatusForAuthError(auth_error, status_label, link_label, - action_type); - } - return SYNC_ERROR; - } - if (status_label) { *status_label = l10n_util::GetStringUTF16(IDS_SYNC_NTP_SETUP_IN_PROGRESS); } @@ -243,12 +247,16 @@ // At this point we've ruled out all other cases - all that's left is a // missing Sync confirmation. DCHECK(ShouldRequestSyncConfirmation(service)); - if (status_label && link_label) { + if (status_label) { *status_label = l10n_util::GetStringUTF16(IDS_SYNC_SETTINGS_NOT_CONFIRMED); + } + if (link_label) { *link_label = l10n_util::GetStringUTF16( IDS_SYNC_ERROR_USER_MENU_CONFIRM_SYNC_SETTINGS_BUTTON); } - *action_type = CONFIRM_SYNC_SETTINGS; + if (action_type) { + *action_type = CONFIRM_SYNC_SETTINGS; + } return SYNC_ERROR; } @@ -270,9 +278,8 @@ } MessageType GetStatus(Profile* profile) { - ActionType action_type = NO_ACTION; return GetStatusLabels(profile, /*status_label=*/nullptr, - /*link_label=*/nullptr, &action_type); + /*link_label=*/nullptr, /*action_type=*/nullptr); } #if !defined(OS_CHROMEOS)
diff --git a/chrome/browser/sync/sync_ui_util.h b/chrome/browser/sync/sync_ui_util.h index 1ae4b17..aaa687a 100644 --- a/chrome/browser/sync/sync_ui_util.h +++ b/chrome/browser/sync/sync_ui_util.h
@@ -50,7 +50,8 @@ // Returns the high-level sync status, and populates status and link label // strings for the current sync status by querying |profile|. -// |status_label| and |link_label| must either be both null or both non-null. +// Any of |status_label|, |link_label|, and |action_type| may be null if the +// caller isn't interested in it. MessageType GetStatusLabels(Profile* profile, base::string16* status_label, base::string16* link_label,
diff --git a/chrome/browser/sync/test/integration/sync_auth_test.cc b/chrome/browser/sync/test/integration/sync_auth_test.cc index f7eff6e..5b2f9c1 100644 --- a/chrome/browser/sync/test/integration/sync_auth_test.cc +++ b/chrome/browser/sync/test/integration/sync_auth_test.cc
@@ -329,13 +329,13 @@ // Enter the "Sync paused" state. GetClient(0)->EnterSyncPausedStateForPrimaryAccount(); ASSERT_TRUE(GetSyncService(0)->GetAuthError().IsPersistentError()); + ASSERT_TRUE(AttemptToTriggerAuthError()); - // Sync should have shut itself down. + // While Sync itself is still considered active, the active data types should + // now be empty. + EXPECT_TRUE(GetSyncService(0)->IsSyncFeatureActive()); EXPECT_EQ(GetSyncService(0)->GetTransportState(), - syncer::SyncService::TransportState::DISABLED); - EXPECT_TRUE(GetSyncService(0)->HasDisableReason( - syncer::SyncService::DISABLE_REASON_PAUSED)); - EXPECT_TRUE(GetSyncService(0)->GetActiveDataTypes().Empty()); + syncer::SyncService::TransportState::ACTIVE); // Clear the "Sync paused" state again. GetClient(0)->ExitSyncPausedStateForPrimaryAccount(); @@ -343,10 +343,8 @@ // access token again, so wait for that to happen. NoAuthErrorChecker(GetSyncService(0)).Wait(); ASSERT_FALSE(GetSyncService(0)->GetAuthError().IsPersistentError()); - // Once the auth error is gone, wait for Sync to start up again. - GetClient(0)->AwaitSyncSetupCompletion(); - // Now Sync should be active again. + // Now the active data types should be back. EXPECT_TRUE(GetSyncService(0)->IsSyncFeatureActive()); EXPECT_EQ(GetSyncService(0)->GetTransportState(), syncer::SyncService::TransportState::ACTIVE);
diff --git a/chrome/browser/ui/android/page_info/page_info_controller_android.cc b/chrome/browser/ui/android/page_info/page_info_controller_android.cc index c0944b9..1f0977fc 100644 --- a/chrome/browser/ui/android/page_info/page_info_controller_android.cc +++ b/chrome/browser/ui/android/page_info/page_info_controller_android.cc
@@ -122,8 +122,7 @@ permissions_to_display.push_back(CONTENT_SETTINGS_TYPE_POPUPS); permissions_to_display.push_back(CONTENT_SETTINGS_TYPE_ADS); permissions_to_display.push_back(CONTENT_SETTINGS_TYPE_AUTOPLAY); - if (base::FeatureList::IsEnabled(features::kSoundContentSetting)) - permissions_to_display.push_back(CONTENT_SETTINGS_TYPE_SOUND); + permissions_to_display.push_back(CONTENT_SETTINGS_TYPE_SOUND); std::map<ContentSettingsType, ContentSetting> user_specified_settings_to_display;
diff --git a/chrome/browser/ui/browser_commands.cc b/chrome/browser/ui/browser_commands.cc index dd36acd..662ff622 100644 --- a/chrome/browser/ui/browser_commands.cc +++ b/chrome/browser/ui/browser_commands.cc
@@ -787,12 +787,9 @@ } void MuteSite(Browser* browser) { - TabStripModel::ContextMenuCommand command_id = - base::FeatureList::IsEnabled(features::kSoundContentSetting) - ? TabStripModel::ContextMenuCommand::CommandToggleSiteMuted - : TabStripModel::ContextMenuCommand::CommandToggleTabAudioMuted; browser->tab_strip_model()->ExecuteContextMenuCommand( - browser->tab_strip_model()->active_index(), command_id); + browser->tab_strip_model()->active_index(), + TabStripModel::ContextMenuCommand::CommandToggleSiteMuted); } void ConvertPopupToTabbedBrowser(Browser* browser) {
diff --git a/chrome/browser/ui/page_info/page_info.cc b/chrome/browser/ui/page_info/page_info.cc index bfcf810..44cb3ac 100644 --- a/chrome/browser/ui/page_info/page_info.cc +++ b/chrome/browser/ui/page_info/page_info.cc
@@ -171,9 +171,6 @@ } if (info.type == CONTENT_SETTINGS_TYPE_SOUND) { - if (!base::FeatureList::IsEnabled(features::kSoundContentSetting)) - return false; - // The sound content setting should always show up when the tab has played // audio. if (web_contents && web_contents->WasEverAudible())
diff --git a/chrome/browser/ui/tab_helpers.cc b/chrome/browser/ui/tab_helpers.cc index fd2c7e7..d814fed 100644 --- a/chrome/browser/ui/tab_helpers.cc +++ b/chrome/browser/ui/tab_helpers.cc
@@ -252,8 +252,7 @@ SecurityStateTabHelper::CreateForWebContents(web_contents); if (SiteEngagementService::IsEnabled()) SiteEngagementService::Helper::CreateForWebContents(web_contents); - if (base::FeatureList::IsEnabled(features::kSoundContentSetting)) - SoundContentSettingObserver::CreateForWebContents(web_contents); + SoundContentSettingObserver::CreateForWebContents(web_contents); sync_sessions::SyncSessionsRouterTabHelper::CreateForWebContents( web_contents, sync_sessions::SyncSessionsWebContentsRouterFactory::GetForProfile(
diff --git a/chrome/browser/ui/tabs/tab_menu_model.cc b/chrome/browser/ui/tabs/tab_menu_model.cc index fbbf66681..d5d754bb 100644 --- a/chrome/browser/ui/tabs/tab_menu_model.cc +++ b/chrome/browser/ui/tabs/tab_menu_model.cc
@@ -67,25 +67,13 @@ AddItemWithStringId(TabStripModel::CommandFocusMode, IDS_TAB_CXMENU_FOCUS_THIS_TAB); } - if (base::FeatureList::IsEnabled(features::kSoundContentSetting)) { - const bool will_mute = - !chrome::AreAllSitesMuted(*tab_strip, affected_indices); - AddItem(TabStripModel::CommandToggleSiteMuted, - will_mute - ? l10n_util::GetPluralStringFUTF16( - IDS_TAB_CXMENU_SOUND_MUTE_SITE, num_affected_tabs) - : l10n_util::GetPluralStringFUTF16( - IDS_TAB_CXMENU_SOUND_UNMUTE_SITE, num_affected_tabs)); - } else { - const bool will_mute = - !chrome::AreAllTabsMuted(*tab_strip, affected_indices); - AddItem(TabStripModel::CommandToggleTabAudioMuted, - will_mute - ? l10n_util::GetPluralStringFUTF16( - IDS_TAB_CXMENU_AUDIO_MUTE_TAB, num_affected_tabs) - : l10n_util::GetPluralStringFUTF16( - IDS_TAB_CXMENU_AUDIO_UNMUTE_TAB, num_affected_tabs)); - } + const bool will_mute = + !chrome::AreAllSitesMuted(*tab_strip, affected_indices); + AddItem(TabStripModel::CommandToggleSiteMuted, + will_mute ? l10n_util::GetPluralStringFUTF16( + IDS_TAB_CXMENU_SOUND_MUTE_SITE, num_affected_tabs) + : l10n_util::GetPluralStringFUTF16( + IDS_TAB_CXMENU_SOUND_UNMUTE_SITE, num_affected_tabs)); Browser* browser = chrome::FindBrowserWithWebContents(tab_strip->GetWebContentsAt(index));
diff --git a/chrome/browser/ui/tabs/tab_strip_model.cc b/chrome/browser/ui/tabs/tab_strip_model.cc index 5c41197..f5d360f1 100644 --- a/chrome/browser/ui/tabs/tab_strip_model.cc +++ b/chrome/browser/ui/tabs/tab_strip_model.cc
@@ -1132,7 +1132,6 @@ return delegate()->GetRestoreTabType() != TabStripModelDelegate::RESTORE_NONE; - case CommandToggleTabAudioMuted: case CommandToggleSiteMuted: { std::vector<int> indices = GetIndicesForCommand(context_index); for (size_t i = 0; i < indices.size(); ++i) { @@ -1276,20 +1275,6 @@ break; } - case CommandToggleTabAudioMuted: { - std::vector<int> indices = GetIndicesForCommand(context_index); - const bool mute = WillContextMenuMute(context_index); - if (mute) - base::RecordAction(UserMetricsAction("TabContextMenu_MuteTabs")); - else - base::RecordAction(UserMetricsAction("TabContextMenu_UnmuteTabs")); - for (auto i = indices.begin(); i != indices.end(); ++i) { - chrome::SetTabAudioMuted(GetWebContentsAt(*i), mute, - TabMutedReason::CONTEXT_MENU, std::string()); - } - break; - } - case CommandToggleSiteMuted: { const bool mute = WillContextMenuMuteSites(context_index); if (mute) { @@ -1343,11 +1328,6 @@ AddToExistingGroup(GetIndicesForCommand(context_index), group); } -bool TabStripModel::WillContextMenuMute(int index) { - std::vector<int> indices = GetIndicesForCommand(index); - return !chrome::AreAllTabsMuted(*this, indices); -} - bool TabStripModel::WillContextMenuMuteSites(int index) { return !chrome::AreAllSitesMuted(*this, GetIndicesForCommand(index)); }
diff --git a/chrome/browser/ui/tabs/tab_strip_model.h b/chrome/browser/ui/tabs/tab_strip_model.h index 0ee2a6f..e1265c05 100644 --- a/chrome/browser/ui/tabs/tab_strip_model.h +++ b/chrome/browser/ui/tabs/tab_strip_model.h
@@ -401,7 +401,6 @@ CommandRestoreTab, CommandTogglePinned, CommandFocusMode, - CommandToggleTabAudioMuted, CommandToggleSiteMuted, CommandSendToMyDevices, CommandBookmarkAllTabs, @@ -427,10 +426,6 @@ void ExecuteAddToExistingGroupCommand(int context_index, const TabGroupData* group); - // Returns true if 'CommandToggleTabAudioMuted' will mute. |index| is the - // index supplied to |ExecuteContextMenuCommand|. - bool WillContextMenuMute(int index); - // Returns true if 'CommandToggleSiteMuted' will mute. |index| is the // index supplied to |ExecuteContextMenuCommand|. bool WillContextMenuMuteSites(int index);
diff --git a/chrome/browser/ui/tabs/tab_utils.cc b/chrome/browser/ui/tabs/tab_utils.cc index 4005c1d..9deb09a 100644 --- a/chrome/browser/ui/tabs/tab_utils.cc +++ b/chrome/browser/ui/tabs/tab_utils.cc
@@ -141,15 +141,6 @@ return true; } -bool AreAllTabsMuted(const TabStripModel& tab_strip, - const std::vector<int>& indices) { - for (auto i = indices.begin(); i != indices.end(); ++i) { - if (!tab_strip.GetWebContentsAt(*i)->IsAudioMuted()) - return false; - } - return true; -} - bool IsSiteMuted(const TabStripModel& tab_strip, const int index) { content::WebContents* web_contents = tab_strip.GetWebContentsAt(index);
diff --git a/chrome/browser/ui/tabs/tab_utils.h b/chrome/browser/ui/tabs/tab_utils.h index 816b9583..8e4ca381 100644 --- a/chrome/browser/ui/tabs/tab_utils.h +++ b/chrome/browser/ui/tabs/tab_utils.h
@@ -76,10 +76,6 @@ // Returns the last reason a tab's mute state was changed. TabMutedReason GetTabAudioMutedReason(content::WebContents* contents); -// Returns true if the tabs at the |indices| in |tab_strip| are all muted. -bool AreAllTabsMuted(const TabStripModel& tab_strip, - const std::vector<int>& indices); - // Returns true if the site at |index| in |tab_strip| is muted. bool IsSiteMuted(const TabStripModel& tab_strip, const int index);
diff --git a/chrome/browser/ui/views/frame/browser_frame_mac.mm b/chrome/browser/ui/views/frame/browser_frame_mac.mm index 3b2dc38b..5650a322 100644 --- a/chrome/browser/ui/views/frame/browser_frame_mac.mm +++ b/chrome/browser/ui/views/frame/browser_frame_mac.mm
@@ -239,10 +239,7 @@ } case IDC_WINDOW_MUTE_SITE: { TabStripModel* model = browser->tab_strip_model(); - bool will_mute = - base::FeatureList::IsEnabled(features::kSoundContentSetting) - ? model->WillContextMenuMuteSites(model->active_index()) - : model->WillContextMenuMute(model->active_index()); + bool will_mute = model->WillContextMenuMuteSites(model->active_index()); // Menu items may be validated during browser startup, before the // TabStripModel has been populated. result->new_toggle_state = !model->empty() && !will_mute;
diff --git a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc index 0698075..7b0b41f 100644 --- a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
@@ -2630,10 +2630,6 @@ subresource_filter::kSafeBrowsingSubresourceFilter)); html_source->AddBoolean( - "enableSoundContentSetting", - base::FeatureList::IsEnabled(features::kSoundContentSetting)); - - html_source->AddBoolean( "enableBlockAutoplayContentSetting", base::FeatureList::IsEnabled(media::kAutoplayDisableSettings));
diff --git a/chrome/browser/ui/webui/settings/people_handler.cc b/chrome/browser/ui/webui/settings/people_handler.cc index 32f4f5cd..eeeb1fa 100644 --- a/chrome/browser/ui/webui/settings/people_handler.cc +++ b/chrome/browser/ui/webui/settings/people_handler.cc
@@ -498,10 +498,11 @@ // If dice is disabled (and unified consent enabled), show only the primary // account. auto* identity_manager = IdentityManagerFactory::GetForProfile(profile_); - if (identity_manager->HasPrimaryAccount()) { - accounts_list.push_back( - GetAccountValue(identity_manager->GetPrimaryAccountInfo())); - } + base::Optional<AccountInfo> primary_account_info = + identity_manager->FindExtendedAccountInfoForAccount( + identity_manager->GetPrimaryAccountInfo()); + if (primary_account_info.has_value()) + accounts_list.push_back(GetAccountValue(primary_account_info.value())); } return accounts; @@ -766,7 +767,9 @@ auto* identity_manager = IdentityManagerFactory::GetForProfile(profile_); DCHECK(identity_manager->HasPrimaryAccount()); - AccountInfo primary_account_info = identity_manager->GetPrimaryAccountInfo(); + CoreAccountInfo primary_account_info = + identity_manager->GetPrimaryAccountInfo(); + identity_manager->GetAccountsMutator()->AddOrUpdateAccount( primary_account_info.gaia, primary_account_info.email, OAuth2TokenServiceDelegate::kInvalidRefreshToken,
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc index 526c637..184cc0e4 100644 --- a/chrome/common/chrome_features.cc +++ b/chrome/common/chrome_features.cc
@@ -14,6 +14,11 @@ // All features in alphabetical order. +#if defined(OS_ANDROID) +const base::Feature kAddToHomescreenMessaging{ + "AddToHomescreenMessaging", base::FEATURE_DISABLED_BY_DEFAULT}; +#endif // defined(OS_ANDROID) + #if defined(OS_MACOSX) // Enables the menu item for Javascript execution via AppleScript. const base::Feature kAppleScriptExecuteJavaScriptMenuItem{ @@ -381,6 +386,15 @@ "AcknowledgeNtpOverrideOnDeactivate", base::FEATURE_DISABLED_BY_DEFAULT}; #endif +#if defined(OS_CHROMEOS) +// Enables or disables notification which pop-ups after managed guest session +// autolaunch +// TODO(owner:raleksandrov): Remove this when message will be confirmed. +// https://crbug.com/927331 +const base::Feature kManagedGuestSessionNotification{ + "ManagedGuestSessionNotification", base::FEATURE_DISABLED_BY_DEFAULT}; +#endif + // Enables or disables modal permission prompts. // TODO(https://crbug.com/935900): Remove this. const base::Feature kModalPermissionPrompts{"ModalPermissionPrompts",
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h index 2d51681..b773f3d 100644 --- a/chrome/common/chrome_features.h +++ b/chrome/common/chrome_features.h
@@ -24,6 +24,11 @@ // All features in alphabetical order. The features should be documented // alongside the definition of their values in the .cc file. +#if defined(OS_ANDROID) +COMPONENT_EXPORT(CHROME_FEATURES) +extern const base::Feature kAddToHomescreenMessaging; +#endif // defined(OS_ANDROID) + #if defined(OS_MACOSX) COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kAppleScriptExecuteJavaScriptMenuItem; @@ -255,6 +260,11 @@ extern const base::Feature kAcknowledgeNtpOverrideOnDeactivate; #endif +#if defined(OS_CHROMEOS) +COMPONENT_EXPORT(CHROME_FEATURES) +extern const base::Feature kManagedGuestSessionNotification; +#endif + COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kModalPermissionPrompts;
diff --git a/chrome/common/extensions/api/bookmark_manager_private.json b/chrome/common/extensions/api/bookmark_manager_private.json index 88f4e61..922e930c 100644 --- a/chrome/common/extensions/api/bookmark_manager_private.json +++ b/chrome/common/extensions/api/bookmark_manager_private.json
@@ -43,12 +43,6 @@ "items": {"$ref": "BookmarkNodeDataElement"} } } - }, - { - "id": "MetaInfoFields", - "type": "object", - "description": "Collection of meta info fields.", - "additionalProperties": {"type": "string"} } ], "functions": [ @@ -100,17 +94,6 @@ ] }, { - "name": "canPaste", - "type": "function", - "description": "Whether there are any bookmarks that can be pasted.", - "parameters": [ - {"type": "string", "name": "parentId", "description": "The ID of the folder to paste into."}, - {"type": "function", "name": "callback", "parameters": [ - {"name": "result", "type": "boolean"} - ]} - ] - }, - { "name": "sortChildren", "type": "function", "description": "Sorts the children of a given folder.", @@ -193,16 +176,6 @@ ] }, { - "name": "canEdit", - "type": "function", - "description": "Whether bookmarks can be modified.", - "parameters": [ - {"type": "function", "name": "callback", "parameters": [ - {"name": "result", "type": "boolean"} - ]} - ] - }, - { "name": "removeTrees", "type": "function", "description": "Recursively removes list of bookmarks nodes.", @@ -218,125 +191,6 @@ ] }, { - "name": "recordLaunch", - "type": "function", - "description": "", - "parameters": [] - }, - { - "name": "createWithMetaInfo", - "type": "function", - "description": "Mimics the functionality of bookmarks.create, but will additionally set the given meta info fields.", - "parameters": [ - { - "name": "bookmark", - "$ref": "bookmarks.CreateDetails" - }, - { - "name": "metaInfo", - "$ref": "MetaInfoFields" - }, - { - "type": "function", - "name": "callback", - "optional": true, - "parameters": [ - { - "name": "result", - "$ref": "bookmarks.BookmarkTreeNode" - } - ] - } - ] - }, - { - "name": "getMetaInfo", - "type": "function", - "description": "Gets meta info from a bookmark node.", - "allowAmbiguousOptionalArguments": true, - "parameters": [ - { - "name": "id", - "description": "The id of the bookmark to retrieve meta info from. If omitted meta info for all nodes is returned.", - "optional": true, - "type": "string" - }, - { - "name": "key", - "description": "The key for the meta info to retrieve. If omitted, all fields are returned.", - "optional": true, - "type": "string" - }, - { - "type": "function", - "optional": true, - "name": "callback", - "parameters": [ - { - "name": "value", - "description": "If a key was given, the value of the specified field, if present. Otherwise an object containing all meta info fields for the node. If id is not given then meta info for all nodes as an object with node id to meta info.", - "optional": true, - "choices": [ - {"type": "string"}, - {"type": "object", "additionalProperties": {"type": "any"}} - ] - } - ] - } - ] - }, - { - "name": "setMetaInfo", - "type": "function", - "description": "Sets a meta info value for a bookmark node.", - "parameters": [ - { - "name": "id", - "description": "The id of the bookmark node to set the meta info on.", - "type": "string" - }, - { - "name": "key", - "description": "The key of the meta info to set.", - "type": "string" - }, - { - "name": "value", - "description": "The meta info to set.", - "type": "string" - }, - { - "name": "callback", - "type": "function", - "optional": true, - "parameters": [] - } - ] - }, - { - "name": "updateMetaInfo", - "type": "function", - "description": "Updates a set of meta info values for a bookmark node.", - "parameters": [ - { - "name": "id", - "description": "The id of the bookmark node to update the meta info of.", - "type": "string" - }, - { - "name": "metaInfoChanges", - "description": "A set of meta info key/value pairs to update.", - "$ref": "MetaInfoFields" - }, - { - "name": "callback", - "type": "function", - "optional": true, - "parameters": [] - } - ] - }, - { "name": "undo", "type": "function", "description": "Performs an undo of the last change to the bookmark model.", @@ -347,48 +201,6 @@ "type": "function", "description": "Performs a redo of last undone change to the bookmark model.", "parameters": [] - }, - { - "name": "getUndoInfo", - "type": "function", - "description": "Gets the information for the undo if available.", - "parameters": [ - { - "type": "function", - "name": "callback", - "parameters": [ - { - "name": "result", - "type": "object", - "properties": { - "enabled" : {"type": "boolean", "description": "Whether there is an action to undo."}, - "label" : {"type": "string", "description": "The i18n label to use for the undo action."} - } - } - ] - } - ] - }, - { - "name": "getRedoInfo", - "type": "function", - "description": "Gets the information for the redo if available.", - "parameters": [ - { - "type": "function", - "name": "callback", - "parameters": [ - { - "name": "result", - "type": "object", - "properties": { - "enabled" : {"type": "boolean", "description": "Whether there is an action to redo"}, - "label" : {"type": "string", "description": "The i18n label to use for the redo action"} - } - } - ] - } - ] } ], "events": [ @@ -415,15 +227,6 @@ "parameters": [ {"name": "bookmarkNodeData", "$ref": "BookmarkNodeData"} ] - }, - { - "name": "onMetaInfoChanged", - "type": "function", - "description": "Fired when the meta info of a node changes.", - "parameters": [ - {"name": "id", "type": "string"}, - {"name": "metaInfoChanges", "$ref": "MetaInfoFields"} - ] } ] }
diff --git a/chrome/credential_provider/gaiacp/gcp_crash_reporting_utils.cc b/chrome/credential_provider/gaiacp/gcp_crash_reporting_utils.cc index b467f39..8fde8e0 100644 --- a/chrome/credential_provider/gaiacp/gcp_crash_reporting_utils.cc +++ b/chrome/credential_provider/gaiacp/gcp_crash_reporting_utils.cc
@@ -65,8 +65,10 @@ if (crash_dir.empty() || (!base::PathExists(crash_dir) && !base::CreateDirectory(crash_dir))) { HRESULT hr = HRESULT_FROM_WIN32(::GetLastError()); - LOGFN(ERROR) << "Failed to create directory for crash dumps: " << crash_dir - << " hr=" << putHR(hr); + if (hr != HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS)) { + LOGFN(ERROR) << "Failed to create directory for crash dumps: " + << crash_dir << " hr=" << putHR(hr); + } } }
diff --git a/chrome/credential_provider/gaiacp/os_user_manager.cc b/chrome/credential_provider/gaiacp/os_user_manager.cc index 52d53ff..12d8ba166 100644 --- a/chrome/credential_provider/gaiacp/os_user_manager.cc +++ b/chrome/credential_provider/gaiacp/os_user_manager.cc
@@ -480,10 +480,6 @@ wcscpy_s(domain, domain_size, local_domain_buffer); } - if (hr != S_OK && hr != HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) - LOGFN(ERROR) << "LookupAccountSid hr=" << putHR(hr); - - LOGFN(INFO) << "username=" << username << " ntdomain=" << domain; ::LocalFree(psid); return hr; }
diff --git a/chrome/credential_provider/gaiacp/scoped_lsa_policy.cc b/chrome/credential_provider/gaiacp/scoped_lsa_policy.cc index 8cb9f320..b94c0b0e 100644 --- a/chrome/credential_provider/gaiacp/scoped_lsa_policy.cc +++ b/chrome/credential_provider/gaiacp/scoped_lsa_policy.cc
@@ -98,11 +98,8 @@ LSA_UNICODE_STRING* lsa_value; NTSTATUS sts = ::LsaRetrievePrivateData(handle_, &lsa_key, &lsa_value); - if (sts != STATUS_SUCCESS) { - HRESULT hr = HRESULT_FROM_NT(sts); - LOGFN(ERROR) << "LsaRetrievePrivateData hr=" << putHR(hr); - return hr; - } + if (sts != STATUS_SUCCESS) + return HRESULT_FROM_NT(sts); errno_t err = wcscpy_s(value, length, lsa_value->Buffer); ::LsaFreeMemory(lsa_value);
diff --git a/chrome/installer/mini_installer/chrome.release b/chrome/installer/mini_installer/chrome.release index a29cd7d..bdf0219 100644 --- a/chrome/installer/mini_installer/chrome.release +++ b/chrome/installer/mini_installer/chrome.release
@@ -18,7 +18,6 @@ # # Chrome version dir entries, sorted alphabetically. # -api-ms-win-*.dll: %(VersionDir)s\ chrome.dll: %(VersionDir)s\ chrome_100_percent.pak: %(VersionDir)s\ chrome_child.dll: %(VersionDir)s\ @@ -37,7 +36,6 @@ natives_blob.bin: %(VersionDir)s\ notification_helper.exe: %(VersionDir)s\ resources.pak: %(VersionDir)s\ -ucrtbase*.dll: %(VersionDir)s\ v8_context_snapshot.bin: %(VersionDir)s\ # # Sub directories living in the version dir
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc index d35c15a..d007c01 100644 --- a/chrome/renderer/chrome_content_renderer_client.cc +++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -1520,6 +1520,10 @@ void ChromeContentRendererClient:: SetRuntimeFeaturesDefaultsBeforeBlinkInitialization() { + // The performance manager service interfaces are provided by the chrome + // embedder only. + blink::WebRuntimeFeatures::EnablePerformanceManagerInstrumentation(true); + // Web Share is shipped on Android, experimental otherwise. It is enabled here, // in chrome/, to avoid it being made available in other clients of content/ // that do not have a Web Share Mojo implementation.
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index a5590450..2c82510a 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -1879,6 +1879,8 @@ "../browser/chromeos/login/test/hid_controller_mixin.h", "../browser/chromeos/login/test/https_forwarder.cc", "../browser/chromeos/login/test/https_forwarder.h", + "../browser/chromeos/login/test/local_policy_test_server_mixin.cc", + "../browser/chromeos/login/test/local_policy_test_server_mixin.h", "../browser/chromeos/login/test/oobe_base_test.cc", "../browser/chromeos/login/test/oobe_base_test.h", "../browser/chromeos/login/ui/captive_portal_window_browsertest.cc",
diff --git a/chrome/test/data/extensions/api_test/bindings/invalidate_context/background.js b/chrome/test/data/extensions/api_test/bindings/invalidate_context/background.js index 4f58c60a..5ea3ef4 100644 --- a/chrome/test/data/extensions/api_test/bindings/invalidate_context/background.js +++ b/chrome/test/data/extensions/api_test/bindings/invalidate_context/background.js
@@ -6,6 +6,7 @@ var frameRuntime; var frameStorage; var frameTabs; +var nativeBindingsEnabled; function createFrame() { frame = document.createElement('iframe'); @@ -16,7 +17,7 @@ }); } -function testPort(port) { +function testPort(port, expectEventsValid) { var result = { disconnectThrow: false, postMessageThrow: false, @@ -39,7 +40,7 @@ } try { - result.onDisconnect = port.onDisconnect; + result.onDisconnectEvent = port.onDisconnect; } catch (e) { result.getOnDisconnectThrow = true; } @@ -52,13 +53,27 @@ chrome.test.assertTrue(result.postMessageThrow); chrome.test.assertTrue(result.disconnectThrow); - chrome.test.assertTrue(result.getOnMessageThrow); - chrome.test.assertTrue(result.getOnDisconnectThrow); - chrome.test.assertFalse(!!result.onMessageEvent); - chrome.test.assertFalse(!!result.onDisconnectEvent); + + // With native bindings, the event object instantiated on a Port is set as a + // lazy data property, and thus is safe to access even after the context has + // been removed. JS bindings always throw errors when trying to access them + // after context invalidation. + expectEventsValid &= nativeBindingsEnabled; + + if (expectEventsValid) { + chrome.test.assertFalse(result.getOnMessageThrow); + chrome.test.assertFalse(result.getOnDisconnectThrow); + chrome.test.assertTrue(!!result.onMessageEvent); + chrome.test.assertTrue(!!result.onDisconnectEvent); + } else { + chrome.test.assertTrue(result.getOnMessageThrow); + chrome.test.assertTrue(result.getOnDisconnectThrow); + chrome.test.assertEq(undefined, result.onMessageEvent); + chrome.test.assertEq(undefined, result.onDisconnectEvent); + } } -chrome.test.runTests([ +const tests = [ function useFrameStorageAndRuntime() { createFrame().then(() => { frameRuntime = frame.contentWindow.chrome.runtime; @@ -104,7 +119,7 @@ port.postMessage; document.body.removeChild(frame); - testPort(port); + testPort(port, false); chrome.test.succeed(); }); }, @@ -117,7 +132,7 @@ port.disconnect(); document.body.removeChild(frame); - testPort(port); + testPort(port, false); chrome.test.succeed(); }); }, @@ -131,8 +146,13 @@ port.onDisconnect; document.body.removeChild(frame); - testPort(port); + testPort(port, true); chrome.test.succeed(); }); }, -]); +]; + +chrome.test.getConfig((config) => { + nativeBindingsEnabled = config.nativeCrxBindingsEnabled; + chrome.test.runTests(tests); +});
diff --git a/chrome/test/data/extensions/api_test/bookmark_manager/edit_disabled/test.js b/chrome/test/data/extensions/api_test/bookmark_manager/edit_disabled/test.js index bc27b5b..e6f33b18 100644 --- a/chrome/test/data/extensions/api_test/bookmark_manager/edit_disabled/test.js +++ b/chrome/test/data/extensions/api_test/bookmark_manager/edit_disabled/test.js
@@ -68,21 +68,9 @@ bookmarkManager.cut([bbb.id], fail(ERROR)); }, - function canPasteDisabled() { - bookmarkManager.canPaste(folder.id, pass(function(result) { - assertFalse(result, 'Should not be able to paste bookmarks'); - })); - }, - function pasteDisabled() { bookmarkManager.paste(folder.id, [bbb.id], fail(ERROR)); }, - - function editDisabled() { - bookmarkManager.canEdit(pass(function(result) { - assertFalse(result, 'Should not be able to edit bookmarks'); - })); - } ]; chrome.test.runTests(tests);
diff --git a/chrome/test/data/extensions/api_test/bookmark_manager/standard/test.js b/chrome/test/data/extensions/api_test/bookmark_manager/standard/test.js index 49f7bc89..c57d683 100644 --- a/chrome/test/data/extensions/api_test/bookmark_manager/standard/test.js +++ b/chrome/test/data/extensions/api_test/bookmark_manager/standard/test.js
@@ -188,11 +188,6 @@ // Copy the fooNode. doCopy([fooNode.id]); - // Ensure canPaste is now true. - bookmarkManager.canPaste('1', pass(function(result) { - assertTrue(result, 'Should be able to paste now'); - })); - // Paste it. doPaste('1'); @@ -218,11 +213,6 @@ count -= 2; assertEq(count, result.length); })); - - // Ensure canPaste is still true. - bookmarkManager.canPaste('1', pass(function(result) { - assertTrue(result, 'Should be able to paste now'); - })); }, function clipboard4() { @@ -260,11 +250,6 @@ // Copy it. doCopy([emptyFolder.id]); - // Ensure canPaste is now true. - bookmarkManager.canPaste('1', pass(function(result) { - assertTrue(result, 'Should be able to paste now'); - })); - // Paste it at the end of a multiple selection. doPaste('1', [barNode.id, fooNode2.id]); @@ -300,100 +285,9 @@ // Pasting to a managed folder is not allowed. assertTrue(result[1].url === undefined); - bookmarkManager.canPaste(result[1].id, pass(function(result) { - assertFalse(result, 'Should not be able to paste to managed folders.'); - })); - bookmarkManager.paste(result[1].id, fail(error)); })); }, - - function canEdit() { - bookmarkManager.canEdit(pass(function(result) { - assertTrue(result, 'Should be able to edit bookmarks'); - })); - }, - - function getSetMetaInfo() { - bookmarkManager.getMetaInfo(nodeA.id, 'meta', pass(function(result) { - assertTrue(!result); - })); - chrome.test.listenOnce(bookmarkManager.onMetaInfoChanged, pass( - function(id, changes) { - assertEq(nodeA.id, id); - assertEq({meta: 'bla'}, changes); - })); - bookmarkManager.setMetaInfo(nodeA.id, 'meta', 'bla'); - bookmarkManager.setMetaInfo(nodeA.id, 'meta2', 'foo'); - bookmarkManager.getMetaInfo(nodeA.id, 'meta', pass(function(result) { - assertEq('bla', result); - })); - - bookmarkManager.getMetaInfo(nodeA.id, pass(function(result) { - assertEq({meta: 'bla', meta2: 'foo'}, result); - })); - }, - - function setMetaInfoPermanent() { - bookmarks.getTree(pass(function(nodes) { - var unmodifiableFolder = nodes[0].children[0]; - bookmarkManager.setMetaInfo(unmodifiableFolder.id, 'meta', 'foo', fail( - "Can't modify the root bookmark folders.")); - bookmarkManager.updateMetaInfo(unmodifiableFolder.id, {a: 'a', b: 'b'}, - fail("Can't modify the root bookmark folders.")); - })); - }, - - function setMetaInfoManaged() { - bookmarks.getChildren('4', pass(function(result) { - assertTrue(result.length > 0); - bookmarkManager.setMetaInfo(result[0].id, 'meta', 'foo', fail( - "Can't modify managed bookmarks.")); - bookmarkManager.updateMetaInfo(result[0].id, {a: 'a', b: 'b'}, - fail("Can't modify managed bookmarks.")); - })); - }, - - function updateMetaInfo() { - bookmarkManager.getMetaInfo(nodeB.id, pass(function(result){ - assertEq({}, result); - })); - - chrome.test.listenOnce(bookmarkManager.onMetaInfoChanged, pass( - function(id, changes) { - assertEq(nodeB.id, id); - assertEq({a: 'a', b: 'b', c: 'c'}, changes); - })); - bookmarkManager.updateMetaInfo(nodeB.id, {a: 'a', b: 'b', c: 'c'}, pass( - function() { - chrome.test.listenOnce(bookmarkManager.onMetaInfoChanged, pass( - function(id, changes) { - assertEq(nodeB.id, id); - assertEq({a: 'aa', d: 'd'}, changes); - })); - bookmarkManager.updateMetaInfo(nodeB.id, {a: 'aa', b: 'b', d: 'd'}); - bookmarkManager.getMetaInfo(nodeB.id, pass(function(result) { - assertEq({a: 'aa', b: 'b', c: 'c', d: 'd'}, result); - })); - })); - }, - - function createWithMetaInfo() { - var node = {title: 'title', url: 'http://www.google.com/'}; - var metaInfo = {a: 'a', b: 'b'}; - chrome.test.listenOnce(bookmarks.onCreated, pass(function(id, created) { - assertEq(node.title, created.title); - assertEq(node.url, created.url); - bookmarkManager.getMetaInfo(id, pass(function(result) { - assertEq(metaInfo, result); - })); - })); - bookmarkManager.createWithMetaInfo(node, metaInfo, pass( - function(createdNode) { - assertEq(node.title, createdNode.title); - assertEq(node.url, createdNode.url); - })); - } ]; chrome.test.runTests(tests);
diff --git a/chrome/test/data/pdf/basic_test.js b/chrome/test/data/pdf/basic_test.js index 3a46c8f..ffe9f34 100644 --- a/chrome/test/data/pdf/basic_test.js +++ b/chrome/test/data/pdf/basic_test.js
@@ -67,7 +67,7 @@ // Clicking on the plugin should close the bookmarks menu. chrome.test.assertFalse(dropdown.dropdownOpen); - MockInteractions.tap(dropdown.$.icon); + MockInteractions.tap(dropdown.$.button); chrome.test.assertTrue(dropdown.dropdownOpen); // Generate pointer event manually, as MockInteractions doesn't include // this. @@ -75,7 +75,7 @@ chrome.test.assertFalse(dropdown.dropdownOpen, "Clicking plugin closes dropdown"); - MockInteractions.tap(dropdown.$.icon); + MockInteractions.tap(dropdown.$.button); chrome.test.assertTrue(dropdown.dropdownOpen); MockInteractions.pressAndReleaseKeyOn(document, ESC_KEY); chrome.test.assertFalse(dropdown.dropdownOpen,
diff --git a/chrome/test/data/pdf/material_elements_test.js b/chrome/test/data/pdf/material_elements_test.js index 5f5a3148..5877168 100644 --- a/chrome/test/data/pdf/material_elements_test.js +++ b/chrome/test/data/pdf/material_elements_test.js
@@ -97,12 +97,12 @@ chrome.test.assertFalse(dropdown.dropdownOpen); chrome.test.assertEq('closedIcon', dropdown.dropdownIcon); - MockInteractions.tap(dropdown.$.icon); + MockInteractions.tap(dropdown.$.button); chrome.test.assertTrue(dropdown.dropdownOpen); chrome.test.assertEq('openIcon', dropdown.dropdownIcon); - MockInteractions.tap(dropdown.$.icon); + MockInteractions.tap(dropdown.$.button); chrome.test.assertFalse(dropdown.dropdownOpen);
diff --git a/chrome/test/data/webui/settings/privacy_page_test.js b/chrome/test/data/webui/settings/privacy_page_test.js index 18ec3c57..d1953f9 100644 --- a/chrome/test/data/webui/settings/privacy_page_test.js +++ b/chrome/test/data/webui/settings/privacy_page_test.js
@@ -645,7 +645,6 @@ setup(() => { loadTimeData.overrideValues({ - enableSoundContentSetting: true, enableBlockAutoplayContentSetting: true });
diff --git a/chrome/test/data/webui/settings/site_details_tests.js b/chrome/test/data/webui/settings/site_details_tests.js index ec15a0c..45a773c 100644 --- a/chrome/test/data/webui/settings/site_details_tests.js +++ b/chrome/test/data/webui/settings/site_details_tests.js
@@ -127,9 +127,6 @@ const optionalSiteDetailsContentSettingsTypes = /** @type {!settings.ContentSettingsType : string} */ ({}); optionalSiteDetailsContentSettingsTypes[settings.ContentSettingsTypes - .SOUND] = - 'enableSoundContentSetting'; - optionalSiteDetailsContentSettingsTypes[settings.ContentSettingsTypes .CLIPBOARD] = 'enableClipboardContentSetting'; optionalSiteDetailsContentSettingsTypes[settings.ContentSettingsTypes.ADS] = @@ -250,7 +247,6 @@ test('correct pref settings are shown', function() { browserProxy.setPrefs(prefs); // Make sure all the possible content settings are shown for this test. - loadTimeData.overrideValues({enableSoundContentSetting: true}); loadTimeData.overrideValues({enableSafeBrowsingSubresourceFilter: true}); loadTimeData.overrideValues({enableClipboardContentSetting: true}); loadTimeData.overrideValues({enableSensorsContentSetting: true});
diff --git a/chromeos/services/ime/BUILD.gn b/chromeos/services/ime/BUILD.gn index 989102a..9ff04eeb 100644 --- a/chromeos/services/ime/BUILD.gn +++ b/chromeos/services/ime/BUILD.gn
@@ -25,6 +25,7 @@ if (enable_cros_ime_decoder) { sources += [ + "//chromeos/services/ime/public/cpp/shared_lib:interfaces", "decoder/decoder_engine.cc", "decoder/decoder_engine.h", ]
diff --git a/chromeos/services/ime/public/cpp/shared_lib/BUILD.gn b/chromeos/services/ime/public/cpp/shared_lib/BUILD.gn new file mode 100644 index 0000000..d84e1d2 --- /dev/null +++ b/chromeos/services/ime/public/cpp/shared_lib/BUILD.gn
@@ -0,0 +1,9 @@ +# Copyright 2019 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +source_set("interfaces") { + sources = [ + "interfaces.h", + ] +}
diff --git a/chromeos/services/ime/public/cpp/shared_lib/interfaces.h b/chromeos/services/ime/public/cpp/shared_lib/interfaces.h new file mode 100644 index 0000000..de8ab1f --- /dev/null +++ b/chromeos/services/ime/public/cpp/shared_lib/interfaces.h
@@ -0,0 +1,162 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMEOS_SERVICES_IME_PUBLIC_CPP_SHARED_LIB_INTERFACES_H_ +#define CHROMEOS_SERVICES_IME_PUBLIC_CPP_SHARED_LIB_INTERFACES_H_ + +#include <stddef.h> +#include <stdint.h> + +// Introduce interfaces between the IME Mojo service and its IME shared library +// which is loaded dynamically during runtime. +// +// Prerequisite: Compilers of both IME service and IME shared library should +// follow the same or similar ABIs, so that their generated code should be +// interoperable. +// +// Please note that the IME shared library is not likely compiled with the same +// compiler as the IME Mojo service. IME shared library's creater should be +// responsible for compiling it in a compiler with the same or similar ABIs. +// +// For polymorphism, the interfaces should be abstract base classes with pure +// virtual methods. An interface will be implemented in one end and called on +// the other end. +// +// +-----------+ +// .---> | Interface | <---. +// depends on | +-----------+ | depends on +// | | +// +----------------+ +-------------+ +// | Shared Library | | IME Service | +// +----------------+ +-------------+ +// +// For best practices on creating/modifying these interfaces. +// +// 1, Stick with "C" style arguments and return types over these interfaces, +// because the "C" ABIs are much more stable. E.g. std structures over these +// interfaces is not likely layout-compatible between compilers. +// +// 2, Every interface here should only contain pure virtual methods, except +// its destructor. +// +// 3, Protect destructors of these interfaces to discourage clients from +// deleting interface. Providing a Destroy function if needed. +// +// 4, Always add new methods at the end of an interface, and do not add new +// virtual overloaded functions (methods with the same name). +// +// 5, Document the ownership of these interfaces' parameters to avoid memory +// leaks or overflows. +// +// IME service and its IME shared library need to be recompiled when these +// interfaces change. Keep these interfaces as stable as possible, so making +// changes to the implementation of an interface will not need to recompile the +// caller end. +// +// And it's important to keep any unnecessary information out of this header. + +namespace chromeos { +namespace ime { + +// This defines the `Platform` interface, which is used throughout the shared +// library to manage platform-specific data/operations. +// +// This class should be provided by the IME service before creating an +// `ImeEngineMainEntry` and be always owned by the IME service. +class Platform { + public: + // The three methods below are Getters of the local data directories on the + // platform. It's possible for the IME service to be running in a mode where + // some local directories are unavailable, in which case these directories + // will be empty. + // + // The returned pointer must remain valid until the `Platform` is destroyed. + + // Get the local IME bundle directory, which is read-only. + virtual const char* GetImeBundleDir() = 0; + + // Get the local IME global directory, which is accessible to all users. + virtual const char* GetImeGlobalDir() = 0; + + // Get the local IME directory in the acitve user's home, which is only + // accessible to that user. + virtual const char* GetImeUserHomeDir() = 0; + + // TODO(https://crbug.com/837156): Provide Downloader/Logger for main entry. +}; + +// The wrapper of Mojo InterfacePtr on an IME client. +// +// This is used to send messages to connected IME client from an IME engine. +// IME service will create then pass it to the engine. +class ImeClientDelegate { + public: + // Returns the c_str() of the internal IME specification of ImeClientDelegate. + // The IME specification will be invalidated by its `Destroy` method. + virtual const char* ImeSpec() = 0; + + // Process response data from the engine instance in its connected IME client. + // The data will be invalidated by the engine soon after this call. + virtual void Process(const uint8_t* data, size_t size) = 0; + + // Destroy the `ImeClientDelegate` instance, which is called in the shared + // library when the bound engine is destroyed. + virtual void Destroy() = 0; + + protected: + ~ImeClientDelegate(); +}; + +// The main entry point of an IME shared library. +// +// This class is implemented in the shared library and processes messages from +// clients of the IME service. The shared library will exposes its create +// function to the IME service. +class ImeEngineMainEntry { + public: + // Returns whether a specific IME is supported by this IME shared library. + // The argument is the specfiation name of an IME, and the caller should + // explicitly know the IME engine's naming rules. + virtual bool IsImeSupported(const char*) = 0; + + // Activate an engine instance in the shared library with an IME specfiation + // name and a bound `ImeClientDelegate` which is used to create a channel from + // the engine instance to the IME client. The ownership of `ImeClientDelegate` + // will be passed to the Main Entry. + virtual bool ActivateIme(const char*, ImeClientDelegate*) = 0; + + // Process data from an IME service in `ImeEngineMainEntry`. + // The data will be invalidated by IME service soon after this call. + virtual void Process(const uint8_t* data, size_t size) = 0; + + // Destroy the `ImeEngineMainEntry` instance, which is called in IME service + // on demand. + virtual void Destroy() = 0; + + protected: + ~ImeEngineMainEntry(); +}; + +// Create ImeEngineMainEntry instance from the IME engine shared library. +// +// Applications using IME engines must call this function before any others. +// The caller will take ownership of the returned pointer and is responsible for +// deleting the ImeEngineMainEntry by calling `Destroy` on it when it's done. +// +// The provided `Platform` must remain valid until the `ImeEngineMainEntry` +// is destroyed. +// +// IME engine shared library must implement this function and export it with the +// name defined in IME_MAIN_ENTRY_CREATE_FN_NAME. +// +// Returns an instance of ImeEngineMainEntry from the IME shared library. +typedef ImeEngineMainEntry* (*ImeMainEntryCreateFn)(Platform*); + +// Defined name of ImeMainEntryCreateFn exported from shared library. +#define IME_MAIN_ENTRY_CREATE_FN_NAME "CreateImeMainEntry" + +} // namespace ime +} // namespace chromeos + +#endif // CHROMEOS_SERVICES_IME_PUBLIC_CPP_SHARED_LIB_INTERFACES_H_
diff --git a/components/autofill/content/renderer/form_autofill_util.cc b/components/autofill/content/renderer/form_autofill_util.cc index bc09293..f3894b9c 100644 --- a/components/autofill/content/renderer/form_autofill_util.cc +++ b/components/autofill/content/renderer/form_autofill_util.cc
@@ -16,6 +16,7 @@ #include "base/command_line.h" #include "base/i18n/case_conversion.h" #include "base/logging.h" +#include "base/metrics/field_trial.h" #include "base/metrics/histogram_macros.h" #include "base/no_destructor.h" #include "base/stl_util.h" @@ -98,6 +99,15 @@ FILTER_NON_FOCUSABLE_ELEMENTS, }; +// Returns whether sending autofill field metadata to the server is enabled. +// TODO(crbug.com/938804): Remove this when button titles are crowdsourced in +// all channels. +bool IsAutofillFieldMetadataEnabled() { + static base::NoDestructor<std::string> kGroupName( + base::FieldTrialList::FindFullName("AutofillFieldMetadata")); + return base::StartsWith(*kGroupName, "Enabled", base::CompareCase::SENSITIVE); +} + void TruncateString(base::string16* str, size_t max_length) { if (str->length() > max_length) str->resize(max_length); @@ -1415,7 +1425,7 @@ FormData* form, FormFieldData* field) { form->origin = GetCanonicalOriginForDocument(document); - if (!document.Body().IsNull()) { + if (IsAutofillFieldMetadataEnabled() && !document.Body().IsNull()) { SCOPED_UMA_HISTOGRAM_TIMER( "PasswordManager.ButtonTitlePerformance.NoFormTag"); form->button_titles = InferButtonTitlesForForm(document.Body()); @@ -1796,7 +1806,7 @@ form->unique_renderer_id = form_element.UniqueRendererFormId(); form->origin = GetCanonicalOriginForDocument(frame->GetDocument()); form->action = GetCanonicalActionForForm(form_element); - { + if (IsAutofillFieldMetadataEnabled()) { SCOPED_UMA_HISTOGRAM_TIMER( "PasswordManager.ButtonTitlePerformance.HasFormTag"); form->button_titles = InferButtonTitlesForForm(form_element);
diff --git a/components/browser_sync/browser_sync_switches.cc b/components/browser_sync/browser_sync_switches.cc index 35e898c..caf84911e 100644 --- a/components/browser_sync/browser_sync_switches.cc +++ b/components/browser_sync/browser_sync_switches.cc
@@ -27,9 +27,8 @@ const char kLocalSyncBackendDir[] = "local-sync-backend-dir"; // If enabled, the sync engine will be shut down in the "paused" state. -// TODO(crbug.com/938819): Remove this after M74 has fully rolled out. const base::Feature kStopSyncInPausedState{"StopSyncInPausedState", - base::FEATURE_ENABLED_BY_DEFAULT}; + base::FEATURE_DISABLED_BY_DEFAULT}; bool IsSyncAllowedByFlag() { return !base::CommandLine::ForCurrentProcess()->HasSwitch(
diff --git a/components/invalidation/impl/channels_states.cc b/components/invalidation/impl/channels_states.cc index 5ba702b6..8ead1b1 100644 --- a/components/invalidation/impl/channels_states.cc +++ b/components/invalidation/impl/channels_states.cc
@@ -17,4 +17,17 @@ } } +const char* SubscriptionChannelStateToString(SubscriptionChannelState state) { + switch (state) { + case SubscriptionChannelState::NOT_STARTED: + return "NOT_STARTED"; + case SubscriptionChannelState::ENABLED: + return "ENABLED"; + case SubscriptionChannelState::ACCESS_TOKEN_FAILURE: + return "ACCESS_TOKEN_FAILURE"; + case SubscriptionChannelState::SUBSCRIPTION_FAILURE: + return "SUBSCRIPTION_FAILURE"; + } +} + } // namespace syncer
diff --git a/components/invalidation/impl/channels_states.h b/components/invalidation/impl/channels_states.h index 2bc3eac9..97d84b7e 100644 --- a/components/invalidation/impl/channels_states.h +++ b/components/invalidation/impl/channels_states.h
@@ -17,8 +17,19 @@ kMaxValue = NO_INSTANCE_ID_TOKEN, }; +enum class SubscriptionChannelState { + NOT_STARTED, + ENABLED, + ACCESS_TOKEN_FAILURE, + SUBSCRIPTION_FAILURE, + + kMaxValue = SUBSCRIPTION_FAILURE, +}; + const char* FcmChannelStateToString(FcmChannelState state); +const char* SubscriptionChannelStateToString(SubscriptionChannelState state); + } // namespace syncer #endif // COMPONENTS_INVALIDATION_IMPL_CHANNELS_STATES_H_
diff --git a/components/invalidation/impl/fcm_invalidation_listener.cc b/components/invalidation/impl/fcm_invalidation_listener.cc index 783c531b..1da1397 100644 --- a/components/invalidation/impl/fcm_invalidation_listener.cc +++ b/components/invalidation/impl/fcm_invalidation_listener.cc
@@ -58,7 +58,7 @@ void FCMInvalidationListener::Ready(InvalidationClient* client) { DCHECK_EQ(client, invalidation_client_.get()); - subscription_channel_state_ = INVALIDATIONS_ENABLED; + subscription_channel_state_ = SubscriptionChannelState::ENABLED; EmitStateChange(); DoRegistrationUpdate(); } @@ -199,25 +199,22 @@ } per_user_topic_registration_manager_.reset(); - subscription_channel_state_ = DEFAULT_INVALIDATION_ERROR; + subscription_channel_state_ = SubscriptionChannelState::NOT_STARTED; fcm_network_state_ = FcmChannelState::NOT_STARTED; } InvalidatorState FCMInvalidationListener::GetState() const { - if (subscription_channel_state_ == INVALIDATION_CREDENTIALS_REJECTED) { - // If either the ticl or the push client rejected our credentials, - // return INVALIDATION_CREDENTIALS_REJECTED. + if (subscription_channel_state_ == + SubscriptionChannelState::ACCESS_TOKEN_FAILURE) { return INVALIDATION_CREDENTIALS_REJECTED; } - if (subscription_channel_state_ == INVALIDATIONS_ENABLED && + if (subscription_channel_state_ == SubscriptionChannelState::ENABLED && fcm_network_state_ == FcmChannelState::ENABLED) { // If the ticl is ready and the push client notifications are // enabled, return INVALIDATIONS_ENABLED. return INVALIDATIONS_ENABLED; } - if (subscription_channel_state_ == SUBSCRIPTION_FAILURE) { - return SUBSCRIPTION_FAILURE; - } + // Otherwise, we have a transient error. return TRANSIENT_INVALIDATION_ERROR; } @@ -232,8 +229,8 @@ } void FCMInvalidationListener::OnSubscriptionChannelStateChanged( - InvalidatorState invalidator_state) { - subscription_channel_state_ = invalidator_state; + SubscriptionChannelState state) { + subscription_channel_state_ = state; EmitStateChange(); } @@ -242,8 +239,9 @@ per_user_topic_registration_manager_->CollectDebugData(); status.SetString("InvalidationListener.FCM-channel-state", FcmChannelStateToString(fcm_network_state_)); - status.SetString("InvalidationListener.Subscription-channel-state", - InvalidatorStateToString(subscription_channel_state_)); + status.SetString( + "InvalidationListener.Subscription-channel-state", + SubscriptionChannelStateToString(subscription_channel_state_)); for (const Topic& topic : registered_topics_) { if (!status.HasKey(topic)) { status.SetString(topic, "Unregistered");
diff --git a/components/invalidation/impl/fcm_invalidation_listener.h b/components/invalidation/impl/fcm_invalidation_listener.h index 2269093a..ffe83d2 100644 --- a/components/invalidation/impl/fcm_invalidation_listener.h +++ b/components/invalidation/impl/fcm_invalidation_listener.h
@@ -87,7 +87,7 @@ // PerUserTopicRegistrationManager::Observer implementation. void OnSubscriptionChannelStateChanged( - InvalidatorState invalidator_state) override; + SubscriptionChannelState state) override; void DoRegistrationUpdate(); @@ -139,7 +139,8 @@ TopicSet registered_topics_; // The states of the HTTP and FCM channel. - InvalidatorState subscription_channel_state_ = DEFAULT_INVALIDATION_ERROR; + SubscriptionChannelState subscription_channel_state_ = + SubscriptionChannelState::NOT_STARTED; FcmChannelState fcm_network_state_ = FcmChannelState::NOT_STARTED; std::unique_ptr<PerUserTopicRegistrationManager>
diff --git a/components/invalidation/impl/per_user_topic_registration_manager.cc b/components/invalidation/impl/per_user_topic_registration_manager.cc index 420959ee..2b6f5af 100644 --- a/components/invalidation/impl/per_user_topic_registration_manager.cc +++ b/components/invalidation/impl/per_user_topic_registration_manager.cc
@@ -270,7 +270,7 @@ if (all_subscription_completed && base::FeatureList::IsEnabled( invalidation::switches::kFCMInvalidationsConservativeEnabling)) { - NotifySubscriptionChannelStateChange(INVALIDATIONS_ENABLED); + NotifySubscriptionChannelStateChange(SubscriptionChannelState::ENABLED); } } @@ -308,7 +308,8 @@ if (type == PerUserTopicRegistrationRequest::SUBSCRIBE && base::FeatureList::IsEnabled( invalidation::switches::kFCMInvalidationsConservativeEnabling)) { - NotifySubscriptionChannelStateChange(SUBSCRIPTION_FAILURE); + NotifySubscriptionChannelStateChange( + SubscriptionChannelState::SUBSCRIPTION_FAILURE); } if (!code.ShouldRetry()) { registration_statuses_.erase(it); @@ -374,14 +375,15 @@ request_access_token_backoff_.Reset(); access_token_ = access_token; // Emit ENABLED when successfully got the token. - NotifySubscriptionChannelStateChange(INVALIDATIONS_ENABLED); + NotifySubscriptionChannelStateChange(SubscriptionChannelState::ENABLED); DoRegistrationUpdate(); } void PerUserTopicRegistrationManager::OnAccessTokenRequestFailed( GoogleServiceAuthError error) { DCHECK_NE(error.state(), GoogleServiceAuthError::NONE); - NotifySubscriptionChannelStateChange(INVALIDATION_CREDENTIALS_REJECTED); + NotifySubscriptionChannelStateChange( + SubscriptionChannelState::ACCESS_TOKEN_FAILURE); request_access_token_backoff_.InformOfRequest(false); request_access_token_retry_timer_.Start( FROM_HERE, request_access_token_backoff_.GetTimeUntilRelease(), @@ -410,18 +412,19 @@ } void PerUserTopicRegistrationManager::NotifySubscriptionChannelStateChange( - InvalidatorState invalidator_state) { - // TRANSIENT_INVALIDATION_ERROR is the default state of the subscription + SubscriptionChannelState state) { + // NOT_STARTED is the default state of the subscription // channel and shouldn't explicitly issued. - DCHECK(invalidator_state != TRANSIENT_INVALIDATION_ERROR); - if (last_issued_state_ == invalidator_state) { + DCHECK(state != SubscriptionChannelState::NOT_STARTED); + if (last_issued_state_ == state) { // Notify only on state change. return; } - last_issued_state_ = invalidator_state; - for (auto& observer : observers_) - observer.OnSubscriptionChannelStateChanged(invalidator_state); + last_issued_state_ = state; + for (auto& observer : observers_) { + observer.OnSubscriptionChannelStateChanged(state); + } } base::DictionaryValue PerUserTopicRegistrationManager::CollectDebugData()
diff --git a/components/invalidation/impl/per_user_topic_registration_manager.h b/components/invalidation/impl/per_user_topic_registration_manager.h index 2af273d..7bff4f69 100644 --- a/components/invalidation/impl/per_user_topic_registration_manager.h +++ b/components/invalidation/impl/per_user_topic_registration_manager.h
@@ -13,6 +13,7 @@ #include "base/sequence_checker.h" #include "base/time/time.h" #include "base/timer/timer.h" +#include "components/invalidation/impl/channels_states.h" #include "components/invalidation/impl/per_user_topic_registration_request.h" #include "components/invalidation/public/identity_provider.h" #include "components/invalidation/public/invalidation_export.h" @@ -46,7 +47,7 @@ class Observer { public: virtual void OnSubscriptionChannelStateChanged( - InvalidatorState invalidator_state) = 0; + SubscriptionChannelState state) = 0; }; PerUserTopicRegistrationManager( @@ -105,7 +106,8 @@ void DropAllSavedRegistrationsOnTokenChange( const std::string& instance_id_token); - void NotifySubscriptionChannelStateChange(InvalidatorState invalidator_state); + void NotifySubscriptionChannelStateChange( + SubscriptionChannelState invalidator_state); std::map<Topic, std::unique_ptr<RegistrationEntry>> registration_statuses_; @@ -131,7 +133,8 @@ const std::string project_id_; base::ObserverList<Observer>::Unchecked observers_; - InvalidatorState last_issued_state_ = TRANSIENT_INVALIDATION_ERROR; + SubscriptionChannelState last_issued_state_ = + SubscriptionChannelState::NOT_STARTED; SEQUENCE_CHECKER(sequence_checker_);
diff --git a/components/invalidation/impl/per_user_topic_registration_manager_unittest.cc b/components/invalidation/impl/per_user_topic_registration_manager_unittest.cc index fd2db05b..2d13321 100644 --- a/components/invalidation/impl/per_user_topic_registration_manager_unittest.cc +++ b/components/invalidation/impl/per_user_topic_registration_manager_unittest.cc
@@ -95,14 +95,15 @@ class RegistrationManagerStateObserver : public PerUserTopicRegistrationManager::Observer { public: - void OnSubscriptionChannelStateChanged(InvalidatorState state) override { + void OnSubscriptionChannelStateChanged( + SubscriptionChannelState state) override { state_ = state; } - InvalidatorState observed_state() const { return state_; } + SubscriptionChannelState observed_state() const { return state_; } private: - InvalidatorState state_ = TRANSIENT_INVALIDATION_ERROR; + SubscriptionChannelState state_ = SubscriptionChannelState::NOT_STARTED; }; class PerUserTopicRegistrationManagerTest : public testing::Test { @@ -138,7 +139,9 @@ TestingPrefServiceSimple* pref_service() { return &pref_service_; } - InvalidatorState observed_state() { return state_observer_.observed_state(); } + SubscriptionChannelState observed_state() { + return state_observer_.observed_state(); + } void AddCorrectSubscriptionResponce( const std::string& private_topic = std::string(), @@ -416,7 +419,7 @@ ids, kFakeInstanceIdToken); base::RunLoop().RunUntilIdle(); EXPECT_EQ(ids, per_user_topic_registration_manager->GetRegisteredIds()); - EXPECT_EQ(observed_state(), INVALIDATIONS_ENABLED); + EXPECT_EQ(observed_state(), SubscriptionChannelState::ENABLED); // Disable some ids. TopicSet disabled_ids = GetSequenceOfTopics(3); @@ -434,7 +437,7 @@ FullSubscriptionUrl(kFakeInstanceIdToken).spec(), std::string() /* content */, net::HTTP_NOT_FOUND); - EXPECT_EQ(observed_state(), INVALIDATIONS_ENABLED); + EXPECT_EQ(observed_state(), SubscriptionChannelState::ENABLED); } TEST_F(PerUserTopicRegistrationManagerTest, @@ -453,7 +456,7 @@ ids, kFakeInstanceIdToken); base::RunLoop().RunUntilIdle(); EXPECT_EQ(ids, per_user_topic_registration_manager->GetRegisteredIds()); - EXPECT_EQ(observed_state(), INVALIDATIONS_ENABLED); + EXPECT_EQ(observed_state(), SubscriptionChannelState::ENABLED); // Disable some ids. TopicSet disabled_ids = GetSequenceOfTopics(3); @@ -472,14 +475,14 @@ per_user_topic_registration_manager->UpdateRegisteredTopics( ids, kFakeInstanceIdToken); base::RunLoop().RunUntilIdle(); - EXPECT_EQ(observed_state(), SUBSCRIPTION_FAILURE); + EXPECT_EQ(observed_state(), SubscriptionChannelState::SUBSCRIPTION_FAILURE); // Configure correct response and retry. AddCorrectSubscriptionResponce(); per_user_topic_registration_manager->UpdateRegisteredTopics( ids, kFakeInstanceIdToken); base::RunLoop().RunUntilIdle(); - EXPECT_EQ(observed_state(), INVALIDATIONS_ENABLED); + EXPECT_EQ(observed_state(), SubscriptionChannelState::ENABLED); } } // namespace syncer
diff --git a/components/language/core/common/BUILD.gn b/components/language/core/common/BUILD.gn index 7ee80f9..2a11b2e 100644 --- a/components/language/core/common/BUILD.gn +++ b/components/language/core/common/BUILD.gn
@@ -6,6 +6,8 @@ sources = [ "language_experiments.cc", "language_experiments.h", + "language_util.cc", + "language_util.h", "locale_util.cc", "locale_util.h", ] @@ -19,6 +21,7 @@ source_set("unit_tests") { testonly = true sources = [ + "language_util_unittest.cc", "locale_util_unittest.cc", ] deps = [
diff --git a/components/language/core/common/language_util.cc b/components/language/core/common/language_util.cc new file mode 100644 index 0000000..f7bf4497 --- /dev/null +++ b/components/language/core/common/language_util.cc
@@ -0,0 +1,118 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/language/core/common/language_util.h" + +#include <stddef.h> +#include <algorithm> + +#include "base/stl_util.h" +#include "components/language/core/common/locale_util.h" + +namespace language { + +struct LanguageCodePair { + // Code used in supporting list of Translate. + const char* const translate_language; + + // Code used in Chrome internal. + const char* const chrome_language; +}; + +// Some languages are treated as same languages in Translate even though they +// are different to be exact. +// +// If this table is updated, please sync this with the synonym table in +// chrome/browser/resources/settings/languages_page/languages.js. +const LanguageCodePair kLanguageCodeSimilitudes[] = { + {"no", "nb"}, + {"tl", "fil"}, +}; + +// Some languages have changed codes over the years and sometimes the older +// codes are used, so we must see them as synonyms. +// +// If this table is updated, please sync this with the synonym table in +// chrome/browser/resources/settings/languages_page/languages.js. +const LanguageCodePair kLanguageCodeSynonyms[] = { + {"iw", "he"}, + {"jw", "jv"}, +}; + +// Some Chinese language codes are compatible with zh-TW or zh-CN in terms of +// Translate. +// +// If this table is updated, please sync this with the synonym table in +// chrome/browser/resources/settings/languages_page/languages.js. +const LanguageCodePair kLanguageCodeChineseCompatiblePairs[] = { + {"zh-TW", "zh-HK"}, + {"zh-TW", "zh-MO"}, + {"zh-CN", "zh-SG"}, +}; + +void ToTranslateLanguageSynonym(std::string* language) { + for (size_t i = 0; i < base::size(kLanguageCodeSimilitudes); ++i) { + if (*language == kLanguageCodeSimilitudes[i].chrome_language) { + *language = kLanguageCodeSimilitudes[i].translate_language; + return; + } + } + + std::string main_part, tail_part; + language::SplitIntoMainAndTail(*language, &main_part, &tail_part); + if (main_part.empty()) + return; + + // Chinese is a special case: we do not return the main_part only. + // There is not a single base language, but two: traditional and simplified. + // The kLanguageCodeChineseCompatiblePairs list contains the relation between + // various Chinese locales. We need to return the code from that mapping + // instead of the main_part. + // Note that "zh" does not have any mapping and as such we leave it as is. See + // https://crbug/798512 for more info. + for (size_t i = 0; i < base::size(kLanguageCodeChineseCompatiblePairs); ++i) { + if (*language == kLanguageCodeChineseCompatiblePairs[i].chrome_language) { + *language = kLanguageCodeChineseCompatiblePairs[i].translate_language; + return; + } + } + if (main_part == "zh") { + return; + } + + // Apply linear search here because number of items in the list is just four. + for (size_t i = 0; i < base::size(kLanguageCodeSynonyms); ++i) { + if (main_part == kLanguageCodeSynonyms[i].chrome_language) { + main_part = std::string(kLanguageCodeSynonyms[i].translate_language); + break; + } + } + + *language = main_part; +} + +void ToChromeLanguageSynonym(std::string* language) { + for (size_t i = 0; i < base::size(kLanguageCodeSimilitudes); ++i) { + if (*language == kLanguageCodeSimilitudes[i].translate_language) { + *language = kLanguageCodeSimilitudes[i].chrome_language; + return; + } + } + + std::string main_part, tail_part; + language::SplitIntoMainAndTail(*language, &main_part, &tail_part); + if (main_part.empty()) + return; + + // Apply liner search here because number of items in the list is just four. + for (size_t i = 0; i < base::size(kLanguageCodeSynonyms); ++i) { + if (main_part == kLanguageCodeSynonyms[i].translate_language) { + main_part = std::string(kLanguageCodeSynonyms[i].chrome_language); + break; + } + } + + *language = main_part + tail_part; +} +} // namespace language
diff --git a/components/language/core/common/language_util.h b/components/language/core/common/language_util.h new file mode 100644 index 0000000..453a270 --- /dev/null +++ b/components/language/core/common/language_util.h
@@ -0,0 +1,24 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_LANGUAGE_CORE_COMMON_LANGUAGE_UTIL_H_ +#define COMPONENTS_LANGUAGE_CORE_COMMON_LANGUAGE_UTIL_H_ + +#include <string> + +namespace language { + +// Converts language code synonym to use at Translate server. +// +// The same logic exists in +// chrome/browser/resources/settings/languages_page/languages.js, +// please keep consistency with the JavaScript file. +void ToTranslateLanguageSynonym(std::string* language); + +// Converts language code synonym to use at Chrome internal. +void ToChromeLanguageSynonym(std::string* language); + +} // namespace language + +#endif // COMPONENTS_LANGUAGE_CORE_COMMON_LANGUAGE_UTIL_H_
diff --git a/components/language/core/common/language_util_unittest.cc b/components/language/core/common/language_util_unittest.cc new file mode 100644 index 0000000..20eff9b --- /dev/null +++ b/components/language/core/common/language_util_unittest.cc
@@ -0,0 +1,65 @@ +// 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 "components/language/core/common/language_util.h" + +#include "testing/gtest/include/gtest/gtest.h" + +typedef testing::Test LanguageUtilTest; + +// Tests that synonym language code is converted to one used in supporting list. +TEST_F(LanguageUtilTest, ToTranslateLanguageSynonym) { + std::string language; + + language = std::string("nb"); + language::ToTranslateLanguageSynonym(&language); + EXPECT_EQ("no", language); + + // Test all known Chinese cases. + language = std::string("zh-HK"); + language::ToTranslateLanguageSynonym(&language); + EXPECT_EQ("zh-TW", language); + language = std::string("zh-MO"); + language::ToTranslateLanguageSynonym(&language); + EXPECT_EQ("zh-TW", language); + language = std::string("zh-SG"); + language::ToTranslateLanguageSynonym(&language); + EXPECT_EQ("zh-CN", language); + language = std::string("zh"); + language::ToTranslateLanguageSynonym(&language); + EXPECT_EQ("zh", language); + + // A sub code is not preserved (except for Chinese). + language = std::string("he-IL"); + language::ToTranslateLanguageSynonym(&language); + EXPECT_EQ("iw", language); + + language = std::string("zh-JP"); + language::ToTranslateLanguageSynonym(&language); + EXPECT_EQ("zh-JP", language); + + // Preserve the argument if it doesn't have its synonym. + language = std::string("en"); + language::ToTranslateLanguageSynonym(&language); + EXPECT_EQ("en", language); +} + +// Tests that synonym language code is converted to one used in Chrome internal. +TEST_F(LanguageUtilTest, ToChromeLanguageSynonym) { + std::string language; + + language = std::string("no"); + language::ToChromeLanguageSynonym(&language); + EXPECT_EQ("nb", language); + + // Preserve a sub code + language = std::string("iw-IL"); + language::ToChromeLanguageSynonym(&language); + EXPECT_EQ("he-IL", language); + + // Preserve the argument if it doesn't have its synonym. + language = std::string("en"); + language::ToChromeLanguageSynonym(&language); + EXPECT_EQ("en", language); +} \ No newline at end of file
diff --git a/components/password_manager/core/browser/sync/password_sync_bridge.cc b/components/password_manager/core/browser/sync/password_sync_bridge.cc index beadf7e..8fc6902e 100644 --- a/components/password_manager/core/browser/sync/password_sync_bridge.cc +++ b/components/password_manager/core/browser/sync/password_sync_bridge.cc
@@ -390,19 +390,35 @@ PasswordStoreChangeList changes = password_store_sync_->AddLoginSync( PasswordFromEntityChange(entity_change, /*sync_time=*/time_now)); - DCHECK_LE(changes.size(), 1U); + // TODO(crbug.com/939302): It's not yet clear if the DCHECK_LE below is + // legit. However, recent crashes suggest that 2 changes are returned + // when trying to AddLoginSync (details are in the bug). Once this is + // resolved, we should update the call the UpdateStorageKey() if + // necessary and remove unnecessary DCHECKs below. + // DCHECK_LE(changes.size(), 1U); + DCHECK_LE(changes.size(), 2U); if (changes.empty()) { return syncer::ModelError( FROM_HERE, "Failed to add an entry in the password store."); } + if (changes.size() == 1) { + DCHECK_EQ(changes[0].type(), PasswordStoreChange::ADD); + } else { + // There must be 2 changes. + DCHECK_EQ(changes[0].type(), PasswordStoreChange::REMOVE); + DCHECK_EQ(changes[1].type(), PasswordStoreChange::ADD); + } + change_processor()->UpdateStorageKey( entity_change.data(), /*storage_key=*/ - base::NumberToString(changes[0].primary_key()), + base::NumberToString(changes.back().primary_key()), metadata_change_list.get()); - password_store_changes.push_back(changes[0]); + + password_store_changes.insert(password_store_changes.end(), + changes.begin(), changes.end()); } // Persist the metadata changes. @@ -456,12 +472,25 @@ return syncer::ModelError( FROM_HERE, "Failed to add an entry to the password store."); } - DCHECK_EQ(1U, changes.size()); - DCHECK_EQ(PasswordStoreChange::ADD, changes[0].type()); + // TODO(crbug.com/939302): It's not yet clear if the DCHECK_LE below + // is legit. However, recent crashes suggest that 2 changes are + // returned when trying to AddLoginSync (details are in the bug). Once + // this is resolved, we should update the call the UpdateStorageKey() + // if necessary and remove unnecessary DCHECKs below. + // DCHECK_EQ(1U, changes.size()); + DCHECK_LE(changes.size(), 2U); + if (changes.size() == 1) { + DCHECK_EQ(changes[0].type(), PasswordStoreChange::ADD); + } else { + // There must be 2 changes. + DCHECK_EQ(changes[0].type(), PasswordStoreChange::REMOVE); + DCHECK_EQ(changes[1].type(), PasswordStoreChange::ADD); + } + change_processor()->UpdateStorageKey( entity_change.data(), /*storage_key=*/ - base::NumberToString(changes[0].primary_key()), + base::NumberToString(changes.back().primary_key()), metadata_change_list.get()); break; case syncer::EntityChange::ACTION_UPDATE: @@ -489,7 +518,8 @@ break; } } - password_store_changes.push_back(changes[0]); + password_store_changes.insert(password_store_changes.end(), + changes.begin(), changes.end()); } // Persist the metadata changes.
diff --git a/components/policy/content/BUILD.gn b/components/policy/content/BUILD.gn index 630c91f..faf39e8 100644 --- a/components/policy/content/BUILD.gn +++ b/components/policy/content/BUILD.gn
@@ -21,6 +21,7 @@ "//components/policy/core/browser", "//components/prefs", "//components/safe_search_api", + "//components/safe_search_api:safe_search_client", "//components/user_prefs:user_prefs", "//content/public/browser", "//net", @@ -38,6 +39,7 @@ "//components/keyed_service/content", "//components/policy/core/browser", "//components/safe_search_api", + "//components/safe_search_api:safe_search_client", "//components/safe_search_api:test_support", "//components/sync_preferences:test_support", "//components/user_prefs:user_prefs",
diff --git a/components/policy/content/policy_blacklist_service.cc b/components/policy/content/policy_blacklist_service.cc index 3c04cd0..0aab90c 100644 --- a/components/policy/content/policy_blacklist_service.cc +++ b/components/policy/content/policy_blacklist_service.cc
@@ -10,6 +10,7 @@ #include "base/sequence_checker.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/policy/core/browser/url_util.h" +#include "components/safe_search_api/safe_search/safe_search_url_checker_client.h" #include "components/safe_search_api/url_checker.h" #include "components/user_prefs/user_prefs.h" #include "content/public/browser/browser_context.h" @@ -72,11 +73,12 @@ } })"); - // TODO(michaelpg): Find the country code. safe_search_url_checker_ = std::make_unique<safe_search_api::URLChecker>( - content::BrowserContext::GetDefaultStoragePartition(browser_context_) - ->GetURLLoaderFactoryForBrowserProcess(), - traffic_annotation, std::string()); + std::make_unique<safe_search_api::SafeSearchURLCheckerClient>( + content::BrowserContext::GetDefaultStoragePartition( + browser_context_) + ->GetURLLoaderFactoryForBrowserProcess(), + traffic_annotation)); } return safe_search_url_checker_->CheckURL(
diff --git a/components/policy/proto/device_management_backend.proto b/components/policy/proto/device_management_backend.proto index 9a803d98..194575b 100644 --- a/components/policy/proto/device_management_backend.proto +++ b/components/policy/proto/device_management_backend.proto
@@ -374,6 +374,12 @@ optional DisabledState disabled_state = 2; } +message CustomerLogo { + // The SCS url for the logo set by the admin for a particular OU. + // This is in the form https://admin.googleusercontent.com/<scs_url_key>. + optional string logo_url = 1; +} + // This message is included in serialized form in PolicyFetchResponse below. It // may also be signed, with the signature being created for the serialized form. message PolicyData { @@ -548,6 +554,12 @@ // This field should only be set for Device Policy response. // See go/cros-rlz-segments optional MarketSegment market_segment = 30; + + // This field is currently only set for Device Policy response. + // This represents the logo set by the admin for the OU that the device + // belongs to. This is domain metadata included in a device policy response, + // but it is not an explicit device policy. + optional CustomerLogo customer_logo = 31; } message PolicyFetchResponse {
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index a982c003..846721a 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -717,6 +717,7 @@ 'BrowserSwitcherDelay', 'BrowserSwitcherEnabled', 'BrowserSwitcherExternalSitelistUrl', + 'BrowserSwitcherKeepLastChromeTab', 'BrowserSwitcherUrlList', 'BrowserSwitcherUrlGreylist', 'BrowserSwitcherUseIeSitelist', @@ -3323,9 +3324,9 @@ 'id': 528, 'caption': '''Use KDC policy to delegate credentials.''', 'tags': ['website-sharing'], - 'desc': '''Controls whether approval by KDC policy is respected to decide whether to delegate Kerberos tickets. + 'desc': '''Controls whether approval by KDC policy is respected to decide whether to delegate <ph name="KERBEROS">Kerberos</ph> tickets. - If this policy is true, HTTP authentication respects approval by KDC policy, i.e. Chrome only delegates credentials if the KDC sets OK-AS-DELEGATE on a service ticket. Please see https://tools.ietf.org/html/rfc5896.html for more information. Service should also match 'AuthNegotiateDelegateWhitelist' policy. + If this policy is true, HTTP authentication respects approval by KDC policy, i.e. Chrome only delegates credentials if the KDC sets <ph name="OK_AS_DELEGATE">OK-AS-DELEGATE</ph> on a service ticket. Please see https://tools.ietf.org/html/rfc5896.html for more information. Service should also match 'AuthNegotiateDelegateWhitelist' policy. If this policy is not set or set to false, KDC policy is ignored on supported platforms and 'AuthNegotiateDelegateWhitelist' policy only is respected.
diff --git a/components/safe_search_api/BUILD.gn b/components/safe_search_api/BUILD.gn index 7883ba3f..2c3b2ff1 100644 --- a/components/safe_search_api/BUILD.gn +++ b/components/safe_search_api/BUILD.gn
@@ -6,11 +6,26 @@ sources = [ "url_checker.cc", "url_checker.h", + "url_checker_client.h", ] deps = [ "//base", "//components/google/core/common", + "//url", + ] +} + +source_set("safe_search_client") { + sources = [ + "safe_search/safe_search_url_checker_client.cc", + "safe_search/safe_search_url_checker_client.h", + ] + + deps = [ + ":safe_search_api", + "//base", + "//components/google/core/common", "//google_apis", "//net", "//services/network/public/cpp", @@ -21,11 +36,14 @@ source_set("test_support") { testonly = true sources = [ + "fake_url_checker_client.cc", + "fake_url_checker_client.h", "stub_url_checker.cc", "stub_url_checker.h", ] deps = [ ":safe_search_api", + ":safe_search_client", "//base", "//base/test:test_support", "//net", @@ -39,14 +57,19 @@ source_set("unit_tests") { testonly = true sources = [ + "safe_search/safe_search_url_checker_client_unittest.cc", "url_checker_unittest.cc", ] deps = [ ":safe_search_api", + ":safe_search_client", ":test_support", "//base", "//base/test:test_support", "//net", + "//net/traffic_annotation:test_support", + "//services/network:test_support", + "//services/network/public/cpp", "//testing/gmock", "//testing/gtest", "//url",
diff --git a/components/safe_search_api/fake_url_checker_client.cc b/components/safe_search_api/fake_url_checker_client.cc new file mode 100644 index 0000000..c7a5a5c --- /dev/null +++ b/components/safe_search_api/fake_url_checker_client.cc
@@ -0,0 +1,28 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/safe_search_api/fake_url_checker_client.h" + +#include <utility> + +#include "base/callback.h" + +namespace safe_search_api { + +FakeURLCheckerClient::FakeURLCheckerClient() = default; + +FakeURLCheckerClient::~FakeURLCheckerClient() = default; + +void FakeURLCheckerClient::CheckURL(const GURL& url, + ClientCheckCallback callback) { + url_ = url; + DCHECK(!callback_); + callback_ = std::move(callback); +} + +void FakeURLCheckerClient::RunCallback(ClientClassification classification) { + std::move(callback_).Run(url_, classification); +} + +} // namespace safe_search_api
diff --git a/components/safe_search_api/fake_url_checker_client.h b/components/safe_search_api/fake_url_checker_client.h new file mode 100644 index 0000000..9c1d971 --- /dev/null +++ b/components/safe_search_api/fake_url_checker_client.h
@@ -0,0 +1,39 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_SAFE_SEARCH_API_FAKE_URL_CHECKER_CLIENT_H_ +#define COMPONENTS_SAFE_SEARCH_API_FAKE_URL_CHECKER_CLIENT_H_ + +#include "base/callback.h" +#include "components/safe_search_api/url_checker_client.h" + +namespace safe_search_api { + +// Helper class with fake URLCheckerClient for use with URLChecker. This +// lets tests control the response the URLChecker will receive from the +// URLCheckerClient. Used to test URLChecker. +class FakeURLCheckerClient : public URLCheckerClient { + public: + FakeURLCheckerClient(); + ~FakeURLCheckerClient() override; + + // Fake override that simply holds references of |url| and |callback|. + // + // See RunCallback() method documentation below on how to run the callback. + void CheckURL(const GURL& url, ClientCheckCallback callback) override; + + // Run the callback function input by the last call of CheckURL() with the + // result input with the last call of SetResult(). + void RunCallback(ClientClassification classification); + + private: + ClientCheckCallback callback_; + GURL url_; + + DISALLOW_COPY_AND_ASSIGN(FakeURLCheckerClient); +}; + +} // namespace safe_search_api + +#endif // COMPONENTS_SAFE_SEARCH_API_FAKE_URL_CHECKER_CLIENT_H_
diff --git a/components/safe_search_api/safe_search/safe_search_url_checker_client.cc b/components/safe_search_api/safe_search/safe_search_url_checker_client.cc new file mode 100644 index 0000000..617a494 --- /dev/null +++ b/components/safe_search_api/safe_search/safe_search_url_checker_client.cc
@@ -0,0 +1,160 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/safe_search_api/safe_search/safe_search_url_checker_client.h" + +#include <utility> + +#include "base/callback.h" +#include "base/json/json_reader.h" +#include "base/metrics/histogram_macros.h" +#include "base/optional.h" +#include "base/stl_util.h" +#include "base/strings/string_piece.h" +#include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" +#include "base/time/time.h" +#include "base/values.h" +#include "components/google/core/common/google_util.h" +#include "net/base/escape.h" +#include "net/base/load_flags.h" +#include "net/url_request/url_request_status.h" +#include "services/network/public/cpp/resource_request.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" +#include "services/network/public/cpp/simple_url_loader.h" +#include "url/url_constants.h" + +namespace safe_search_api { + +namespace { + +const char kSafeSearchApiUrl[] = + "https://safesearch.googleapis.com/v1:classify"; +const char kDataContentType[] = "application/x-www-form-urlencoded"; +const char kDataFormat[] = "key=%s&urls=%s®ion_code=%s"; + +// Builds the POST data for SafeSearch API requests. +std::string BuildRequestData(const std::string& api_key, + const GURL& url, + const std::string& region_code) { + std::string query = net::EscapeQueryParamValue(url.spec(), true); + return base::StringPrintf(kDataFormat, api_key.c_str(), query.c_str(), + region_code.c_str()); +} + +// Parses a SafeSearch API |response| and stores the result in |is_porn|, +// returns true on success. Otherwise, returns false and doesn't set |is_porn|. +bool ParseResponse(const std::string& response, bool* is_porn) { + base::Optional<base::Value> optional_value = base::JSONReader::Read(response); + const base::DictionaryValue* dict = nullptr; + if (!optional_value || !optional_value.value().GetAsDictionary(&dict)) { + DLOG(WARNING) << "ParseResponse failed to parse global dictionary"; + return false; + } + const base::ListValue* classifications_list = nullptr; + if (!dict->GetList("classifications", &classifications_list)) { + DLOG(WARNING) << "ParseResponse failed to parse classifications list"; + return false; + } + if (classifications_list->GetSize() != 1) { + DLOG(WARNING) << "ParseResponse expected exactly one result"; + return false; + } + const base::DictionaryValue* classification_dict = nullptr; + if (!classifications_list->GetDictionary(0, &classification_dict)) { + DLOG(WARNING) << "ParseResponse failed to parse classification dict"; + return false; + } + classification_dict->GetBoolean("pornography", is_porn); + return true; +} + +} // namespace + +struct SafeSearchURLCheckerClient::Check { + Check(const GURL& url, + std::unique_ptr<network::SimpleURLLoader> simple_url_loader, + ClientCheckCallback callback); + ~Check(); + + GURL url; + ClientCheckCallback callback; + std::unique_ptr<network::SimpleURLLoader> simple_url_loader; + base::TimeTicks start_time; +}; + +SafeSearchURLCheckerClient::Check::Check( + const GURL& url, + std::unique_ptr<network::SimpleURLLoader> simple_url_loader, + ClientCheckCallback callback) + : url(url), + callback(std::move(callback)), + simple_url_loader(std::move(simple_url_loader)), + start_time(base::TimeTicks::Now()) {} + +SafeSearchURLCheckerClient::Check::~Check() = default; + +SafeSearchURLCheckerClient::SafeSearchURLCheckerClient( + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, + const net::NetworkTrafficAnnotationTag& traffic_annotation, + const std::string& country, + const std::string& api_key) + : url_loader_factory_(std::move(url_loader_factory)), + traffic_annotation_(traffic_annotation), + country_(country), + api_key_(api_key) {} + +SafeSearchURLCheckerClient::~SafeSearchURLCheckerClient() = default; + +void SafeSearchURLCheckerClient::CheckURL(const GURL& url, + ClientCheckCallback callback) { + DVLOG(1) << "Checking URL " << url; + auto resource_request = std::make_unique<network::ResourceRequest>(); + resource_request->url = GURL(kSafeSearchApiUrl); + resource_request->method = "POST"; + resource_request->load_flags = + net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES; + std::unique_ptr<network::SimpleURLLoader> simple_url_loader = + network::SimpleURLLoader::Create(std::move(resource_request), + traffic_annotation_); + simple_url_loader->AttachStringForUpload( + BuildRequestData(api_key_, url, country_), kDataContentType); + checks_in_progress_.push_front(std::make_unique<Check>( + url, std::move(simple_url_loader), std::move(callback))); + auto it = checks_in_progress_.begin(); + network::SimpleURLLoader* loader = it->get()->simple_url_loader.get(); + loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie( + url_loader_factory_.get(), + base::BindOnce(&SafeSearchURLCheckerClient::OnSimpleLoaderComplete, + base::Unretained(this), it)); +} + +void SafeSearchURLCheckerClient::OnSimpleLoaderComplete( + CheckList::iterator it, + std::unique_ptr<std::string> response_body) { + std::unique_ptr<Check> check = std::move(*it); + + checks_in_progress_.erase(it); + + if (!response_body) { + DLOG(WARNING) << "URL request failed! Letting through..."; + std::move(check->callback).Run(check->url, ClientClassification::kUnknown); + return; + } + + ClientClassification classification = ClientClassification::kUnknown; + bool is_porn = false; + if (ParseResponse(*response_body, &is_porn)) { + classification = is_porn ? ClientClassification::kRestricted + : ClientClassification::kAllowed; + } + + // TODO(msramek): Consider moving this to SupervisedUserResourceThrottle. + UMA_HISTOGRAM_TIMES("ManagedUsers.SafeSitesDelay", + base::TimeTicks::Now() - check->start_time); + + std::move(check->callback).Run(check->url, classification); +} + +} // namespace safe_search_api
diff --git a/components/safe_search_api/safe_search/safe_search_url_checker_client.h b/components/safe_search_api/safe_search/safe_search_url_checker_client.h new file mode 100644 index 0000000..49af799 --- /dev/null +++ b/components/safe_search_api/safe_search/safe_search_url_checker_client.h
@@ -0,0 +1,65 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_SAFE_SEARCH_API_SAFE_SEARCH_SAFE_SEARCH_URL_CHECKER_CLIENT_H_ +#define COMPONENTS_SAFE_SEARCH_API_SAFE_SEARCH_SAFE_SEARCH_URL_CHECKER_CLIENT_H_ + +#include <list> +#include <memory> +#include <string> + +#include "base/macros.h" +#include "base/memory/scoped_refptr.h" +#include "components/safe_search_api/url_checker_client.h" +#include "google_apis/google_api_keys.h" +#include "net/traffic_annotation/network_traffic_annotation.h" + +namespace network { +class SharedURLLoaderFactory; +} // namespace network + +namespace safe_search_api { + +// This class uses the SafeSearch API to check the SafeSearch classification +// of the content on a given URL and returns the result asynchronously +// via a callback. +class SafeSearchURLCheckerClient : public URLCheckerClient { + public: + // |country| should be a two-letter country code (ISO 3166-1 alpha-2), e.g., + // "us". Optional + SafeSearchURLCheckerClient( + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, + const net::NetworkTrafficAnnotationTag& traffic_annotation, + const std::string& country = std::string(), + const std::string& api_key = google_apis::GetAPIKey()); + + ~SafeSearchURLCheckerClient() override; + + // Checks whether an |url| is restricted according to SafeSearch. + // + // On failure, the |callback| function is called with |url| as the first + // parameter, and UNKNOWN as the second. + void CheckURL(const GURL& url, ClientCheckCallback callback) override; + + private: + struct Check; + + using CheckList = std::list<std::unique_ptr<Check>>; + + void OnSimpleLoaderComplete(CheckList::iterator it, + std::unique_ptr<std::string> response_body); + + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_; + const net::NetworkTrafficAnnotationTag traffic_annotation_; + const std::string country_; + const std::string api_key_; + + CheckList checks_in_progress_; + + DISALLOW_COPY_AND_ASSIGN(SafeSearchURLCheckerClient); +}; + +} // namespace safe_search_api + +#endif // COMPONENTS_SAFE_SEARCH_API_SAFE_SEARCH_SAFE_SEARCH_URL_CHECKER_CLIENT_H_
diff --git a/components/safe_search_api/safe_search/safe_search_url_checker_client_unittest.cc b/components/safe_search_api/safe_search/safe_search_url_checker_client_unittest.cc new file mode 100644 index 0000000..d42e3f06 --- /dev/null +++ b/components/safe_search_api/safe_search/safe_search_url_checker_client_unittest.cc
@@ -0,0 +1,136 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/safe_search_api/safe_search/safe_search_url_checker_client.h" + +#include <memory> +#include <utility> + +#include "base/bind.h" +#include "base/json/json_writer.h" +#include "base/test/scoped_task_environment.h" +#include "base/values.h" +#include "net/base/net_errors.h" +#include "net/http/http_util.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" +#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" +#include "services/network/test/test_url_loader_factory.h" +#include "testing/gmock/include/gmock/gmock.h" + +using testing::_; + +namespace safe_search_api { + +namespace { + +constexpr char kSafeSearchApiUrl[] = + "https://safesearch.googleapis.com/v1:classify"; + +std::string BuildResponse(bool is_porn) { + base::DictionaryValue dict; + auto classification_dict = std::make_unique<base::DictionaryValue>(); + if (is_porn) + classification_dict->SetBoolean("pornography", is_porn); + auto classifications_list = std::make_unique<base::ListValue>(); + classifications_list->Append(std::move(classification_dict)); + dict.SetWithoutPathExpansion("classifications", + std::move(classifications_list)); + std::string result; + base::JSONWriter::Write(dict, &result); + return result; +} + +const char* kURLs[] = { + "http://www.randomsite1.com", "http://www.randomsite2.com", + "http://www.randomsite3.com", "http://www.randomsite4.com", + "http://www.randomsite5.com", "http://www.randomsite6.com", + "http://www.randomsite7.com", "http://www.randomsite8.com", + "http://www.randomsite9.com", +}; + +} // namespace + +class SafeSearchURLCheckerClientTest : public testing::Test { + public: + SafeSearchURLCheckerClientTest() + : next_url_(0), + test_shared_loader_factory_( + base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( + &test_url_loader_factory_)) { + checker_ = std::make_unique<SafeSearchURLCheckerClient>( + test_shared_loader_factory_, TRAFFIC_ANNOTATION_FOR_TESTS); + } + + MOCK_METHOD2(OnCheckDone, + void(const GURL& url, ClientClassification classification)); + + protected: + GURL GetNewURL() { + CHECK(next_url_ < base::size(kURLs)); + return GURL(kURLs[next_url_++]); + } + + void CheckURL(const GURL& url) { + checker_->CheckURL( + url, base::BindOnce(&SafeSearchURLCheckerClientTest::OnCheckDone, + base::Unretained(this))); + } + + void WaitForResponse() { base::RunLoop().RunUntilIdle(); } + + void SetUpFailedResponse() { SetUpResponse(net::ERR_ABORTED, std::string()); } + + void SetUpResponse(net::Error error, const std::string& response) { + network::URLLoaderCompletionStatus status(error); + status.decoded_body_length = response.size(); + test_url_loader_factory_.AddResponse(GURL(kSafeSearchApiUrl), + network::ResourceResponseHead(), + response, status); + } + + // This method should only be used for Classification kAllowed and kRestricted + void SetUpValidResponse(ClientClassification classification) { + bool is_porn = classification == ClientClassification::kRestricted; + SetUpResponse(net::OK, BuildResponse(is_porn)); + } + + void SendValidResponse(const GURL& url, ClientClassification classification) { + SetUpValidResponse(classification); + CheckURL(url); + WaitForResponse(); + } + + void SendFailedResponse(const GURL& url) { + SetUpFailedResponse(); + CheckURL(url); + WaitForResponse(); + } + + size_t next_url_; + base::test::ScopedTaskEnvironment task_environment_; + network::TestURLLoaderFactory test_url_loader_factory_; + scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_; + std::unique_ptr<SafeSearchURLCheckerClient> checker_; +}; + +TEST_F(SafeSearchURLCheckerClientTest, Simple) { + { + GURL url(GetNewURL()); + EXPECT_CALL(*this, OnCheckDone(url, ClientClassification::kAllowed)); + SendValidResponse(url, ClientClassification::kAllowed); + } + { + GURL url(GetNewURL()); + EXPECT_CALL(*this, OnCheckDone(url, ClientClassification::kRestricted)); + SendValidResponse(url, ClientClassification::kRestricted); + } + { + GURL url(GetNewURL()); + EXPECT_CALL(*this, OnCheckDone(url, ClientClassification::kUnknown)); + SendFailedResponse(url); + } +} + +} // namespace safe_search_api
diff --git a/components/safe_search_api/stub_url_checker.cc b/components/safe_search_api/stub_url_checker.cc index 0871c75..eeaa36b 100644 --- a/components/safe_search_api/stub_url_checker.cc +++ b/components/safe_search_api/stub_url_checker.cc
@@ -4,8 +4,11 @@ #include "components/safe_search_api/stub_url_checker.h" +#include <utility> + #include "base/json/json_writer.h" #include "base/values.h" +#include "components/safe_search_api/safe_search/safe_search_url_checker_client.h" #include "components/safe_search_api/url_checker.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "services/network/public/cpp/shared_url_loader_factory.h" @@ -43,9 +46,10 @@ StubURLChecker::~StubURLChecker() = default; std::unique_ptr<URLChecker> StubURLChecker::BuildURLChecker(size_t cache_size) { - return std::make_unique<URLChecker>(test_shared_loader_factory_, - TRAFFIC_ANNOTATION_FOR_TESTS, - std::string(), cache_size); + return std::make_unique<URLChecker>( + std::make_unique<SafeSearchURLCheckerClient>( + test_shared_loader_factory_, TRAFFIC_ANNOTATION_FOR_TESTS), + cache_size); } void StubURLChecker::SetUpValidResponse(bool is_porn) {
diff --git a/components/safe_search_api/url_checker.cc b/components/safe_search_api/url_checker.cc index bacd56d72..fbc4db52 100644 --- a/components/safe_search_api/url_checker.cc +++ b/components/safe_search_api/url_checker.cc
@@ -6,6 +6,7 @@ #include <string> #include <utility> +#include <vector> #include "base/bind.h" #include "base/callback.h" @@ -19,64 +20,14 @@ #include "base/time/time.h" #include "base/values.h" #include "components/google/core/common/google_util.h" -#include "google_apis/google_api_keys.h" -#include "net/base/escape.h" -#include "net/base/load_flags.h" -#include "net/url_request/url_request_status.h" -#include "services/network/public/cpp/resource_request.h" -#include "services/network/public/cpp/shared_url_loader_factory.h" -#include "services/network/public/cpp/simple_url_loader.h" -#include "url/url_constants.h" namespace safe_search_api { namespace { -const char kSafeSearchApiUrl[] = - "https://safesearch.googleapis.com/v1:classify"; -const char kDataContentType[] = "application/x-www-form-urlencoded"; -const char kDataFormat[] = "key=%s&urls=%s®ion_code=%s"; - const size_t kDefaultCacheSize = 1000; const size_t kDefaultCacheTimeoutSeconds = 3600; -// Builds the POST data for SafeSearch API requests. -std::string BuildRequestData(const std::string& api_key, - const GURL& url, - const std::string& region_code) { - std::string query = net::EscapeQueryParamValue(url.spec(), true); - return base::StringPrintf(kDataFormat, api_key.c_str(), query.c_str(), - region_code.c_str()); -} - -// Parses a SafeSearch API |response| and stores the result in |is_porn|. -// On errors, returns false and doesn't set |is_porn|. -bool ParseResponse(const std::string& response, bool* is_porn) { - std::unique_ptr<base::Value> value = - base::JSONReader::ReadDeprecated(response); - const base::DictionaryValue* dict = nullptr; - if (!value || !value->GetAsDictionary(&dict)) { - DLOG(WARNING) << "ParseResponse failed to parse global dictionary"; - return false; - } - const base::ListValue* classifications_list = nullptr; - if (!dict->GetList("classifications", &classifications_list)) { - DLOG(WARNING) << "ParseResponse failed to parse classifications list"; - return false; - } - if (classifications_list->GetSize() != 1) { - DLOG(WARNING) << "ParseResponse expected exactly one result"; - return false; - } - const base::DictionaryValue* classification_dict = nullptr; - if (!classifications_list->GetDictionary(0, &classification_dict)) { - DLOG(WARNING) << "ParseResponse failed to parse classification dict"; - return false; - } - classification_dict->GetBoolean("pornography", is_porn); - return true; -} - } // namespace // Consider all URLs within a google domain to be safe. @@ -84,24 +35,14 @@ base::FEATURE_DISABLED_BY_DEFAULT}; struct URLChecker::Check { - Check(const GURL& url, - std::unique_ptr<network::SimpleURLLoader> simple_url_loader, - CheckCallback callback); + Check(const GURL& url, CheckCallback callback); ~Check(); GURL url; - std::unique_ptr<network::SimpleURLLoader> simple_url_loader; std::vector<CheckCallback> callbacks; - base::TimeTicks start_time; }; -URLChecker::Check::Check( - const GURL& url, - std::unique_ptr<network::SimpleURLLoader> simple_url_loader, - CheckCallback callback) - : url(url), - simple_url_loader(std::move(simple_url_loader)), - start_time(base::TimeTicks::Now()) { +URLChecker::Check::Check(const GURL& url, CheckCallback callback) : url(url) { callbacks.push_back(std::move(callback)); } @@ -117,36 +58,12 @@ uncertain(uncertain), timestamp(base::TimeTicks::Now()) {} -URLChecker::URLChecker( - scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, - const net::NetworkTrafficAnnotationTag& traffic_annotation, - const std::string& country) - : URLChecker(std::move(url_loader_factory), - traffic_annotation, - country, - kDefaultCacheSize) {} +URLChecker::URLChecker(std::unique_ptr<URLCheckerClient> async_checker) + : URLChecker(std::move(async_checker), kDefaultCacheSize) {} -URLChecker::URLChecker( - scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, - const net::NetworkTrafficAnnotationTag& traffic_annotation, - const std::string& country, - size_t cache_size) - : URLChecker(std::move(url_loader_factory), - traffic_annotation, - country, - cache_size, - google_apis::GetAPIKey()) {} - -URLChecker::URLChecker( - scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, - const net::NetworkTrafficAnnotationTag& traffic_annotation, - const std::string& country, - size_t cache_size, - const std::string& api_key) - : url_loader_factory_(std::move(url_loader_factory)), - traffic_annotation_(traffic_annotation), - country_(country), - api_key_(api_key), +URLChecker::URLChecker(std::unique_ptr<URLCheckerClient> async_checker, + size_t cache_size) + : async_checker_(std::move(async_checker)), cache_(cache_size), cache_timeout_( base::TimeDelta::FromSeconds(kDefaultCacheTimeoutSeconds)) {} @@ -195,54 +112,30 @@ } } - DVLOG(1) << "Checking URL " << url; - auto resource_request = std::make_unique<network::ResourceRequest>(); - resource_request->url = GURL(kSafeSearchApiUrl); - resource_request->method = "POST"; - resource_request->load_flags = - net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES; - std::unique_ptr<network::SimpleURLLoader> simple_url_loader = - network::SimpleURLLoader::Create(std::move(resource_request), - traffic_annotation_); - simple_url_loader->AttachStringForUpload( - BuildRequestData(api_key_, url, country_), kDataContentType); auto it = checks_in_progress_.insert( checks_in_progress_.begin(), - std::make_unique<Check>(url, std::move(simple_url_loader), - std::move(callback))); - network::SimpleURLLoader* loader = it->get()->simple_url_loader.get(); - loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie( - url_loader_factory_.get(), - base::BindOnce(&URLChecker::OnSimpleLoaderComplete, - base::Unretained(this), std::move(it))); + std::make_unique<Check>(url, std::move(callback))); + async_checker_->CheckURL(url, + base::BindOnce(&URLChecker::OnAsyncCheckComplete, + base::Unretained(this), it)); + return false; } -void URLChecker::OnSimpleLoaderComplete( - CheckList::iterator it, - std::unique_ptr<std::string> response_body) { - Check* check = it->get(); +void URLChecker::OnAsyncCheckComplete(CheckList::iterator it, + const GURL& url, + ClientClassification api_classification) { + bool uncertain = api_classification == ClientClassification::kUnknown; - GURL url = check->url; - std::vector<CheckCallback> callbacks = std::move(check->callbacks); - base::TimeTicks start_time = check->start_time; - checks_in_progress_.erase(it); - - if (!response_body) { - DLOG(WARNING) << "URL request failed! Letting through..."; - for (size_t i = 0; i < callbacks.size(); i++) - std::move(callbacks[i]).Run(url, Classification::SAFE, true); - return; + // Fallback to a |SAFE| classification when the result is not explicitly + // marked as restricted. + Classification classification = Classification::SAFE; + if (api_classification == ClientClassification::kRestricted) { + classification = Classification::UNSAFE; } - bool is_porn = false; - bool uncertain = !ParseResponse(*response_body, &is_porn); - Classification classification = - is_porn ? Classification::UNSAFE : Classification::SAFE; - - // TODO(msramek): Consider moving this to SupervisedUserResourceThrottle. - UMA_HISTOGRAM_TIMES("ManagedUsers.SafeSitesDelay", - base::TimeTicks::Now() - start_time); + std::vector<CheckCallback> callbacks = std::move(it->get()->callbacks); + checks_in_progress_.erase(it); cache_.Put(url, CheckResult(classification, uncertain));
diff --git a/components/safe_search_api/url_checker.h b/components/safe_search_api/url_checker.h index cbde568..d47999d 100644 --- a/components/safe_search_api/url_checker.h +++ b/components/safe_search_api/url_checker.h
@@ -5,23 +5,15 @@ #ifndef COMPONENTS_SAFE_SEARCH_API_URL_CHECKER_H_ #define COMPONENTS_SAFE_SEARCH_API_URL_CHECKER_H_ -#include <stddef.h> - +#include <list> #include <memory> -#include <vector> #include "base/callback_forward.h" #include "base/containers/mru_cache.h" -#include "base/macros.h" -#include "base/memory/scoped_refptr.h" #include "base/time/time.h" -#include "net/traffic_annotation/network_traffic_annotation.h" +#include "components/safe_search_api/url_checker_client.h" #include "url/gurl.h" -namespace network { -class SharedURLLoaderFactory; -} // namespace network - namespace base { struct Feature; } @@ -34,29 +26,22 @@ // Visible for testing. extern const base::Feature kAllowAllGoogleUrls; -// This class uses the SafeSearch API to check the SafeSearch classification -// of the content on a given URL and returns the result asynchronously -// via a callback. +// This class uses one implementation of URLCheckerClient to check the +// classification of the content on a given URL and returns the result +// asynchronously via a callback. It is also responsible for the synchronous +// logic such as caching, the injected URLCheckerClient is who makes the +// async request. class URLChecker { public: - // Returns whether |url| should be blocked. Called from CheckURL. + // Used to report whether |url| should be blocked. Called from CheckURL. using CheckCallback = base::OnceCallback< void(const GURL&, Classification classification, bool /* uncertain */)>; - // |country| should be a two-letter country code (ISO 3166-1 alpha-2), e.g., - // "us". - URLChecker(scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, - const net::NetworkTrafficAnnotationTag& traffic_annotation, - const std::string& country); - URLChecker(scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, - const net::NetworkTrafficAnnotationTag& traffic_annotation, - const std::string& country, + explicit URLChecker(std::unique_ptr<URLCheckerClient> async_checker); + + URLChecker(std::unique_ptr<URLCheckerClient> async_checker, size_t cache_size); - URLChecker(scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, - const net::NetworkTrafficAnnotationTag& traffic_annotation, - const std::string& country, - size_t cache_size, - const std::string& api_key); + ~URLChecker(); // Returns whether |callback| was run synchronously. @@ -76,14 +61,11 @@ }; using CheckList = std::list<std::unique_ptr<Check>>; - void OnSimpleLoaderComplete(CheckList::iterator it, - std::unique_ptr<std::string> response_body); + void OnAsyncCheckComplete(CheckList::iterator it, + const GURL& url, + ClientClassification classification); - scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_; - const net::NetworkTrafficAnnotationTag traffic_annotation_; - const std::string country_; - const std::string api_key_; - + std::unique_ptr<URLCheckerClient> async_checker_; CheckList checks_in_progress_; base::MRUCache<GURL, CheckResult> cache_;
diff --git a/components/safe_search_api/url_checker_client.h b/components/safe_search_api/url_checker_client.h new file mode 100644 index 0000000..98f75f1 --- /dev/null +++ b/components/safe_search_api/url_checker_client.h
@@ -0,0 +1,38 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_SAFE_SEARCH_API_URL_CHECKER_CLIENT_H_ +#define COMPONENTS_SAFE_SEARCH_API_URL_CHECKER_CLIENT_H_ + +#include "base/callback_forward.h" +#include "url/gurl.h" + +namespace safe_search_api { + +// The client representation of a URL classification by the service for the user +// in the request context. +enum class ClientClassification { kAllowed, kRestricted, kUnknown }; + +// Interface to make the server request and check an URL. +class URLCheckerClient { + public: + // Used to report whether |url| should be blocked. Called from CheckURL. + using ClientCheckCallback = + base::OnceCallback<void(const GURL&, + ClientClassification classification)>; + + virtual ~URLCheckerClient() = default; + + // Checks whether an |url| is restricted for the user in the request context. + // + // On success, the |callback| function is called with |url| as the first + // parameter, the result as second. + // + // Refer to the implementation class for documentation about error handling. + virtual void CheckURL(const GURL& url, ClientCheckCallback callback) = 0; +}; + +} // namespace safe_search_api + +#endif // COMPONENTS_SAFE_SEARCH_API_URL_CHECKER_CLIENT_H_
diff --git a/components/safe_search_api/url_checker_unittest.cc b/components/safe_search_api/url_checker_unittest.cc index 3388729..362fde4 100644 --- a/components/safe_search_api/url_checker_unittest.cc +++ b/components/safe_search_api/url_checker_unittest.cc
@@ -13,13 +13,10 @@ #include "base/bind.h" #include "base/callback.h" #include "base/macros.h" -#include "base/run_loop.h" #include "base/stl_util.h" #include "base/test/scoped_feature_list.h" #include "base/test/scoped_task_environment.h" -#include "base/threading/thread_task_runner_handle.h" -#include "components/safe_search_api/stub_url_checker.h" -#include "net/base/net_errors.h" +#include "components/safe_search_api/fake_url_checker_client.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -40,12 +37,29 @@ "http://www.randomsite9.com", }; +ClientClassification ToAPIClassification(Classification classification, + bool uncertain) { + if (uncertain) { + return ClientClassification::kUnknown; + } + switch (classification) { + case Classification::SAFE: + return ClientClassification::kAllowed; + case Classification::UNSAFE: + return ClientClassification::kRestricted; + } +} + } // namespace class SafeSearchURLCheckerTest : public testing::Test { public: - SafeSearchURLCheckerTest() - : next_url_(0), checker_(stub_url_checker_.BuildURLChecker(kCacheSize)) {} + SafeSearchURLCheckerTest() : next_url_(0) { + std::unique_ptr<FakeURLCheckerClient> fake_client = + std::make_unique<FakeURLCheckerClient>(); + fake_client_ = fake_client.get(); + checker_ = std::make_unique<URLChecker>(std::move(fake_client), kCacheSize); + } MOCK_METHOD3(OnCheckDone, void(const GURL& url, @@ -66,25 +80,16 @@ return cached; } - void WaitForResponse() { base::RunLoop().RunUntilIdle(); } - - bool SendValidResponse(const GURL& url, bool is_porn) { - stub_url_checker_.SetUpValidResponse(is_porn); + bool SendResponse(const GURL& url, + Classification classification, + bool uncertain) { bool result = CheckURL(url); - WaitForResponse(); - return result; - } - - bool SendFailedResponse(const GURL& url) { - stub_url_checker_.SetUpFailedResponse(); - bool result = CheckURL(url); - WaitForResponse(); + fake_client_->RunCallback(ToAPIClassification(classification, uncertain)); return result; } size_t next_url_; - base::test::ScopedTaskEnvironment task_environment_; - StubURLChecker stub_url_checker_; + FakeURLCheckerClient* fake_client_; std::unique_ptr<URLChecker> checker_; }; @@ -92,17 +97,17 @@ { GURL url(GetNewURL()); EXPECT_CALL(*this, OnCheckDone(url, Classification::SAFE, false)); - ASSERT_FALSE(SendValidResponse(url, false)); + ASSERT_FALSE(SendResponse(url, Classification::SAFE, false)); } { GURL url(GetNewURL()); EXPECT_CALL(*this, OnCheckDone(url, Classification::UNSAFE, false)); - ASSERT_FALSE(SendValidResponse(url, true)); + ASSERT_FALSE(SendResponse(url, Classification::UNSAFE, false)); } { GURL url(GetNewURL()); EXPECT_CALL(*this, OnCheckDone(url, Classification::SAFE, true)); - ASSERT_FALSE(SendFailedResponse(url)); + ASSERT_FALSE(SendResponse(url, Classification::SAFE, true)); } } @@ -115,12 +120,11 @@ // Populate the cache. EXPECT_CALL(*this, OnCheckDone(url1, Classification::SAFE, false)); - ASSERT_FALSE(SendValidResponse(url1, false)); + ASSERT_FALSE(SendResponse(url1, Classification::SAFE, false)); EXPECT_CALL(*this, OnCheckDone(url2, Classification::SAFE, false)); - ASSERT_FALSE(SendValidResponse(url2, false)); + ASSERT_FALSE(SendResponse(url2, Classification::SAFE, false)); - // Now we should get results synchronously, without a network request. - stub_url_checker_.ClearResponses(); + // Now we should get results synchronously, without a request to the api. EXPECT_CALL(*this, OnCheckDone(url2, Classification::SAFE, false)); ASSERT_TRUE(CheckURL(url2)); EXPECT_CALL(*this, OnCheckDone(url1, Classification::SAFE, false)); @@ -128,21 +132,20 @@ // Now |url2| is the LRU and should be evicted on the next check. EXPECT_CALL(*this, OnCheckDone(url3, Classification::SAFE, false)); - ASSERT_FALSE(SendValidResponse(url3, false)); + ASSERT_FALSE(SendResponse(url3, Classification::SAFE, false)); EXPECT_CALL(*this, OnCheckDone(url2, Classification::SAFE, false)); - ASSERT_FALSE(SendValidResponse(url2, false)); + ASSERT_FALSE(SendResponse(url2, Classification::SAFE, false)); } TEST_F(SafeSearchURLCheckerTest, CoalesceRequestsToSameURL) { GURL url(GetNewURL()); // Start two checks for the same URL. - stub_url_checker_.SetUpValidResponse(false); ASSERT_FALSE(CheckURL(url)); ASSERT_FALSE(CheckURL(url)); // A single response should answer both of those checks EXPECT_CALL(*this, OnCheckDone(url, Classification::SAFE, false)).Times(2); - WaitForResponse(); + fake_client_->RunCallback(ToAPIClassification(Classification::SAFE, false)); } TEST_F(SafeSearchURLCheckerTest, CacheTimeout) { @@ -151,12 +154,12 @@ checker_->SetCacheTimeoutForTesting(base::TimeDelta::FromSeconds(0)); EXPECT_CALL(*this, OnCheckDone(url, Classification::SAFE, false)); - ASSERT_FALSE(SendValidResponse(url, false)); + ASSERT_FALSE(SendResponse(url, Classification::SAFE, false)); // Since the cache timeout is zero, the cache entry should be invalidated // immediately. EXPECT_CALL(*this, OnCheckDone(url, Classification::UNSAFE, false)); - ASSERT_FALSE(SendValidResponse(url, true)); + ASSERT_FALSE(SendResponse(url, Classification::UNSAFE, false)); } TEST_F(SafeSearchURLCheckerTest, AllowAllGoogleURLs) { @@ -183,19 +186,13 @@ feature_list.InitAndDisableFeature(kAllowAllGoogleUrls); { GURL url("https://sites.google.com/porn"); - EXPECT_CALL(*this, OnCheckDone(url, Classification::UNSAFE, _)); - stub_url_checker_.SetUpValidResponse(true); - bool cache_hit = CheckURL(url); - ASSERT_FALSE(cache_hit); - WaitForResponse(); + EXPECT_CALL(*this, OnCheckDone(url, Classification::UNSAFE, false)); + ASSERT_FALSE(SendResponse(url, Classification::UNSAFE, false)); } { GURL url("https://youtube.com/porn"); - EXPECT_CALL(*this, OnCheckDone(url, Classification::UNSAFE, _)); - stub_url_checker_.SetUpValidResponse(true); - bool cache_hit = CheckURL(url); - ASSERT_FALSE(cache_hit); - WaitForResponse(); + EXPECT_CALL(*this, OnCheckDone(url, Classification::UNSAFE, false)); + ASSERT_FALSE(SendResponse(url, Classification::UNSAFE, false)); } }
diff --git a/components/signin/core/browser/BUILD.gn b/components/signin/core/browser/BUILD.gn index 3b9b244..c6ea7639 100644 --- a/components/signin/core/browser/BUILD.gn +++ b/components/signin/core/browser/BUILD.gn
@@ -218,10 +218,10 @@ static_library("internals_test_support") { testonly = true sources = [ - "fake_account_fetcher_service.cc", - "fake_account_fetcher_service.h", "fake_profile_oauth2_token_service.cc", "fake_profile_oauth2_token_service.h", + "test_image_decoder.cc", + "test_image_decoder.h", # TODO(https://crbug.com/907782): Move list_accounts_test_utils to # //services/identity/public/cpp once FakeGCMS no longer depends on it.
diff --git a/components/signin/core/browser/account_tracker_service_unittest.cc b/components/signin/core/browser/account_tracker_service_unittest.cc index 2aac21e..885ab88 100644 --- a/components/signin/core/browser/account_tracker_service_unittest.cc +++ b/components/signin/core/browser/account_tracker_service_unittest.cc
@@ -21,8 +21,8 @@ #include "components/signin/core/browser/account_info.h" #include "components/signin/core/browser/account_tracker_service.h" #include "components/signin/core/browser/avatar_icon_util.h" -#include "components/signin/core/browser/fake_account_fetcher_service.h" #include "components/signin/core/browser/signin_pref_names.h" +#include "components/signin/core/browser/test_image_decoder.h" #include "components/signin/core/browser/test_signin_client.h" #include "google_apis/gaia/fake_oauth2_token_service.h" #include "google_apis/gaia/gaia_oauth_client.h"
diff --git a/components/signin/core/browser/signin_manager_unittest.cc b/components/signin/core/browser/signin_manager_unittest.cc index be9ac36..1751a43d 100644 --- a/components/signin/core/browser/signin_manager_unittest.cc +++ b/components/signin/core/browser/signin_manager_unittest.cc
@@ -21,10 +21,10 @@ #include "components/signin/core/browser/account_consistency_method.h" #include "components/signin/core/browser/account_tracker_service.h" #include "components/signin/core/browser/device_id_helper.h" -#include "components/signin/core/browser/fake_account_fetcher_service.h" #include "components/signin/core/browser/gaia_cookie_manager_service.h" #include "components/signin/core/browser/profile_oauth2_token_service.h" #include "components/signin/core/browser/signin_pref_names.h" +#include "components/signin/core/browser/test_image_decoder.h" #include "components/signin/core/browser/test_signin_client.h" #include "components/sync_preferences/testing_pref_service_syncable.h" #include "google_apis/gaia/fake_oauth2_token_service_delegate.h" @@ -99,7 +99,7 @@ TestSigninClient* signin_client() { return &test_signin_client_; } AccountTrackerService* account_tracker() { return &account_tracker_; } - FakeAccountFetcherService* account_fetcher() { return &account_fetcher_; } + AccountFetcherService* account_fetcher() { return &account_fetcher_; } PrefService* prefs() { return &user_prefs_; } // Seed the account tracker with information from logged in user. Normally @@ -149,7 +149,7 @@ ProfileOAuth2TokenService token_service_; AccountTrackerService account_tracker_; GaiaCookieManagerService cookie_manager_service_; - FakeAccountFetcherService account_fetcher_; + AccountFetcherService account_fetcher_; std::unique_ptr<SigninManager> manager_; TestSigninManagerObserver test_observer_; std::vector<std::string> oauth_tokens_fetched_;
diff --git a/components/signin/core/browser/fake_account_fetcher_service.cc b/components/signin/core/browser/test_image_decoder.cc similarity index 85% rename from components/signin/core/browser/fake_account_fetcher_service.cc rename to components/signin/core/browser/test_image_decoder.cc index 2cc03d0..225b413 100644 --- a/components/signin/core/browser/fake_account_fetcher_service.cc +++ b/components/signin/core/browser/test_image_decoder.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/signin/core/browser/fake_account_fetcher_service.h" +#include "components/signin/core/browser/test_image_decoder.h" #include "base/values.h" #include "build/build_config.h" @@ -10,8 +10,6 @@ #include "components/signin/core/browser/profile_oauth2_token_service.h" #include "ui/gfx/image/image_unittest_util.h" -FakeAccountFetcherService::FakeAccountFetcherService() {} - TestImageDecoder::TestImageDecoder() = default; TestImageDecoder::~TestImageDecoder() = default;
diff --git a/components/signin/core/browser/fake_account_fetcher_service.h b/components/signin/core/browser/test_image_decoder.h similarity index 61% rename from components/signin/core/browser/fake_account_fetcher_service.h rename to components/signin/core/browser/test_image_decoder.h index f3528e6..311099d 100644 --- a/components/signin/core/browser/fake_account_fetcher_service.h +++ b/components/signin/core/browser/test_image_decoder.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 COMPONENTS_SIGNIN_CORE_BROWSER_FAKE_ACCOUNT_FETCHER_SERVICE_H_ -#define COMPONENTS_SIGNIN_CORE_BROWSER_FAKE_ACCOUNT_FETCHER_SERVICE_H_ +#ifndef COMPONENTS_SIGNIN_CORE_BROWSER_TEST_IMAGE_DECODER_H_ +#define COMPONENTS_SIGNIN_CORE_BROWSER_TEST_IMAGE_DECODER_H_ #include <memory> @@ -12,19 +12,6 @@ #include "components/image_fetcher/core/image_decoder.h" #include "components/signin/core/browser/account_fetcher_service.h" -class KeyedService; - -// AccountTrackerService is a KeyedService that retrieves and caches GAIA -// information about Google Accounts. This fake class can be used in tests -// to prevent AccountTrackerService from sending network requests. -class FakeAccountFetcherService : public AccountFetcherService { - public: - FakeAccountFetcherService(); - - private: - 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 { @@ -45,4 +32,4 @@ DISALLOW_COPY_AND_ASSIGN(TestImageDecoder); }; -#endif // COMPONENTS_SIGNIN_CORE_BROWSER_FAKE_ACCOUNT_FETCHER_SERVICE_H_ +#endif // COMPONENTS_SIGNIN_CORE_BROWSER_TEST_IMAGE_DECODER_H_
diff --git a/components/sync/base/model_type.h b/components/sync/base/model_type.h index fb78756..ca6acf4c 100644 --- a/components/sync/base/model_type.h +++ b/components/sync/base/model_type.h
@@ -60,29 +60,31 @@ FIRST_USER_MODEL_TYPE = BOOKMARKS, // Declared 2nd, for debugger prettiness. FIRST_REAL_MODEL_TYPE = FIRST_USER_MODEL_TYPE, - // A preference object. + // A preference object, a.k.a. "Settings". PREFERENCES, // A password object. PASSWORDS, - // An AutofillProfile Object + // An autofill_profile object, i.e. an address. AUTOFILL_PROFILE, - // An autofill object. + // An autofill object, i.e. an autocomplete entry keyed to an HTML form field. AUTOFILL, - // Credit cards and addresses synced from the user's account. These are - // read-only on the client. + // Credit cards and addresses from the user's account. These are read-only on + // the client. AUTOFILL_WALLET_DATA, // Usage counts and last use dates for Wallet cards and addresses. This data // is both readable and writable. AUTOFILL_WALLET_METADATA, - // A themes object. + // A theme object. THEMES, - // A typed_url object. + // A typed_url object, i.e. a URL the user has typed into the Omnibox. TYPED_URLS, // An extension object. EXTENSIONS, // An object representing a custom search engine. SEARCH_ENGINES, - // An object representing a browser session. + // An object representing a browser session, e.g. an open tab. This is used + // for both "History" (together with TYPED_URLS) and "Tabs" (depending on + // PROXY_TABS). SESSIONS, // An app object. APPS, @@ -90,19 +92,18 @@ APP_SETTINGS, // An extension setting from the extension settings API. EXTENSION_SETTINGS, - // App notifications. Deprecated. + // Deprecated. DEPRECATED_APP_NOTIFICATIONS, - // History delete directives. + // History delete directives, used to propagate history deletions (e.g. based + // on a time range). HISTORY_DELETE_DIRECTIVES, - // Synced push notifications. Deprecated. DEPRECATED_SYNCED_NOTIFICATIONS, - // Synced Notification app info. Deprecated. DEPRECATED_SYNCED_NOTIFICATION_APP_INFO, - // Custom spelling dictionary. + // Custom spelling dictionary entries. DICTIONARY, - // Favicon images. + // Favicon images, including both the image URL and the actual pixels. FAVICON_IMAGES, - // Favicon tracking information. + // Favicon tracking information, i.e. metadata such as last visit date. FAVICON_TRACKING, // Client-specific metadata, synced before other user types. DEVICE_INFO, @@ -111,24 +112,20 @@ PRIORITY_PREFERENCES, // Supervised user settings. Cannot be encrypted. SUPERVISED_USER_SETTINGS, - // Deprecated supervised user types that are not used anymore. DEPRECATED_SUPERVISED_USERS, DEPRECATED_SUPERVISED_USER_SHARED_SETTINGS, - // Distilled articles. DEPRECATED_ARTICLES, - // App List items + // App List items, used by the ChromeOS app launcher. APP_LIST, - // WiFi credentials. Each item contains the information for connecting to one - // WiFi network. This includes, e.g., network name and password. DEPRECATED_WIFI_CREDENTIALS, // Supervised user whitelists. Each item contains a CRX ID (like an extension // ID) and a name. SUPERVISED_USER_WHITELISTS, - // ARC Package items. + // ARC package items, i.e. Android apps on ChromeOS. ARC_PACKAGE, - // Printer device information. + // Printer device information. ChromeOS only. PRINTERS, - // Reading list items. + // Reading list items. iOS only. READING_LIST, // Commit only user events. USER_EVENTS,
diff --git a/components/translate/core/browser/translate_accept_languages.cc b/components/translate/core/browser/translate_accept_languages.cc index 8a3c6a11..c6cd9fc 100644 --- a/components/translate/core/browser/translate_accept_languages.cc +++ b/components/translate/core/browser/translate_accept_languages.cc
@@ -10,9 +10,9 @@ #include "base/metrics/histogram_macros.h" #include "base/strings/string_split.h" #include "base/strings/string_util.h" +#include "components/language/core/common/language_util.h" #include "components/prefs/pref_service.h" #include "components/translate/core/browser/translate_download_manager.h" -#include "components/translate/core/common/translate_util.h" #include "ui/base/l10n/l10n_util.h" namespace translate { @@ -41,7 +41,7 @@ SCOPED_UMA_HISTOGRAM_TIMER("Translate.AcceptLanguages.CanBeAcceptDuration"); std::string accept_language = language; - translate::ToChromeLanguageSynonym(&accept_language); + language::ToChromeLanguageSynonym(&accept_language); const std::string locale = TranslateDownloadManager::GetInstance()->application_locale(); @@ -51,7 +51,7 @@ bool TranslateAcceptLanguages::IsAcceptLanguage(const std::string& language) { std::string accept_language = language; - translate::ToChromeLanguageSynonym(&accept_language); + language::ToChromeLanguageSynonym(&accept_language); return accept_languages_.find(accept_language) != accept_languages_.end(); }
diff --git a/components/translate/core/browser/translate_manager.cc b/components/translate/core/browser/translate_manager.cc index 159ff579..2e9836d 100644 --- a/components/translate/core/browser/translate_manager.cc +++ b/components/translate/core/browser/translate_manager.cc
@@ -18,6 +18,7 @@ #include "base/time/time.h" #include "components/language/core/browser/language_model.h" #include "components/language/core/common/language_experiments.h" +#include "components/language/core/common/language_util.h" #include "components/language/core/common/locale_util.h" #include "components/prefs/pref_service.h" #include "components/translate/core/browser/language_state.h" @@ -36,7 +37,6 @@ #include "components/translate/core/common/language_detection_details.h" #include "components/translate/core/common/translate_constants.h" #include "components/translate/core/common/translate_switches.h" -#include "components/translate/core/common/translate_util.h" #include "components/variations/variations_associated_data.h" #include "google_apis/google_api_keys.h" #include "net/base/network_change_notifier.h" @@ -467,7 +467,7 @@ for (const auto& lang : language_model->GetLanguages()) { std::string lang_code = TranslateDownloadManager::GetLanguageCode(lang.lang_code); - translate::ToTranslateLanguageSynonym(&lang_code); + language::ToTranslateLanguageSynonym(&lang_code); if (TranslateDownloadManager::IsSupportedLanguage(lang_code)) language_codes.push_back(lang_code); } @@ -483,7 +483,7 @@ std::string language = TranslateDownloadManager::GetLanguageCode( TranslateDownloadManager::GetInstance()->application_locale()); // Map 'he', 'nb', 'fil' back to 'iw', 'no', 'tl' - translate::ToTranslateLanguageSynonym(&language); + language::ToTranslateLanguageSynonym(&language); if (TranslateDownloadManager::IsSupportedLanguage(language)) return language;
diff --git a/components/translate/core/browser/translate_prefs.cc b/components/translate/core/browser/translate_prefs.cc index 7d580378..8b9c8ff 100644 --- a/components/translate/core/browser/translate_prefs.cc +++ b/components/translate/core/browser/translate_prefs.cc
@@ -23,6 +23,7 @@ #include "build/build_config.h" #include "components/language/core/browser/language_prefs.h" #include "components/language/core/common/language_experiments.h" +#include "components/language/core/common/language_util.h" #include "components/language/core/common/locale_util.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_service.h" @@ -31,7 +32,6 @@ #include "components/translate/core/browser/translate_accept_languages.h" #include "components/translate/core/browser/translate_download_manager.h" #include "components/translate/core/browser/translate_pref_names.h" -#include "components/translate/core/common/translate_util.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util_collator.h" @@ -217,7 +217,7 @@ DCHECK(!input_language.empty()); std::string chrome_language = input_language; - translate::ToChromeLanguageSynonym(&chrome_language); + language::ToChromeLanguageSynonym(&chrome_language); std::vector<std::string> languages; GetLanguageList(&languages); @@ -242,7 +242,7 @@ DCHECK(!input_language.empty()); std::string chrome_language = input_language; - translate::ToChromeLanguageSynonym(&chrome_language); + language::ToChromeLanguageSynonym(&chrome_language); std::vector<std::string> languages; GetLanguageList(&languages); @@ -439,7 +439,7 @@ // Extract the base language: if the base language can be translated, then // even the regional one should be marked as such. - translate::ToTranslateLanguageSynonym(&supports_translate_code); + language::ToTranslateLanguageSynonym(&supports_translate_code); language.supports_translate = translate_language_set.count(supports_translate_code) > 0; @@ -452,7 +452,7 @@ DCHECK(!input_language.empty()); std::string translate_language = input_language; - translate::ToTranslateLanguageSynonym(&translate_language); + language::ToTranslateLanguageSynonym(&translate_language); BlacklistValue(kPrefTranslateBlockedLanguages, translate_language); } @@ -461,7 +461,7 @@ DCHECK(!input_language.empty()); std::string translate_language = input_language; - translate::ToTranslateLanguageSynonym(&translate_language); + language::ToTranslateLanguageSynonym(&translate_language); if (GetListSize(kPrefTranslateBlockedLanguages) > 1) { RemoveValueFromBlacklist(kPrefTranslateBlockedLanguages, translate_language); @@ -985,7 +985,7 @@ #endif base::ListValue language_values; for (std::string& language : languages) { - translate::ToTranslateLanguageSynonym(&language); + language::ToTranslateLanguageSynonym(&language); if (std::find(language_values.GetList().begin(), language_values.GetList().end(), base::Value(language)) == language_values.GetList().end())
diff --git a/components/translate/core/common/translate_util.cc b/components/translate/core/common/translate_util.cc index 87e7a20..e2c4a61 100644 --- a/components/translate/core/common/translate_util.cc +++ b/components/translate/core/common/translate_util.cc
@@ -18,112 +18,8 @@ namespace translate { -struct LanguageCodePair { - // Code used in supporting list of Translate. - const char* const translate_language; - - // Code used in Chrome internal. - const char* const chrome_language; -}; - -// Some languages are treated as same languages in Translate even though they -// are different to be exact. -// -// If this table is updated, please sync this with the synonym table in -// chrome/browser/resources/settings/languages_page/languages.js. -const LanguageCodePair kLanguageCodeSimilitudes[] = { - {"no", "nb"}, - {"tl", "fil"}, -}; - -// Some languages have changed codes over the years and sometimes the older -// codes are used, so we must see them as synonyms. -// -// If this table is updated, please sync this with the synonym table in -// chrome/browser/resources/settings/languages_page/languages.js. -const LanguageCodePair kLanguageCodeSynonyms[] = { - {"iw", "he"}, - {"jw", "jv"}, -}; - -// Some Chinese language codes are compatible with zh-TW or zh-CN in terms of -// Translate. -// -// If this table is updated, please sync this with the synonym table in -// chrome/browser/resources/settings/languages_page/languages.js. -const LanguageCodePair kLanguageCodeChineseCompatiblePairs[] = { - {"zh-TW", "zh-HK"}, - {"zh-TW", "zh-MO"}, - {"zh-CN", "zh-SG"}, -}; - const char kSecurityOrigin[] = "https://translate.googleapis.com/"; -void ToTranslateLanguageSynonym(std::string* language) { - for (size_t i = 0; i < base::size(kLanguageCodeSimilitudes); ++i) { - if (*language == kLanguageCodeSimilitudes[i].chrome_language) { - *language = kLanguageCodeSimilitudes[i].translate_language; - return; - } - } - - std::string main_part, tail_part; - language::SplitIntoMainAndTail(*language, &main_part, &tail_part); - if (main_part.empty()) - return; - - // Chinese is a special case: we do not return the main_part only. - // There is not a single base language, but two: traditional and simplified. - // The kLanguageCodeChineseCompatiblePairs list contains the relation between - // various Chinese locales. We need to return the code from that mapping - // instead of the main_part. - // Note that "zh" does not have any mapping and as such we leave it as is. See - // https://crbug/798512 for more info. - for (size_t i = 0; i < base::size(kLanguageCodeChineseCompatiblePairs); ++i) { - if (*language == kLanguageCodeChineseCompatiblePairs[i].chrome_language) { - *language = kLanguageCodeChineseCompatiblePairs[i].translate_language; - return; - } - } - if (main_part == "zh") { - return; - } - - // Apply linear search here because number of items in the list is just four. - for (size_t i = 0; i < base::size(kLanguageCodeSynonyms); ++i) { - if (main_part == kLanguageCodeSynonyms[i].chrome_language) { - main_part = std::string(kLanguageCodeSynonyms[i].translate_language); - break; - } - } - - *language = main_part; -} - -void ToChromeLanguageSynonym(std::string* language) { - for (size_t i = 0; i < base::size(kLanguageCodeSimilitudes); ++i) { - if (*language == kLanguageCodeSimilitudes[i].translate_language) { - *language = kLanguageCodeSimilitudes[i].chrome_language; - return; - } - } - - std::string main_part, tail_part; - language::SplitIntoMainAndTail(*language, &main_part, &tail_part); - if (main_part.empty()) - return; - - // Apply liner search here because number of items in the list is just four. - for (size_t i = 0; i < base::size(kLanguageCodeSynonyms); ++i) { - if (main_part == kLanguageCodeSynonyms[i].translate_language) { - main_part = std::string(kLanguageCodeSynonyms[i].chrome_language); - break; - } - } - - *language = main_part + tail_part; -} - GURL GetTranslateSecurityOrigin() { std::string security_origin(kSecurityOrigin); base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
diff --git a/components/translate/core/common/translate_util.h b/components/translate/core/common/translate_util.h index a7036c5..7c4385ce 100644 --- a/components/translate/core/common/translate_util.h +++ b/components/translate/core/common/translate_util.h
@@ -15,15 +15,6 @@ // Isolated world sets following security-origin by default. extern const char kSecurityOrigin[]; -// Converts language code synonym to use at Translate server. -// -// The same logic exists at language_options.js, and please keep consistency -// with the JavaScript file. -void ToTranslateLanguageSynonym(std::string* language); - -// Converts language code synonym to use at Chrome internal. -void ToChromeLanguageSynonym(std::string* language); - // Gets Security origin with which Translate runs. This is used both for // language checks and to obtain the list of available languages. GURL GetTranslateSecurityOrigin();
diff --git a/components/translate/core/common/translate_util_unittest.cc b/components/translate/core/common/translate_util_unittest.cc index d29f92e1..6d3a393 100644 --- a/components/translate/core/common/translate_util_unittest.cc +++ b/components/translate/core/common/translate_util_unittest.cc
@@ -11,62 +11,6 @@ typedef testing::Test TranslateUtilTest; -// Tests that synonym language code is converted to one used in supporting list. -TEST_F(TranslateUtilTest, ToTranslateLanguageSynonym) { - std::string language; - - language = std::string("nb"); - translate::ToTranslateLanguageSynonym(&language); - EXPECT_EQ("no", language); - - // Test all known Chinese cases. - language = std::string("zh-HK"); - translate::ToTranslateLanguageSynonym(&language); - EXPECT_EQ("zh-TW", language); - language = std::string("zh-MO"); - translate::ToTranslateLanguageSynonym(&language); - EXPECT_EQ("zh-TW", language); - language = std::string("zh-SG"); - translate::ToTranslateLanguageSynonym(&language); - EXPECT_EQ("zh-CN", language); - language = std::string("zh"); - translate::ToTranslateLanguageSynonym(&language); - EXPECT_EQ("zh", language); - - // A sub code is not preserved (except for Chinese). - language = std::string("he-IL"); - translate::ToTranslateLanguageSynonym(&language); - EXPECT_EQ("iw", language); - - language = std::string("zh-JP"); - translate::ToTranslateLanguageSynonym(&language); - EXPECT_EQ("zh-JP", language); - - // Preserve the argument if it doesn't have its synonym. - language = std::string("en"); - translate::ToTranslateLanguageSynonym(&language); - EXPECT_EQ("en", language); -} - -// Tests that synonym language code is converted to one used in Chrome internal. -TEST_F(TranslateUtilTest, ToChromeLanguageSynonym) { - std::string language; - - language = std::string("no"); - translate::ToChromeLanguageSynonym(&language); - EXPECT_EQ("nb", language); - - // Preserve a sub code - language = std::string("iw-IL"); - translate::ToChromeLanguageSynonym(&language); - EXPECT_EQ("he-IL", language); - - // Preserve the argument if it doesn't have its synonym. - language = std::string("en"); - translate::ToChromeLanguageSynonym(&language); - EXPECT_EQ("en", language); -} - TEST_F(TranslateUtilTest, SecurityOrigin) { GURL origin = translate::GetTranslateSecurityOrigin(); EXPECT_EQ(std::string(translate::kSecurityOrigin), origin.spec());
diff --git a/components/translate/core/language_detection/BUILD.gn b/components/translate/core/language_detection/BUILD.gn index 5653eb1..713c50dd 100644 --- a/components/translate/core/language_detection/BUILD.gn +++ b/components/translate/core/language_detection/BUILD.gn
@@ -25,6 +25,7 @@ deps = [ ":chinese_script_classifier", "//base", + "//components/language/core/common", "//components/translate/core/common", "//third_party/cld_3/src/src:cld_3", "//third_party/icu",
diff --git a/components/translate/core/language_detection/language_detection_util.cc b/components/translate/core/language_detection/language_detection_util.cc index 5bb8b516..ba6ca77 100644 --- a/components/translate/core/language_detection/language_detection_util.cc +++ b/components/translate/core/language_detection/language_detection_util.cc
@@ -15,9 +15,9 @@ #include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" +#include "components/language/core/common/language_util.h" #include "components/translate/core/common/translate_constants.h" #include "components/translate/core/common/translate_metrics.h" -#include "components/translate/core/common/translate_util.h" #include "components/translate/core/language_detection/chinese_script_classifier.h" #include "third_party/cld_3/src/src/nnet_language_identifier.h" @@ -63,7 +63,7 @@ return; } - translate::ToTranslateLanguageSynonym(code); + language::ToTranslateLanguageSynonym(code); } // Returns the ISO 639 language code of the specified |text|, or 'unknown' if it @@ -175,7 +175,7 @@ *cld_language_p = cld_language; if (is_cld_reliable_p != nullptr) *is_cld_reliable_p = is_cld_reliable; - translate::ToTranslateLanguageSynonym(&cld_language); + language::ToTranslateLanguageSynonym(&cld_language); // Adopt |modified_html_lang| if it is valid. Otherwise, adopt // |modified_code|.
diff --git a/components/viz/common/BUILD.gn b/components/viz/common/BUILD.gn index 1b3be20..43efd68 100644 --- a/components/viz/common/BUILD.gn +++ b/components/viz/common/BUILD.gn
@@ -82,6 +82,8 @@ sources = [ "constants.cc", "constants.h", + "display/overlay_strategy.cc", + "display/overlay_strategy.h", "display/renderer_settings.cc", "display/renderer_settings.h", "features.cc", @@ -254,6 +256,7 @@ never_build_jumbo = true testonly = true sources = [ + "display/overlay_strategy_unittest.cc", "frame_sinks/begin_frame_args_unittest.cc", "frame_sinks/begin_frame_source_unittest.cc", "frame_sinks/copy_output_util_unittest.cc",
diff --git a/components/viz/common/display/overlay_strategy.cc b/components/viz/common/display/overlay_strategy.cc new file mode 100644 index 0000000..7dfdd63 --- /dev/null +++ b/components/viz/common/display/overlay_strategy.cc
@@ -0,0 +1,34 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/viz/common/display/overlay_strategy.h" + +#include "base/logging.h" +#include "base/strings/string_split.h" + +namespace viz { + +std::vector<OverlayStrategy> ParseOverlayStategies( + const std::string& strategies_string) { + std::vector<OverlayStrategy> strategies; + + auto strategy_names = base::SplitStringPiece( + strategies_string, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); + for (auto& strategy_name : strategy_names) { + if (strategy_name == "single-fullscreen") { + strategies.push_back(OverlayStrategy::kFullscreen); + } else if (strategy_name == "single-on-top") { + strategies.push_back(OverlayStrategy::kSingleOnTop); + } else if (strategy_name == "underlay") { + strategies.push_back(OverlayStrategy::kUnderlay); + } else if (strategy_name == "cast") { + strategies.push_back(OverlayStrategy::kUnderlayCast); + } else { + LOG(ERROR) << "Unrecognized overlay strategy " << strategy_name; + } + } + return strategies; +} + +} // namespace viz
diff --git a/components/viz/common/display/overlay_strategy.h b/components/viz/common/display/overlay_strategy.h new file mode 100644 index 0000000..d88cc31 --- /dev/null +++ b/components/viz/common/display/overlay_strategy.h
@@ -0,0 +1,34 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_VIZ_COMMON_DISPLAY_OVERLAY_STRATEGY_H_ +#define COMPONENTS_VIZ_COMMON_DISPLAY_OVERLAY_STRATEGY_H_ + +#include <string> +#include <vector> + +#include "components/viz/common/viz_common_export.h" + +namespace viz { + +// Enum used for UMA histogram. These enum values must not be changed or +// reused. +enum class OverlayStrategy { + kUnknown = 0, + kNoStrategyUsed = 1, + kFullscreen = 2, + kSingleOnTop = 3, + kUnderlay = 4, + kUnderlayCast = 5, + kMaxValue = kUnderlayCast, +}; + +// Parses a comma separated list of overlay strategy types and returns a list +// of the corresponding OverlayStrategy enum values. +VIZ_COMMON_EXPORT std::vector<OverlayStrategy> ParseOverlayStategies( + const std::string& strategies_string); + +} // namespace viz + +#endif // COMPONENTS_VIZ_COMMON_DISPLAY_OVERLAY_STRATEGY_H_
diff --git a/components/viz/common/display/overlay_strategy_unittest.cc b/components/viz/common/display/overlay_strategy_unittest.cc new file mode 100644 index 0000000..7df3227 --- /dev/null +++ b/components/viz/common/display/overlay_strategy_unittest.cc
@@ -0,0 +1,43 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/viz/common/display/overlay_strategy.h" + +#include <string> +#include <vector> + +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using testing::IsEmpty; +using testing::UnorderedElementsAre; + +namespace viz { + +TEST(ParseOverlayStrategiesTest, ParseEmptyList) { + std::vector<OverlayStrategy> strategies = ParseOverlayStategies(""); + EXPECT_THAT(strategies, IsEmpty()); +} + +TEST(ParseOverlayStrategiesTest, ParseFullList) { + std::vector<OverlayStrategy> strategies = + ParseOverlayStategies("single-fullscreen,single-on-top,underlay,cast"); + + EXPECT_THAT(strategies, UnorderedElementsAre(OverlayStrategy::kFullscreen, + OverlayStrategy::kSingleOnTop, + OverlayStrategy::kUnderlay, + OverlayStrategy::kUnderlayCast)); +} + +TEST(ParseOverlayStrategiesTest, BadValue) { + std::vector<OverlayStrategy> strategies = + ParseOverlayStategies("single-fullscreen,bad-value,underlay"); + + // The string "bad-value" doesn't correspond to an overlay strategy so it + // should be skipped. + EXPECT_THAT(strategies, UnorderedElementsAre(OverlayStrategy::kFullscreen, + OverlayStrategy::kUnderlay)); +} + +} // namespace viz
diff --git a/components/viz/service/display/overlay_processor.cc b/components/viz/service/display/overlay_processor.cc index 26b9560..965663d 100644 --- a/components/viz/service/display/overlay_processor.cc +++ b/components/viz/service/display/overlay_processor.cc
@@ -46,8 +46,8 @@ } // namespace -OverlayProcessor::StrategyType OverlayProcessor::Strategy::GetUMAEnum() const { - return StrategyType::kUnknown; +OverlayStrategy OverlayProcessor::Strategy::GetUMAEnum() const { + return OverlayStrategy::kUnknown; } OverlayProcessor::OverlayProcessor(OutputSurface* surface) @@ -194,7 +194,7 @@ UMA_HISTOGRAM_ENUMERATION("Viz.DisplayCompositor.OverlayStrategy", successful_strategy ? successful_strategy->GetUMAEnum() - : StrategyType::kNoStrategyUsed); + : OverlayStrategy::kNoStrategyUsed); TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("viz.debug.overlay_planes"), "Scheduled overlay planes", candidates->size());
diff --git a/components/viz/service/display/overlay_processor.h b/components/viz/service/display/overlay_processor.h index c0a70f7..1a696cfe 100644 --- a/components/viz/service/display/overlay_processor.h +++ b/components/viz/service/display/overlay_processor.h
@@ -9,6 +9,7 @@ #include "base/containers/flat_map.h" #include "base/macros.h" +#include "components/viz/common/display/overlay_strategy.h" #include "components/viz/common/quads/render_pass.h" #include "components/viz/service/display/ca_layer_overlay.h" #include "components/viz/service/display/dc_layer_overlay.h" @@ -24,18 +25,6 @@ class VIZ_SERVICE_EXPORT OverlayProcessor { public: - // Enum used for UMA histogram. These enum values must not be changed or - // reused. - enum class StrategyType { - kUnknown = 0, - kNoStrategyUsed = 1, - kFullscreen = 2, - kSingleOnTop = 3, - kUnderlay = 4, - kUnderlayCast = 5, - kMaxValue = kUnderlayCast, - }; - using FilterOperationsMap = base::flat_map<RenderPassId, cc::FilterOperations*>; @@ -55,7 +44,7 @@ OverlayCandidateList* candidates, std::vector<gfx::Rect>* content_bounds) = 0; - virtual StrategyType GetUMAEnum() const; + virtual OverlayStrategy GetUMAEnum() const; }; using StrategyList = std::vector<std::unique_ptr<Strategy>>;
diff --git a/components/viz/service/display/overlay_strategy_fullscreen.cc b/components/viz/service/display/overlay_strategy_fullscreen.cc index c723210..7515ad52 100644 --- a/components/viz/service/display/overlay_strategy_fullscreen.cc +++ b/components/viz/service/display/overlay_strategy_fullscreen.cc
@@ -69,8 +69,8 @@ return true; } -OverlayProcessor::StrategyType OverlayStrategyFullscreen::GetUMAEnum() const { - return OverlayProcessor::StrategyType::kFullscreen; +OverlayStrategy OverlayStrategyFullscreen::GetUMAEnum() const { + return OverlayStrategy::kFullscreen; } } // namespace viz
diff --git a/components/viz/service/display/overlay_strategy_fullscreen.h b/components/viz/service/display/overlay_strategy_fullscreen.h index 3a98a80..a3a76a9 100644 --- a/components/viz/service/display/overlay_strategy_fullscreen.h +++ b/components/viz/service/display/overlay_strategy_fullscreen.h
@@ -30,7 +30,7 @@ OverlayCandidateList* candidate_list, std::vector<gfx::Rect>* content_bounds) override; - OverlayProcessor::StrategyType GetUMAEnum() const override; + OverlayStrategy GetUMAEnum() const override; private: OverlayCandidateValidator* capability_checker_; // Weak.
diff --git a/components/viz/service/display/overlay_strategy_single_on_top.cc b/components/viz/service/display/overlay_strategy_single_on_top.cc index 758e629..03e71188 100644 --- a/components/viz/service/display/overlay_strategy_single_on_top.cc +++ b/components/viz/service/display/overlay_strategy_single_on_top.cc
@@ -75,8 +75,8 @@ return false; } -OverlayProcessor::StrategyType OverlayStrategySingleOnTop::GetUMAEnum() const { - return OverlayProcessor::StrategyType::kSingleOnTop; +OverlayStrategy OverlayStrategySingleOnTop::GetUMAEnum() const { + return OverlayStrategy::kSingleOnTop; } } // namespace viz
diff --git a/components/viz/service/display/overlay_strategy_single_on_top.h b/components/viz/service/display/overlay_strategy_single_on_top.h index 91ce21e..dd9f28e 100644 --- a/components/viz/service/display/overlay_strategy_single_on_top.h +++ b/components/viz/service/display/overlay_strategy_single_on_top.h
@@ -28,7 +28,7 @@ OverlayCandidateList* candidate_list, std::vector<gfx::Rect>* content_bounds) override; - OverlayProcessor::StrategyType GetUMAEnum() const override; + OverlayStrategy GetUMAEnum() const override; private: bool TryOverlay(QuadList* quad_list,
diff --git a/components/viz/service/display/overlay_strategy_underlay.cc b/components/viz/service/display/overlay_strategy_underlay.cc index 40be0300..86be7fd7 100644 --- a/components/viz/service/display/overlay_strategy_underlay.cc +++ b/components/viz/service/display/overlay_strategy_underlay.cc
@@ -100,8 +100,8 @@ return false; } -OverlayProcessor::StrategyType OverlayStrategyUnderlay::GetUMAEnum() const { - return OverlayProcessor::StrategyType::kUnderlay; +OverlayStrategy OverlayStrategyUnderlay::GetUMAEnum() const { + return OverlayStrategy::kUnderlay; } } // namespace viz
diff --git a/components/viz/service/display/overlay_strategy_underlay.h b/components/viz/service/display/overlay_strategy_underlay.h index 5ccce6c..338b8f75 100644 --- a/components/viz/service/display/overlay_strategy_underlay.h +++ b/components/viz/service/display/overlay_strategy_underlay.h
@@ -44,7 +44,7 @@ OverlayCandidateList* candidate_list, std::vector<gfx::Rect>* content_bounds) override; - OverlayProcessor::StrategyType GetUMAEnum() const override; + OverlayStrategy GetUMAEnum() const override; private: OverlayCandidateValidator* capability_checker_; // Weak.
diff --git a/components/viz/service/display/overlay_strategy_underlay_cast.cc b/components/viz/service/display/overlay_strategy_underlay_cast.cc index 3b87d13..6378ec1 100644 --- a/components/viz/service/display/overlay_strategy_underlay_cast.cc +++ b/components/viz/service/display/overlay_strategy_underlay_cast.cc
@@ -122,8 +122,8 @@ return found_underlay; } -OverlayProcessor::StrategyType OverlayStrategyUnderlayCast::GetUMAEnum() const { - return OverlayProcessor::StrategyType::kUnderlayCast; +OverlayStrategy OverlayStrategyUnderlayCast::GetUMAEnum() const { + return OverlayStrategy::kUnderlayCast; } // static
diff --git a/components/viz/service/display/overlay_strategy_underlay_cast.h b/components/viz/service/display/overlay_strategy_underlay_cast.h index 1040e08..284df81 100644 --- a/components/viz/service/display/overlay_strategy_underlay_cast.h +++ b/components/viz/service/display/overlay_strategy_underlay_cast.h
@@ -38,7 +38,7 @@ base::RepeatingCallback<void(const gfx::RectF&, gfx::OverlayTransform)>; static void SetOverlayCompositedCallback(const OverlayCompositedCallback& cb); - OverlayProcessor::StrategyType GetUMAEnum() const override; + OverlayStrategy GetUMAEnum() const override; private: // Keep track if an overlay is being used on the previous frame.
diff --git a/components/viz/service/display_embedder/compositor_overlay_candidate_validator_ozone.cc b/components/viz/service/display_embedder/compositor_overlay_candidate_validator_ozone.cc index 845d211f..6a06990 100644 --- a/components/viz/service/display_embedder/compositor_overlay_candidate_validator_ozone.cc +++ b/components/viz/service/display_embedder/compositor_overlay_candidate_validator_ozone.cc
@@ -8,8 +8,6 @@ #include <utility> -#include "base/bind.h" -#include "base/strings/string_split.h" #include "components/viz/service/display/overlay_strategy_fullscreen.h" #include "components/viz/service/display/overlay_strategy_single_on_top.h" #include "components/viz/service/display/overlay_strategy_underlay.h" @@ -17,60 +15,44 @@ #include "ui/ozone/public/overlay_candidates_ozone.h" namespace viz { -namespace { -// Templated function used to create an OverlayProcessor::Strategy -// of type |S|. -template <typename S> -std::unique_ptr<OverlayProcessor::Strategy> MakeOverlayStrategy( - CompositorOverlayCandidateValidatorOzone* capability_checker) { - return std::make_unique<S>(capability_checker); -} - -} // namespace // |overlay_candidates| is an object used to answer questions about possible // overlays configurations. -// |strategies_string| is a comma-separated string containing all the overlay -// strategies that should be returned by GetStrategies. -// If |strategies_string| is empty "single-on-top,underlay" will be used as -// default. +// |strategies_string| is a list of overlay strategies that should be returned +// by GetStrategies. CompositorOverlayCandidateValidatorOzone:: CompositorOverlayCandidateValidatorOzone( std::unique_ptr<ui::OverlayCandidatesOzone> overlay_candidates, - std::string strategies_string) + std::vector<OverlayStrategy> strategies) : overlay_candidates_(std::move(overlay_candidates)), - software_mirror_active_(false) { - if (!strategies_string.length()) - strategies_string = "single-on-top,underlay"; - - for (const auto& strategy_name : - base::SplitStringPiece(strategies_string, ",", base::TRIM_WHITESPACE, - base::SPLIT_WANT_NONEMPTY)) { - if (strategy_name == "single-fullscreen") { - strategies_instantiators_.push_back( - base::BindRepeating(MakeOverlayStrategy<OverlayStrategyFullscreen>)); - } else if (strategy_name == "single-on-top") { - strategies_instantiators_.push_back( - base::BindRepeating(MakeOverlayStrategy<OverlayStrategySingleOnTop>)); - } else if (strategy_name == "underlay") { - strategies_instantiators_.push_back( - base::BindRepeating(MakeOverlayStrategy<OverlayStrategyUnderlay>)); - } else if (strategy_name == "cast") { - strategies_instantiators_.push_back(base::BindRepeating( - MakeOverlayStrategy<OverlayStrategyUnderlayCast>)); - } else { - LOG(WARNING) << "Unrecognized overlay strategy " << strategy_name; - } - } -} + strategies_(std::move(strategies)) {} CompositorOverlayCandidateValidatorOzone:: ~CompositorOverlayCandidateValidatorOzone() {} void CompositorOverlayCandidateValidatorOzone::GetStrategies( OverlayProcessor::StrategyList* strategies) { - for (auto& instantiator : strategies_instantiators_) - strategies->push_back(instantiator.Run(this)); + for (OverlayStrategy strategy : strategies_) { + switch (strategy) { + case OverlayStrategy::kFullscreen: + strategies->push_back( + std::make_unique<OverlayStrategyFullscreen>(this)); + break; + case OverlayStrategy::kSingleOnTop: + strategies->push_back( + std::make_unique<OverlayStrategySingleOnTop>(this)); + break; + case OverlayStrategy::kUnderlay: + strategies->push_back(std::make_unique<OverlayStrategyUnderlay>(this)); + break; + case OverlayStrategy::kUnderlayCast: + strategies->push_back( + std::make_unique<OverlayStrategyUnderlayCast>(this)); + break; + default: + NOTREACHED(); + } + } } bool CompositorOverlayCandidateValidatorOzone::AllowCALayerOverlays() {
diff --git a/components/viz/service/display_embedder/compositor_overlay_candidate_validator_ozone.h b/components/viz/service/display_embedder/compositor_overlay_candidate_validator_ozone.h index cca7a65..b1e657e 100644 --- a/components/viz/service/display_embedder/compositor_overlay_candidate_validator_ozone.h +++ b/components/viz/service/display_embedder/compositor_overlay_candidate_validator_ozone.h
@@ -6,9 +6,10 @@ #define COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_COMPOSITOR_OVERLAY_CANDIDATE_VALIDATOR_OZONE_H_ #include <memory> +#include <vector> -#include "base/callback.h" #include "base/macros.h" +#include "components/viz/common/display/overlay_strategy.h" #include "components/viz/service/display_embedder/compositor_overlay_candidate_validator.h" #include "components/viz/service/viz_service_export.h" #include "ui/gfx/native_widget_types.h" @@ -24,7 +25,7 @@ public: CompositorOverlayCandidateValidatorOzone( std::unique_ptr<ui::OverlayCandidatesOzone> overlay_candidates, - std::string strategies_string); + std::vector<OverlayStrategy> strategies); ~CompositorOverlayCandidateValidatorOzone() override; // OverlayCandidateValidator implementation. @@ -38,14 +39,8 @@ private: std::unique_ptr<ui::OverlayCandidatesOzone> overlay_candidates_; - // Callback declaration to allocate a new OverlayProcessor::Strategy. - using StrategyInstantiator = - base::RepeatingCallback<std::unique_ptr<OverlayProcessor::Strategy>( - CompositorOverlayCandidateValidatorOzone*)>; - // List callbacks used to instantiate OverlayProcessor::Strategy - // as defined by |strategies_string| paramter in the constructor. - std::vector<StrategyInstantiator> strategies_instantiators_; - bool software_mirror_active_; + const std::vector<OverlayStrategy> strategies_; + bool software_mirror_active_ = false; DISALLOW_COPY_AND_ASSIGN(CompositorOverlayCandidateValidatorOzone); };
diff --git a/content/browser/compositor/gpu_process_transport_factory.cc b/content/browser/compositor/gpu_process_transport_factory.cc index bc1934e..4768ac1 100644 --- a/content/browser/compositor/gpu_process_transport_factory.cc +++ b/content/browser/compositor/gpu_process_transport_factory.cc
@@ -274,7 +274,8 @@ std::unique_ptr<ui::OverlayCandidatesOzone> overlay_candidates = ozone_platform->GetOverlayManager()->CreateOverlayCandidates(widget); validator.reset(new viz::CompositorOverlayCandidateValidatorOzone( - std::move(overlay_candidates), enable_overlay_flag)); + std::move(overlay_candidates), + viz::ParseOverlayStategies(enable_overlay_flag))); } #elif defined(OS_MACOSX) // Overlays are only supported through the remote layer API.
diff --git a/content/browser/compositor/reflector_impl_unittest.cc b/content/browser/compositor/reflector_impl_unittest.cc index 687a1f5b..2287823 100644 --- a/content/browser/compositor/reflector_impl_unittest.cc +++ b/content/browser/compositor/reflector_impl_unittest.cc
@@ -67,11 +67,10 @@ std::unique_ptr<viz::CompositorOverlayCandidateValidator> CreateTestValidatorOzone() { #if defined(USE_OZONE) - return std::unique_ptr<viz::CompositorOverlayCandidateValidator>( - new viz::CompositorOverlayCandidateValidatorOzone( - std::unique_ptr<ui::OverlayCandidatesOzone>( - new TestOverlayCandidatesOzone()), - "")); + std::vector<viz::OverlayStrategy> strategies = { + viz::OverlayStrategy::kSingleOnTop, viz::OverlayStrategy::kUnderlay}; + return std::make_unique<viz::CompositorOverlayCandidateValidatorOzone>( + std::make_unique<TestOverlayCandidatesOzone>(), std::move(strategies)); #else return nullptr; #endif // defined(USE_OZONE)
diff --git a/content/browser/frame_host/navigation_handle_impl.cc b/content/browser/frame_host/navigation_handle_impl.cc index d30899a..1e91218 100644 --- a/content/browser/frame_host/navigation_handle_impl.cc +++ b/content/browser/frame_host/navigation_handle_impl.cc
@@ -4,42 +4,21 @@ #include "content/browser/frame_host/navigation_handle_impl.h" -#include <iterator> - -#include "base/bind.h" #include "base/debug/dump_without_crashing.h" -#include "base/logging.h" #include "base/metrics/histogram_macros.h" -#include "base/optional.h" -#include "base/time/time.h" #include "content/browser/appcache/appcache_navigation_handle.h" #include "content/browser/appcache/appcache_service_impl.h" #include "content/browser/child_process_security_policy_impl.h" #include "content/browser/devtools/devtools_instrumentation.h" #include "content/browser/frame_host/debug_urls.h" -#include "content/browser/frame_host/frame_tree_node.h" #include "content/browser/frame_host/navigation_controller_impl.h" -#include "content/browser/frame_host/navigation_entry_impl.h" #include "content/browser/frame_host/navigator.h" -#include "content/browser/frame_host/navigator_delegate.h" #include "content/browser/loader/resource_dispatcher_host_impl.h" #include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/browser/service_worker/service_worker_context_wrapper.h" #include "content/browser/service_worker/service_worker_navigation_handle.h" -#include "content/common/child_process_host_impl.h" #include "content/common/frame_messages.h" -#include "content/public/browser/content_browser_client.h" -#include "content/public/browser/navigation_ui_data.h" -#include "content/public/browser/render_process_host.h" -#include "content/public/browser/site_instance.h" -#include "content/public/common/child_process_host.h" -#include "content/public/common/url_constants.h" #include "content/public/common/url_utils.h" -#include "net/base/net_errors.h" -#include "net/url_request/redirect_info.h" -#include "services/network/public/cpp/resource_request_body.h" -#include "url/gurl.h" -#include "url/url_constants.h" namespace content {
diff --git a/content/browser/frame_host/navigation_handle_impl.h b/content/browser/frame_host/navigation_handle_impl.h index 17b4489f..53cf57aa 100644 --- a/content/browser/frame_host/navigation_handle_impl.h +++ b/content/browser/frame_host/navigation_handle_impl.h
@@ -423,12 +423,6 @@ // The state the navigation is in. State state_; - // A list of Throttles registered for this navigation. - std::vector<std::unique_ptr<NavigationThrottle>> throttles_; - - // The index of the next throttle to check. - size_t next_index_; - // The time this naviagtion was ready to commit. base::TimeTicks ready_to_commit_time_;
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 7a9ed5b..a8185e63 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -2946,7 +2946,6 @@ service_manager::switches::kEnableSandboxLogging, #endif switches::kAgcStartupMinVolume, - switches::kAecRefinedAdaptiveFilter, switches::kAllowLoopbackInPeerConnection, switches::kAndroidFontsPath, switches::kAudioBufferSize,
diff --git a/content/browser/utility_process_host.cc b/content/browser/utility_process_host.cc index 9b800fe..3d74373 100644 --- a/content/browser/utility_process_host.cc +++ b/content/browser/utility_process_host.cc
@@ -390,7 +390,6 @@ switches::kFailAudioStreamCreation, switches::kMuteAudio, switches::kUseFileForFakeAudioCapture, - switches::kAecRefinedAdaptiveFilter, switches::kAgcStartupMinVolume, #if defined(OS_LINUX) || defined(OS_FREEBSD) || defined(OS_SOLARIS) switches::kAlsaInputDevice,
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc index 6f69859..98977d2a 100644 --- a/content/child/runtime_features.cc +++ b/content/child/runtime_features.cc
@@ -368,9 +368,6 @@ WebRuntimeFeatures::EnableModernMediaControls( base::FeatureList::IsEnabled(media::kUseModernMediaControls)); - WebRuntimeFeatures::EnableScheduledScriptStreaming( - base::FeatureList::IsEnabled(features::kScheduledScriptStreaming)); - WebRuntimeFeatures::EnableScriptStreamingOnPreload( base::FeatureList::IsEnabled(features::kScriptStreamingOnPreload));
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index 426a68e..1b364a7 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc
@@ -294,6 +294,10 @@ const base::Feature kNotificationContentImage{"NotificationContentImage", base::FEATURE_ENABLED_BY_DEFAULT}; +// Enables the notification trigger API. +const base::Feature kNotificationTriggers{"NotificationTriggers", + base::FEATURE_DISABLED_BY_DEFAULT}; + // Origin Policy. See https://crbug.com/751996 const base::Feature kOriginPolicy{"OriginPolicy", base::FEATURE_DISABLED_BY_DEFAULT}; @@ -629,12 +633,6 @@ const base::Feature kWebRtcScreenshareSwEncoding{ "WebRtcScreenshareSwEncoding", base::FEATURE_DISABLED_BY_DEFAULT}; -// Enables the WebRTC Echo Canceller version 3 (AEC3). Feature for -// http://crbug.com/688388. This value is sent to WebRTC's echo canceller to -// toggle which echo canceller should be used. -const base::Feature kWebRtcUseEchoCanceller3{"WebRtcUseEchoCanceller3", - base::FEATURE_ENABLED_BY_DEFAULT}; - // Use GpuMemoryBuffer backed VideoFrames in media streams. const base::Feature kWebRtcUseGpuMemoryBufferVideoFrames{ "WebRTC-UseGpuMemoryBufferVideoFrames", base::FEATURE_ENABLED_BY_DEFAULT}; @@ -660,10 +658,6 @@ const base::Feature kWipeCorruptV2IDBDatabases{ "WipeCorruptV2IDBDatabases", base::FEATURE_ENABLED_BY_DEFAULT}; -// Enabled scheduler use for script streaming. -const base::Feature kScheduledScriptStreaming{"ScheduledScriptStreaming", - base::FEATURE_ENABLED_BY_DEFAULT}; - // Start streaming scripts on script preload. const base::Feature kScriptStreamingOnPreload{ "ScriptStreamingOnPreload", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h index 9cf84f4..c47e085 100644 --- a/content/public/common/content_features.h +++ b/content/public/common/content_features.h
@@ -74,6 +74,7 @@ CONTENT_EXPORT extern const base::Feature kNetworkQualityEstimatorWebHoldback; CONTENT_EXPORT extern const base::Feature kNetworkServiceInProcess; CONTENT_EXPORT extern const base::Feature kNotificationContentImage; +CONTENT_EXPORT extern const base::Feature kNotificationTriggers; CONTENT_EXPORT extern const base::Feature kOriginPolicy; CONTENT_EXPORT extern const base::Feature kOriginTrials; CONTENT_EXPORT extern const base::Feature kOverscrollHistoryNavigation; @@ -137,7 +138,6 @@ CONTENT_EXPORT extern const base::Feature kWebRtcHWVP9Encoding; CONTENT_EXPORT extern const base::Feature kWebRtcMultiplexCodec; CONTENT_EXPORT extern const base::Feature kWebRtcScreenshareSwEncoding; -CONTENT_EXPORT extern const base::Feature kWebRtcUseEchoCanceller3; CONTENT_EXPORT extern const base::Feature kWebRtcUseGpuMemoryBufferVideoFrames; CONTENT_EXPORT extern const base::Feature kWebRtcHideLocalIpsWithMdns; CONTENT_EXPORT extern const base::Feature kWebUsb; @@ -145,7 +145,6 @@ CONTENT_EXPORT extern const base::Feature kWebXrGamepadSupport; CONTENT_EXPORT extern const base::Feature kWebXrHitTest; CONTENT_EXPORT extern const base::Feature kWipeCorruptV2IDBDatabases; -CONTENT_EXPORT extern const base::Feature kScheduledScriptStreaming; CONTENT_EXPORT extern const base::Feature kScriptStreamingOnPreload; #if defined(OS_ANDROID)
diff --git a/content/renderer/media/stream/media_stream_audio_processor.cc b/content/renderer/media/stream/media_stream_audio_processor.cc index a955723..e171ed9 100644 --- a/content/renderer/media/stream/media_stream_audio_processor.cc +++ b/content/renderer/media/stream/media_stream_audio_processor.cc
@@ -32,7 +32,6 @@ #include "media/base/audio_fifo.h" #include "media/base/audio_parameters.h" #include "media/base/channel_layout.h" -#include "media/webrtc/echo_information.h" #include "media/webrtc/webrtc_switches.h" #include "third_party/webrtc/api/audio/echo_canceller3_config.h" #include "third_party/webrtc/api/audio/echo_canceller3_config_json.h" @@ -106,13 +105,6 @@ return base::Optional<int>(startup_min_volume); } -// Checks if the AEC's refined adaptive filter tuning was enabled on the command -// line. -bool UseAecRefinedAdaptiveFilter() { - return base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kAecRefinedAdaptiveFilter); -} - } // namespace // Wraps AudioBus to provide access to the array of channel pointers, since this @@ -392,9 +384,6 @@ playout_data_source_->RemovePlayoutSink(this); playout_data_source_ = nullptr; } - - if (echo_information_) - echo_information_->ReportAndResetAecDivergentFilterStats(); } const media::AudioParameters& MediaStreamAudioProcessor::InputFormat() const { @@ -573,15 +562,6 @@ // Experimental options provided at creation. webrtc::Config config; - config.Set<webrtc::ExtendedFilter>( - new webrtc::ExtendedFilter(goog_experimental_aec)); - config.Set<webrtc::ExperimentalNs>(new webrtc::ExperimentalNs( - properties.goog_experimental_noise_suppression)); - config.Set<webrtc::DelayAgnostic>(new webrtc::DelayAgnostic(true)); - if (UseAecRefinedAdaptiveFilter()) { - config.Set<webrtc::RefinedAdaptiveFilter>( - new webrtc::RefinedAdaptiveFilter(true)); - } // If the experimental AGC is enabled, check for overridden config params. if (properties.goog_experimental_auto_gain_control) { @@ -607,8 +587,7 @@ ->WebRTCPlatformSpecificAudioProcessingConfiguration(); } webrtc::AudioProcessingBuilder ap_builder; - if (properties.echo_cancellation_type == - EchoCancellationType::kEchoCancellationAec3) { + if (properties.EchoCancellationIsWebRtcProvided()) { webrtc::EchoCanceller3Config aec3_config; if (audio_processing_platform_config_json) { aec3_config = webrtc::Aec3ConfigFromJsonString( @@ -631,14 +610,6 @@ if (properties.EchoCancellationIsWebRtcProvided()) { EnableEchoCancellation(audio_processing_.get()); - - // Prepare for logging echo information. Do not log any echo information - // when AEC3 is active, as the echo information then will not be properly - // updated. - if (properties.echo_cancellation_type != - EchoCancellationType::kEchoCancellationAec3) { - echo_information_ = std::make_unique<media::EchoInformation>(); - } } if (properties.goog_noise_suppression) @@ -831,9 +802,6 @@ void MediaStreamAudioProcessor::UpdateAecStats() { DCHECK(main_thread_runner_->BelongsToCurrentThread()); - if (echo_information_) - echo_information_->UpdateAecStats( - audio_processing_->GetStatistics(true /* has_remote_tracks */)); } } // namespace content
diff --git a/content/renderer/media/stream/media_stream_audio_processor.h b/content/renderer/media/stream/media_stream_audio_processor.h index b5f9256..12884d88 100644 --- a/content/renderer/media/stream/media_stream_audio_processor.h +++ b/content/renderer/media/stream/media_stream_audio_processor.h
@@ -31,7 +31,6 @@ namespace media { class AudioBus; class AudioParameters; -class EchoInformation; } // namespace media namespace webrtc { @@ -215,10 +214,6 @@ size_t apm_playout_error_code_log_count_ = 0; size_t large_delay_log_count_ = 0; - // Object for logging UMA stats for echo information when the AEC is enabled. - // Accessed on the main render thread. - std::unique_ptr<media::EchoInformation> echo_information_; - DISALLOW_COPY_AND_ASSIGN(MediaStreamAudioProcessor); };
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 63ff53f..1c4ae023 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -3633,8 +3633,11 @@ } Send(new FrameHostMsg_DidStopLoading(routing_id_)); } else { - if (callback) + if (callback) { std::move(callback).Run(blink::mojom::CommitResult::Ok); + } else { + navigation_client_impl_.reset(); + } } browser_side_navigation_pending_ = false; browser_side_navigation_pending_url_ = GURL();
diff --git a/content/shell/test_runner/test_runner.cc b/content/shell/test_runner/test_runner.cc index 421b6a3c..157fd13 100644 --- a/content/shell/test_runner/test_runner.cc +++ b/content/shell/test_runner/test_runner.cc
@@ -1446,7 +1446,7 @@ } void TestRunner::WorkQueue::ProcessWorkSoon() { - if (controller_->topLoadingFrame()) + if (controller_->top_loading_frame_) return; if (!queue_.empty()) { @@ -1488,7 +1488,7 @@ } if (!controller_->web_test_runtime_flags_.wait_until_done() && - !controller_->topLoadingFrame()) + !controller_->top_loading_frame_) controller_->delegate_->TestFinished(); } @@ -1833,25 +1833,24 @@ return test_is_running_ && frame->Top()->View() == main_view_; } -bool TestRunner::tryToSetTopLoadingFrame(blink::WebFrame* frame) { +void TestRunner::tryToSetTopLoadingFrame(blink::WebFrame* frame) { if (!IsFramePartOfMainTestWindow(frame)) - return false; + return; if (top_loading_frame_ || web_test_runtime_flags_.have_top_loading_frame()) - return false; + return; top_loading_frame_ = frame; web_test_runtime_flags_.set_have_top_loading_frame(true); OnWebTestRuntimeFlagsChanged(); - return true; } -bool TestRunner::tryToClearTopLoadingFrame(blink::WebFrame* frame) { +void TestRunner::tryToClearTopLoadingFrame(blink::WebFrame* frame) { if (!IsFramePartOfMainTestWindow(frame)) - return false; + return; if (frame != top_loading_frame_) - return false; + return; top_loading_frame_ = nullptr; DCHECK(web_test_runtime_flags_.have_top_loading_frame()); @@ -1859,11 +1858,6 @@ OnWebTestRuntimeFlagsChanged(); LocationChangeDone(); - return true; -} - -blink::WebFrame* TestRunner::topLoadingFrame() const { - return top_loading_frame_; } blink::WebFrame* TestRunner::mainFrame() const { @@ -2599,7 +2593,7 @@ } void TestRunner::NotifyDone() { - if (web_test_runtime_flags_.wait_until_done() && !topLoadingFrame() && + if (web_test_runtime_flags_.wait_until_done() && !top_loading_frame_ && work_queue_.is_empty()) delegate_->TestFinished(); web_test_runtime_flags_.set_wait_until_done(false);
diff --git a/content/shell/test_runner/test_runner.h b/content/shell/test_runner/test_runner.h index d318871..db9140e2 100644 --- a/content/shell/test_runner/test_runner.h +++ b/content/shell/test_runner/test_runner.h
@@ -136,20 +136,19 @@ bool animation_requires_raster() const { return animation_requires_raster_; } void SetAnimationRequiresRaster(bool do_raster); - // To be called when |frame| starts loading - TestRunner will check if - // there is currently no top-loading-frame being tracked and if so, then it - // will return true and start tracking |frame| as the top-loading-frame. - bool tryToSetTopLoadingFrame(blink::WebFrame* frame); + // To be called when |frame| starts loading - TestRunner will check if there + // is currently no top-loading-frame being tracked and if so, then it will + // start tracking |frame| as the top-loading-frame. + void tryToSetTopLoadingFrame(blink::WebFrame* frame); // To be called when |frame| finishes loading - TestRunner will check if - // |frame| is currently tracked as the top-loading-frame, and if yes, then it - // will return true, stop top-loading-frame tracking, and potentially finish - // the test (unless testRunner.waitUntilDone() was called and/or there are - // pending load requests in WorkQueue). - bool tryToClearTopLoadingFrame(blink::WebFrame*); + // |frame| is currently tracked as the top-loading-frame, if yes, stop + // top-loading-frame tracking, and potentially finish the test (unless + // testRunner.waitUntilDone() was called and/or there are pending load + // requests in WorkQueue). + void tryToClearTopLoadingFrame(blink::WebFrame*); blink::WebFrame* mainFrame() const; - blink::WebFrame* topLoadingFrame() const; void policyDelegateDone(); bool policyDelegateEnabled() const; bool policyDelegateIsPermissive() const;
diff --git a/docs/clang_static_analyzer.md b/docs/clang_static_analyzer.md index b63cd593..8935ffa 100644 --- a/docs/clang_static_analyzer.md +++ b/docs/clang_static_analyzer.md
@@ -29,6 +29,10 @@ * [Linux buildbot logs](https://ci.chromium.org/p/chromium/builders/luci.chromium.ci/Linux%20Clang%20Analyzer) ## Enabling static analysis + +*Warning:* `use_clang_static_analyzer` is deprecated, but the static analyzer can +still be invoked with [clang-tidy](clang_tidy.md). + To get static analysis running for your build, add the following flag to your GN args.
diff --git a/docs/clang_tidy.md b/docs/clang_tidy.md index 10f5fc3b..3d3e5cc4 100644 --- a/docs/clang_tidy.md +++ b/docs/clang_tidy.md
@@ -18,6 +18,14 @@ ## Setting Up +### Automatic Setup + +The script [clang_tidy_tool.py](../tools/clang/scripts/clang_tidy_tool.py) will +automatically fetch, build, and invoke `clang-tidy`. To do this manually, follow +the steps in the next section. + +### Manual Setup + In addition to a full Chromium checkout, you need the clang-tidy binary. We recommend checking llvm's clang source and building the clang-tidy binary directly. Instructions for getting started with clang are available from @@ -28,7 +36,10 @@ Instead of building with `"Unix Makefiles"`, generate build files for Ninja with ``` -cmake -GNinja -DCMAKE_BUILD_TYPE=Release ../llvm +cmake -GNinja \ + -DLLVM_ENABLE_PROJECTS=clang;clang-tools-extra \ + -DCMAKE_BUILD_TYPE=Release \ + ../llvm ``` Then, instead of using `make`, use ninja to build the clang-tidy binary with
diff --git a/extensions/renderer/gin_port.cc b/extensions/renderer/gin_port.cc index 51fae8dd..b978877 100644 --- a/extensions/renderer/gin_port.cc +++ b/extensions/renderer/gin_port.cc
@@ -39,6 +39,7 @@ name_(name), event_handler_(event_handler), delegate_(delegate), + accessed_sender_(false), weak_factory_(this) { context_invalidation_listener_.emplace( context, base::BindOnce(&GinPort::OnContextInvalidated, @@ -54,10 +55,10 @@ return Wrappable<GinPort>::GetObjectTemplateBuilder(isolate) .SetMethod("disconnect", &GinPort::DisconnectHandler) .SetMethod("postMessage", &GinPort::PostMessageHandler) - .SetProperty("name", &GinPort::GetName) - .SetProperty("onDisconnect", &GinPort::GetOnDisconnectEvent) - .SetProperty("onMessage", &GinPort::GetOnMessageEvent) - .SetProperty("sender", &GinPort::GetSender); + .SetLazyDataProperty("name", &GinPort::GetName) + .SetLazyDataProperty("onDisconnect", &GinPort::GetOnDisconnectEvent) + .SetLazyDataProperty("onMessage", &GinPort::GetOnMessageEvent) + .SetLazyDataProperty("sender", &GinPort::GetSender); } const char* GinPort::GetTypeName() { @@ -108,6 +109,8 @@ void GinPort::SetSender(v8::Local<v8::Context> context, v8::Local<v8::Value> sender) { DCHECK_EQ(kActive, state_); + DCHECK(!accessed_sender_) + << "|sender| can only be set before its first access."; v8::Isolate* isolate = context->GetIsolate(); v8::HandleScope handle_scope(isolate); @@ -179,6 +182,7 @@ } v8::Local<v8::Value> GinPort::GetSender(gin::Arguments* arguments) { + accessed_sender_ = true; v8::Isolate* isolate = arguments->isolate(); v8::Local<v8::Object> wrapper = GetWrapper(isolate).ToLocalChecked(); v8::Local<v8::Private> key =
diff --git a/extensions/renderer/gin_port.h b/extensions/renderer/gin_port.h index 935b0877..7b941f2 100644 --- a/extensions/renderer/gin_port.h +++ b/extensions/renderer/gin_port.h
@@ -70,7 +70,9 @@ // the port. void DispatchOnDisconnect(v8::Local<v8::Context> context); - // Sets the |sender| property on the port. + // Sets the |sender| property on the port. Note: this can only be called + // before the `sender` property is accessed on the JS object, since it is + // lazily set as a data property in first access. void SetSender(v8::Local<v8::Context> context, v8::Local<v8::Value> sender); const PortId& port_id() const { return port_id_; } @@ -142,6 +144,10 @@ // outlive this object. Delegate* const delegate_; + // Whether the `sender` property has been accessed, and thus set on the + // port JS object. + bool accessed_sender_; + // A listener for context invalidation. Note: this isn't actually optional; // it just needs to be created after |weak_factory_|, which needs to be the // final member.
diff --git a/extensions/renderer/gin_port_unittest.cc b/extensions/renderer/gin_port_unittest.cc index a6ccbdb9..bb971a22 100644 --- a/extensions/renderer/gin_port_unittest.cc +++ b/extensions/renderer/gin_port_unittest.cc
@@ -371,18 +371,24 @@ v8::Local<v8::Context> context = MainContext(); PortId port_id(base::UnguessableToken::Create(), 0, true); - gin::Handle<GinPort> port = CreatePort(context, port_id); - v8::Local<v8::Object> port_obj = port.ToV8().As<v8::Object>(); + { + gin::Handle<GinPort> port = CreatePort(context, port_id); + v8::Local<v8::Object> port_obj = port.ToV8().As<v8::Object>(); + EXPECT_EQ("undefined", + GetStringPropertyFromObject(port_obj, context, "sender")); + } - EXPECT_EQ("undefined", - GetStringPropertyFromObject(port_obj, context, "sender")); - - port->SetSender(context, - gin::DataObjectBuilder(isolate()).Set("prop", 42).Build()); - - EXPECT_EQ(R"({"prop":42})", - GetStringPropertyFromObject(port_obj, context, "sender")); + { + // SetSender() can only be called before the `sender` property is accessed, + // so we need to create a new port here. + gin::Handle<GinPort> port = CreatePort(context, port_id); + port->SetSender(context, + gin::DataObjectBuilder(isolate()).Set("prop", 42).Build()); + v8::Local<v8::Object> port_obj = port.ToV8().As<v8::Object>(); + EXPECT_EQ(R"({"prop":42})", + GetStringPropertyFromObject(port_obj, context, "sender")); + } } TEST_F(GinPortTest, TryUsingPortAfterInvalidation) { @@ -427,4 +433,22 @@ } } +TEST_F(GinPortTest, AlteringPortName) { + v8::HandleScope handle_scope(isolate()); + v8::Local<v8::Context> context = MainContext(); + + PortId port_id(base::UnguessableToken::Create(), 0, true); + gin::Handle<GinPort> port = CreatePort(context, port_id); + + v8::Local<v8::Object> port_obj = port.ToV8().As<v8::Object>(); + + v8::Local<v8::Function> change_port_name = FunctionFromString( + context, "(function(port) { port.name = 'foo'; return port.name; })"); + + v8::Local<v8::Value> args[] = {port_obj}; + v8::Local<v8::Value> result = + RunFunction(change_port_name, context, base::size(args), args); + EXPECT_EQ(R"("foo")", V8ToString(result, context)); +} + } // namespace extensions
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd index 01b7ae3..9c9e6dd 100644 --- a/ios/chrome/app/strings/ios_strings.grd +++ b/ios/chrome/app/strings/ios_strings.grd
@@ -1516,10 +1516,10 @@ Syncing to <ph name="EMAIL">$1<ex>john.doe@gmail.com</ex></ph> </message> <message name="IDS_IOS_SIGN_IN_TO_CHROME_SETTING_SYNC_OFF" desc="The subtitle for the setting item of the signed in user when sync is off [iOS only]"> - Sync is Off + Sync is off </message> <message name="IDS_IOS_SIGN_IN_TO_CHROME_SETTING_SYNC_ON" desc="The subtitle for the setting item of the signed in user when sync is on [iOS only]"> - Sync is On + Sync is on </message> <message name="IDS_IOS_SPOTLIGHT_KEYWORD_EIGHT" desc="Keyword used in Spotlight that will be linked to the Chrome App. [iOS only]"> Online
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_SIGN_IN_TO_CHROME_SETTING_SYNC_OFF.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_SIGN_IN_TO_CHROME_SETTING_SYNC_OFF.png.sha1 new file mode 100644 index 0000000..023ead7a --- /dev/null +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_SIGN_IN_TO_CHROME_SETTING_SYNC_OFF.png.sha1
@@ -0,0 +1 @@ +9bfb049e5a0c6c49e6b65de93857ff11bbf737dd \ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_SIGN_IN_TO_CHROME_SETTING_SYNC_ON.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_SIGN_IN_TO_CHROME_SETTING_SYNC_ON.png.sha1 index 2ce90ed..794bd51 100644 --- a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_SIGN_IN_TO_CHROME_SETTING_SYNC_ON.png.sha1 +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_SIGN_IN_TO_CHROME_SETTING_SYNC_ON.png.sha1
@@ -1 +1 @@ -6bb2ae6df2d558f808f67e753b0a22bf9d9e89b0 \ No newline at end of file +090f44b7e0b23ed33b5066642aeeca97540c12d6 \ No newline at end of file
diff --git a/ios/chrome/browser/signin/identity_test_environment_chrome_browser_state_adaptor.cc b/ios/chrome/browser/signin/identity_test_environment_chrome_browser_state_adaptor.cc index 92fd4dec..ab13af6 100644 --- a/ios/chrome/browser/signin/identity_test_environment_chrome_browser_state_adaptor.cc +++ b/ios/chrome/browser/signin/identity_test_environment_chrome_browser_state_adaptor.cc
@@ -7,8 +7,8 @@ #include <utility> #include "base/bind.h" -#include "components/signin/core/browser/fake_account_fetcher_service.h" #include "components/signin/core/browser/fake_profile_oauth2_token_service.h" +#include "components/signin/core/browser/test_image_decoder.h" #include "components/signin/core/browser/test_signin_client.h" #include "components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" @@ -44,19 +44,6 @@ browser_state->GetPrefs(), std::move(delegate)); } -std::unique_ptr<KeyedService> BuildFakeAccountFetcherService( - web::BrowserState* context) { - ios::ChromeBrowserState* browser_state = - ios::ChromeBrowserState::FromBrowserState(context); - auto account_fetcher_service = std::make_unique<FakeAccountFetcherService>(); - account_fetcher_service->Initialize( - SigninClientFactory::GetForBrowserState(browser_state), - ProfileOAuth2TokenServiceFactory::GetForBrowserState(browser_state), - ios::AccountTrackerServiceFactory::GetForBrowserState(browser_state), - std::make_unique<TestImageDecoder>()); - return account_fetcher_service; -} - std::unique_ptr<KeyedService> BuildTestSigninClient(web::BrowserState* state) { return std::make_unique<TestSigninClient>( ios::ChromeBrowserState::FromBrowserState(state)->GetPrefs()); @@ -66,8 +53,6 @@ bool use_ios_token_service_delegate) { return {{SigninClientFactory::GetInstance(), base::BindRepeating(&BuildTestSigninClient)}, - {ios::AccountFetcherServiceFactory::GetInstance(), - base::BindRepeating(&BuildFakeAccountFetcherService)}, {ProfileOAuth2TokenServiceFactory::GetInstance(), base::BindRepeating(use_ios_token_service_delegate ? &BuildFakeOAuth2TokenServiceWithIOSDelegate @@ -140,9 +125,7 @@ : identity_test_env_( browser_state->GetPrefs(), ios::AccountTrackerServiceFactory::GetForBrowserState(browser_state), - static_cast<FakeAccountFetcherService*>( - ios::AccountFetcherServiceFactory::GetForBrowserState( - browser_state)), + ios::AccountFetcherServiceFactory::GetForBrowserState(browser_state), static_cast<FakeProfileOAuth2TokenService*>( ProfileOAuth2TokenServiceFactory::GetForBrowserState( browser_state)),
diff --git a/ios/chrome/browser/ui/settings/resources/BUILD.gn b/ios/chrome/browser/ui/settings/resources/BUILD.gn index 7024fe92..bdad55e 100644 --- a/ios/chrome/browser/ui/settings/resources/BUILD.gn +++ b/ios/chrome/browser/ui/settings/resources/BUILD.gn
@@ -151,7 +151,6 @@ imageset("sync_and_google_services") { sources = [ "sync_and_google_services.imageset/Contents.json", - "sync_and_google_services.imageset/sync_and_google_services.png", "sync_and_google_services.imageset/sync_and_google_services@2x.png", "sync_and_google_services.imageset/sync_and_google_services@3x.png", ]
diff --git a/ios/chrome/browser/ui/settings/resources/sync_and_google_services.imageset/Contents.json b/ios/chrome/browser/ui/settings/resources/sync_and_google_services.imageset/Contents.json index 2db5ced..d2a6ef3 100644 --- a/ios/chrome/browser/ui/settings/resources/sync_and_google_services.imageset/Contents.json +++ b/ios/chrome/browser/ui/settings/resources/sync_and_google_services.imageset/Contents.json
@@ -2,11 +2,6 @@ "images": [ { "idiom": "universal", - "scale": "1x", - "filename": "sync_and_google_services.png" - }, - { - "idiom": "universal", "scale": "2x", "filename": "sync_and_google_services@2x.png" },
diff --git a/ios/chrome/browser/ui/settings/resources/sync_and_google_services.imageset/sync_and_google_services.png b/ios/chrome/browser/ui/settings/resources/sync_and_google_services.imageset/sync_and_google_services.png deleted file mode 100644 index 041cc34..0000000 --- a/ios/chrome/browser/ui/settings/resources/sync_and_google_services.imageset/sync_and_google_services.png +++ /dev/null Binary files differ
diff --git a/ios/chrome/browser/ui/settings/resources/sync_and_google_services.imageset/sync_and_google_services@2x.png b/ios/chrome/browser/ui/settings/resources/sync_and_google_services.imageset/sync_and_google_services@2x.png index 1309597..22008755 100644 --- a/ios/chrome/browser/ui/settings/resources/sync_and_google_services.imageset/sync_and_google_services@2x.png +++ b/ios/chrome/browser/ui/settings/resources/sync_and_google_services.imageset/sync_and_google_services@2x.png Binary files differ
diff --git a/ios/chrome/browser/ui/settings/resources/sync_and_google_services.imageset/sync_and_google_services@3x.png b/ios/chrome/browser/ui/settings/resources/sync_and_google_services.imageset/sync_and_google_services@3x.png index 68a2857..d1712b2 100644 --- a/ios/chrome/browser/ui/settings/resources/sync_and_google_services.imageset/sync_and_google_services@3x.png +++ b/ios/chrome/browser/ui/settings/resources/sync_and_google_services.imageset/sync_and_google_services@3x.png Binary files differ
diff --git a/ios/chrome/browser/ui/settings/resources/sync_and_google_services_sync_error.imageset/sync_and_google_services_sync_error@2x.png b/ios/chrome/browser/ui/settings/resources/sync_and_google_services_sync_error.imageset/sync_and_google_services_sync_error@2x.png index 1e5940a..68ef40d9 100644 --- a/ios/chrome/browser/ui/settings/resources/sync_and_google_services_sync_error.imageset/sync_and_google_services_sync_error@2x.png +++ b/ios/chrome/browser/ui/settings/resources/sync_and_google_services_sync_error.imageset/sync_and_google_services_sync_error@2x.png Binary files differ
diff --git a/ios/chrome/browser/ui/settings/resources/sync_and_google_services_sync_error.imageset/sync_and_google_services_sync_error@3x.png b/ios/chrome/browser/ui/settings/resources/sync_and_google_services_sync_error.imageset/sync_and_google_services_sync_error@3x.png index 83e49263..246cefde 100644 --- a/ios/chrome/browser/ui/settings/resources/sync_and_google_services_sync_error.imageset/sync_and_google_services_sync_error@3x.png +++ b/ios/chrome/browser/ui/settings/resources/sync_and_google_services_sync_error.imageset/sync_and_google_services_sync_error@3x.png Binary files differ
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm index 3723b93..bb17d0e0 100644 --- a/ios/web/web_state/ui/crw_web_controller.mm +++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -358,8 +358,8 @@ } // If |contentView_| contains a web view, this is the web view it contains. -// If not, it's nil. -@property(weak, nonatomic, readonly) WKWebView* webView; +// If not, it's nil. When setting the property, it performs basic setup. +@property(weak, nonatomic) WKWebView* webView; // The scroll view of |webView|. @property(weak, nonatomic, readonly) UIScrollView* webScrollView; // The current page state of the web view. Writing to this property @@ -432,49 +432,12 @@ // unless the request was a POST. @property(weak, nonatomic, readonly) NSDictionary* currentHTTPHeaders; -// Called when the web page has changed document and/or URL, and so the page -// navigation should be reported to the delegate, and internal state updated to -// reflect the fact that the navigation has occurred. |context| contains -// information about the navigation that triggered the document/URL change. -// TODO(stuartmorgan): The code conflates URL changes and document object -// changes; the two need to be separated and handled differently. -- (void)webPageChangedWithContext:(web::NavigationContextImpl*)context; -// Resets any state that is associated with a specific document object (e.g., -// page interaction tracking). -- (void)resetDocumentSpecificState; -// Called when a page (native or web) has actually started loading (i.e., for -// a web page the document has actually changed), or after the load request has -// been registered for a non-document-changing URL change. Updates internal -// state not specific to web pages. -- (void)didStartLoading; -// Returns YES if the URL looks like it is one CRWWebController can show. -+ (BOOL)webControllerCanShow:(const GURL&)url; -// Creates a container view if it's not yet created. -- (void)ensureContainerViewCreated; -// Creates a web view if it's not yet created. -- (void)ensureWebViewCreated; -// Creates a web view with given |config|. No-op if web view is already created. -- (void)ensureWebViewCreatedWithConfiguration:(WKWebViewConfiguration*)config; -// Returns a new autoreleased web view created with given configuration. -- (WKWebView*)webViewWithConfiguration:(WKWebViewConfiguration*)config; -// Sets the value of the webView property, and performs its basic setup. -- (void)setWebView:(WKWebView*)webView; -// Wraps the web view in a CRWWebViewContentView and adds it to the container -// view. -- (void)displayWebView; -// Called when web view process has been terminated. -- (void)webViewWebProcessDidCrash; -// Returns the WKWebViewConfigurationProvider associated with the web -// controller's BrowserState. -- (web::WKWebViewConfigurationProvider&)webViewConfigurationProvider; // Extracts "Referer" [sic] value from WKNavigationAction request header. - (NSString*)referrerFromNavigationAction:(WKNavigationAction*)action; // Returns the current URL of the web view, and sets |trustLevel| accordingly // based on the confidence in the verification. - (GURL)webURLWithTrustLevel:(web::URLVerificationTrustLevel*)trustLevel; -// Returns |YES| if |url| should be loaded in a native view. -- (BOOL)shouldLoadURLInNativeView:(const GURL&)url; // Loads POST request with body in |_wkWebView| by constructing an HTML page // that executes the request through JavaScript and replaces document with the // result. @@ -485,8 +448,6 @@ // TODO(crbug.com/740987): Remove |loadPOSTRequest:| workaround once iOS 10 is // dropped. - (WKNavigation*)loadPOSTRequest:(NSMutableURLRequest*)request; -// Loads the HTML into the page at the given URL. -- (void)loadHTML:(NSString*)html forURL:(const GURL&)url; // Extracts navigation info from WKNavigationAction and sets it as a pending. // Some pieces of navigation information are only known in @@ -510,15 +471,6 @@ // Updates the WKBackForwardListItemHolder navigation item. - (void)updateCurrentBackForwardListItemHolder; -// Presents native content using the native controller for |item| without -// notifying WebStateObservers. This method does not modify the underlying web -// view. It simply covers the web view with the native content. -// |-didLoadNativeContentForNavigationItem| must be called some time later -// to notify WebStateObservers. -- (void)presentNativeContentForNavigationItem:(web::NavigationItem*)item; -// Notifies WebStateObservers the completion of this navigation. -- (void)didLoadNativeContentForNavigationItem:(web::NavigationItemImpl*)item - rendererInitiated:(BOOL)rendererInitiated; // Loads a blank page directly into WKWebView as a placeholder for a Native View // or WebUI URL. This page has the URL about:blank?for=<encoded original URL>. // If |originalContext| is provided, reuse it for the placeholder navigation @@ -545,10 +497,6 @@ // If YES, the page should be closed if it successfully redirects to a native // application, for example if a new tab redirects to the App Store. - (BOOL)shouldClosePageOnNativeApplicationLoad; -// Discards non committed items, only if the last committed URL was not loaded -// in native view. But if it was a native view, no discard will happen to avoid -// an ugly animation where the web view is inserted and quickly removed. -- (void)discardNonCommittedItemsIfLastCommittedWasNotNativeView; // Updates URL for navigation context and navigation item. - (void)didReceiveRedirectForNavigation:(web::NavigationContextImpl*)context withURL:(const GURL&)URL; @@ -571,8 +519,6 @@ // bounds. Reloads if delta is 0. // TODO(crbug.com/661316): Move this method to NavigationManager. - (void)rendererInitiatedGoDelta:(int)delta hasUserGesture:(BOOL)hasUserGesture; -// Informs the native controller if web usage is allowed or not. -- (void)setNativeControllerWebUsageEnabled:(BOOL)webUsageEnabled; // Acts on a single message from the JS object, parsed from JSON into a // DictionaryValue. Returns NO if the format for the message was invalid. - (BOOL)respondToMessage:(base::DictionaryValue*)crwMessage @@ -753,96 +699,6 @@ // navigation is not back forward navigation. - (void)reportBackForwardNavigationTypeForFastNavigation:(BOOL)isFast; -// Handlers for JavaScript messages. |message| contains a JavaScript command and -// data relevant to the message, and |context| contains contextual information -// about web view state needed for some handlers. - -// Handles 'chrome.send' message. -- (BOOL)handleChromeSendMessage:(base::DictionaryValue*)message - context:(NSDictionary*)context; -// Handles 'document.favicons' message. -- (BOOL)handleDocumentFaviconsMessage:(base::DictionaryValue*)message - context:(NSDictionary*)context; -// Handles 'window.error' message. -- (BOOL)handleWindowErrorMessage:(base::DictionaryValue*)message - context:(NSDictionary*)context; -// Handles 'window.hashchange' message. -- (BOOL)handleWindowHashChangeMessage:(base::DictionaryValue*)message - context:(NSDictionary*)context; -// Handles 'window.history.back' message. -- (BOOL)handleWindowHistoryBackMessage:(base::DictionaryValue*)message - context:(NSDictionary*)context; -// Handles 'window.history.forward' message. -- (BOOL)handleWindowHistoryForwardMessage:(base::DictionaryValue*)message - context:(NSDictionary*)context; -// Handles 'window.history.go' message. -- (BOOL)handleWindowHistoryGoMessage:(base::DictionaryValue*)message - context:(NSDictionary*)context; -// Handles 'window.history.willChangeState' message. -- (BOOL)handleWindowHistoryWillChangeStateMessage: - (base::DictionaryValue*)message - context:(NSDictionary*)context; -// Handles 'window.history.didPushState' message. -- (BOOL)handleWindowHistoryDidPushStateMessage:(base::DictionaryValue*)message - context:(NSDictionary*)context; - -// Handles 'window.history.didReplaceState' message. -- (BOOL)handleWindowHistoryDidReplaceStateMessage: - (base::DictionaryValue*)message - context:(NSDictionary*)context; - -// Handles 'restoresession.error' message. -- (BOOL)handleRestoreSessionErrorMessage:(base::DictionaryValue*)message - context:(NSDictionary*)context; - -// Caches request POST data in the given session entry. -- (void)cachePOSTDataForRequest:(NSURLRequest*)request - inNavigationItem:(web::NavigationItemImpl*)item; - -// Returns YES if the given |action| should be allowed to continue for app -// specific URL. If this returns NO, the navigation should be cancelled. -// App specific pages have elevated privileges and WKWebView uses the same -// renderer process for all page frames. With that Chromium does not allow -// running App specific pages in the same process as a web site from the -// internet. Allows navigation to app specific URL in the following cases: -// - last committed URL is app specific -// - navigation not a new navigation (back-forward or reload) -// - navigation is typed, generated or bookmark -// - navigation is performed in iframe and main frame is app-specific page -- (BOOL)shouldAllowAppSpecificURLNavigationAction:(WKNavigationAction*)action - transition: - (ui::PageTransition)pageTransition; -// Called when a load ends in an error. -- (void)handleLoadError:(NSError*)error - forNavigation:(WKNavigation*)navigation - provisionalLoad:(BOOL)provisionalLoad; - -// Handles cancelled load in WKWebView (error with NSURLErrorCancelled code). -- (void)handleCancelledError:(NSError*)error - forNavigation:(WKNavigation*)navigation - provisionalLoad:(BOOL)provisionalLoad; - -// Used to decide whether a load that generates errors with the -// NSURLErrorCancelled code should be cancelled. -- (BOOL)shouldCancelLoadForCancelledError:(NSError*)error - provisionalLoad:(BOOL)provisionalLoad; - -// Returns YES if response should be rendered in WKWebView. -- (BOOL)shouldRenderResponse:(WKNavigationResponse*)WKResponse; - -// Creates DownloadTask for the given navigation response. Headers are passed -// as argument to avoid extra NSDictionary -> net::HttpResponseHeaders -// conversion. -- (void)createDownloadTaskForResponse:(WKNavigationResponse*)WKResponse - HTTPHeaders:(net::HttpResponseHeaders*)headers; - -// This method should be called on receiving WKNavigationDelegate callbacks. It -// will log a metric if the callback occurs after the reciever has already been -// closed. It also stops the SafeBrowsing warning detection timer, since after -// this point it's too late for a SafeBrowsing warning to be displayed for the -// navigation for which the timer was started. -- (void)didReceiveWebViewNavigationDelegateCallback; - // Sets up WebUI for URL. - (void)createWebUIForURL:(const GURL&)URL; // Clears WebUI, if one exists. @@ -984,6 +840,63 @@ #pragma mark - Private properties accessors +- (void)setWebView:(WKWebView*)webView { + DCHECK_NE(_webView, webView); + + // Unwind the old web view. + // TODO(crbug.com/543374): Remove CRWWKScriptMessageRouter once + // crbug.com/543374 is fixed. + CRWWKScriptMessageRouter* messageRouter = + [self webViewConfigurationProvider].GetScriptMessageRouter(); + if (_webView) { + [messageRouter removeAllScriptMessageHandlersForWebView:_webView]; + } + [_webView setNavigationDelegate:nil]; + [_webView setUIDelegate:nil]; + for (NSString* keyPath in self.WKWebViewObservers) { + [_webView removeObserver:self forKeyPath:keyPath]; + } + + _webView = webView; + + // Set up the new web view. + if (webView) { + __weak CRWWebController* weakSelf = self; + [messageRouter + setScriptMessageHandler:^(WKScriptMessage* message) { + [weakSelf didReceiveScriptMessage:message]; + } + name:kScriptMessageName + webView:webView]; + + [messageRouter + setScriptMessageHandler:^(WKScriptMessage* message) { + [weakSelf frameBecameAvailableWithMessage:message]; + } + name:kFrameBecameAvailableMessageName + webView:webView]; + [messageRouter + setScriptMessageHandler:^(WKScriptMessage* message) { + [weakSelf frameBecameUnavailableWithMessage:message]; + } + name:kFrameBecameUnavailableMessageName + webView:webView]; + + _windowIDJSManager = [[CRWJSWindowIDManager alloc] initWithWebView:webView]; + } else { + _windowIDJSManager = nil; + } + [_webView setNavigationDelegate:self]; + [_webView setUIDelegate:self]; + for (NSString* keyPath in self.WKWebViewObservers) { + [_webView addObserver:self forKeyPath:keyPath options:0 context:nullptr]; + } + _webView.allowsBackForwardNavigationGestures = + _allowsBackForwardNavigationGestures; + _injectedScriptManagers = [[NSMutableSet alloc] init]; + [self setDocumentURL:_defaultURL context:nullptr]; +} + - (UIScrollView*)webScrollView { return self.webView.scrollView; } @@ -1521,6 +1434,55 @@ [self loadHTML:HTML forURL:URL]; } +// Loads the HTML into the page at the given URL. Extracted from +// loadHTML:forAppSpecificURL: for testing purpose. +- (void)loadHTML:(NSString*)HTML forURL:(const GURL&)URL { + DCHECK(HTML.length); + // Remove the transient content view. + self.webStateImpl->ClearTransientContent(); + + _loadPhase = web::LOAD_REQUESTED; + + // Web View should not be created for App Specific URLs. + if (!web::GetWebClient()->IsAppSpecificURL(URL)) { + [self ensureWebViewCreated]; + DCHECK(self.webView) << "self.webView null while trying to load HTML"; + } + WKNavigation* navigation = + [self.webView loadHTMLString:HTML baseURL:net::NSURLWithGURL(URL)]; + [_navigationStates setState:web::WKNavigationState::REQUESTED + forNavigation:navigation]; + std::unique_ptr<web::NavigationContextImpl> context; + const ui::PageTransition loadHTMLTransition = + ui::PageTransition::PAGE_TRANSITION_TYPED; + if (self.webStateImpl->HasWebUI()) { + // WebUI uses |loadHTML:forURL:| to feed the content to web view. This + // should not be treated as a navigation, but WKNavigationDelegate callbacks + // still expect a valid context. + context = web::NavigationContextImpl::CreateNavigationContext( + self.webStateImpl, URL, /*has_user_gesture=*/true, loadHTMLTransition, + /*is_renderer_initiated=*/false); + context->SetNavigationItemUniqueID(self.currentNavItem->GetUniqueID()); + if (web::features::StorePendingItemInContext()) { + // Transfer pending item ownership to NavigationContext. + // NavigationManager owns pending item after navigation is requested and + // until navigation context is created. + context->SetItem([self.sessionController releasePendingItem]); + } + } else { + context = [self registerLoadRequestForURL:URL + referrer:web::Referrer() + transition:loadHTMLTransition + sameDocumentNavigation:NO + hasUserGesture:YES + rendererInitiated:NO + placeholderNavigation:NO]; + } + context->SetLoadingHtmlString(true); + context->SetMimeType(@"text/html"); + [_navigationStates setContext:std::move(context) forNavigation:navigation]; +} + - (void)executeUserJavaScript:(NSString*)script completionHandler:(web::JavaScriptResultBlock)completion { // For security reasons, executing JavaScript on pages with app-specific URLs @@ -1757,13 +1719,6 @@ #pragma mark - -- (void)setNativeControllerWebUsageEnabled:(BOOL)webUsageEnabled { - if ([self.nativeController - respondsToSelector:@selector(setWebUsageEnabled:)]) { - [self.nativeController setWebUsageEnabled:webUsageEnabled]; - } -} - - (BOOL)isSafeBrowsingWarningDisplayedInWebView { // A SafeBrowsing warning is a UIScrollView that is inserted on top of // WKWebView's scroll view. This method uses heuristics to detect this view. @@ -2376,6 +2331,28 @@ })); } +- (WKNavigation*)loadPOSTRequest:(NSMutableURLRequest*)request { + if (!_POSTRequestLoader) { + _POSTRequestLoader = [[CRWJSPOSTRequestLoader alloc] init]; + } + + CRWWKScriptMessageRouter* messageRouter = + [self webViewConfigurationProvider].GetScriptMessageRouter(); + + return + [_POSTRequestLoader loadPOSTRequest:request + inWebView:self.webView + messageRouter:messageRouter + completionHandler:^(NSError* loadError) { + if (loadError) + [self handleLoadError:loadError + forNavigation:nil + provisionalLoad:YES]; + else + self.webStateImpl->SetContentsMimeType("text/html"); + }]; +} + - (void)reportBackForwardNavigationTypeForFastNavigation:(BOOL)isFast { // TODO(crbug.com/665189): Use NavigationManager::GetPendingItemIndex() once // it returns correct result. @@ -2592,85 +2569,6 @@ self.webStateImpl->OnPageLoaded(currentURL, NO); } -// Loads the current URL in a native controller if using the legacy navigation -// stack. If the new navigation stack is used, start loading a placeholder -// into the web view, upon the completion of which the native controller will -// be triggered. -- (void)loadCurrentURLInNativeViewWithRendererInitiatedNavigation: - (BOOL)rendererInitiated { - if (!web::GetWebClient()->IsSlimNavigationManagerEnabled()) { - // Free the web view. - [self removeWebView]; - [self presentNativeContentForNavigationItem:self.currentNavItem]; - [self didLoadNativeContentForNavigationItem:self.currentNavItem - rendererInitiated:rendererInitiated]; - } else { - // Just present the native view now. Leave the rest of native content load - // until the placeholder navigation finishes. - [self presentNativeContentForNavigationItem:self.currentNavItem]; - web::NavigationContextImpl* context = [self - loadPlaceholderInWebViewForURL:self.currentNavItem->GetVirtualURL() - rendererInitiated:rendererInitiated - forContext:nullptr]; - context->SetIsNativeContentPresented(true); - } -} - -- (void)presentNativeContentForNavigationItem:(web::NavigationItem*)item { - const GURL targetURL = item ? item->GetURL() : GURL::EmptyGURL(); - id<CRWNativeContent> nativeContent = - [_nativeProvider controllerForURL:targetURL webState:self.webState]; - // Unlike the WebView case, always create a new controller and view. - // TODO(crbug.com/759178): What to do if this does return nil? - [self setNativeController:nativeContent]; - if ([nativeContent respondsToSelector:@selector(virtualURL)]) { - item->SetVirtualURL([nativeContent virtualURL]); - } - - NSString* title = [self.nativeController title]; - if (title && item) { - base::string16 newTitle = base::SysNSStringToUTF16(title); - item->SetTitle(newTitle); - } -} - -- (void)didLoadNativeContentForNavigationItem:(web::NavigationItemImpl*)item - rendererInitiated:(BOOL)rendererInitiated { - const GURL targetURL = item ? item->GetURL() : GURL::EmptyGURL(); - const web::Referrer referrer; - std::unique_ptr<web::NavigationContextImpl> context = - [self registerLoadRequestForURL:targetURL - referrer:referrer - transition:self.currentTransition - sameDocumentNavigation:NO - hasUserGesture:YES - rendererInitiated:rendererInitiated - placeholderNavigation:NO]; - - self.webStateImpl->OnNavigationStarted(context.get()); - [self didStartLoading]; - self.navigationManagerImpl->CommitPendingItem(); - context->SetHasCommitted(true); - self.webStateImpl->OnNavigationFinished(context.get()); - - if (item && web::GetWebClient()->IsAppSpecificURL(item->GetURL())) { - // Report the successful navigation to the ErrorRetryStateMachine. - item->error_retry_state_machine().SetNoNavigationError(); - } - - NSString* title = [self.nativeController title]; - if (title) { - [self setNavigationItemTitle:title]; - } - - if ([self.nativeController respondsToSelector:@selector(setDelegate:)]) { - [self.nativeController setDelegate:self]; - } - - _loadPhase = web::PAGE_LOADED; - [self didFinishWithURL:targetURL loadSuccess:YES context:context.get()]; -} - - (web::NavigationContextImpl*) loadPlaceholderInWebViewForURL:(const GURL&)originalURL rendererInitiated:(BOOL)rendererInitiated @@ -2759,13 +2657,6 @@ return _documentURL; } -- (BOOL)shouldLoadURLInNativeView:(const GURL&)url { - // App-specific URLs that don't require WebUI are loaded in native views. - return web::GetWebClient()->IsAppSpecificURL(url) && - !self.webStateImpl->HasWebUI() && - [_nativeProvider hasControllerForURL:url]; -} - - (void)abortLoad { [self.webView stopLoading]; [_pendingNavigationInfo setCancelled:YES]; @@ -2942,6 +2833,112 @@ [self requirePageReconstruction]; } +#pragma mark - Native Content + +// Returns |YES| if |url| should be loaded in a native view. +- (BOOL)shouldLoadURLInNativeView:(const GURL&)url { + // App-specific URLs that don't require WebUI are loaded in native views. + return web::GetWebClient()->IsAppSpecificURL(url) && + !self.webStateImpl->HasWebUI() && + [_nativeProvider hasControllerForURL:url]; +} + +// Informs the native controller if web usage is allowed or not. +- (void)setNativeControllerWebUsageEnabled:(BOOL)webUsageEnabled { + if ([self.nativeController + respondsToSelector:@selector(setWebUsageEnabled:)]) { + [self.nativeController setWebUsageEnabled:webUsageEnabled]; + } +} + +// Loads the current URL in a native controller if using the legacy navigation +// stack. If the new navigation stack is used, start loading a placeholder +// into the web view, upon the completion of which the native controller will +// be triggered. +- (void)loadCurrentURLInNativeViewWithRendererInitiatedNavigation: + (BOOL)rendererInitiated { + if (!web::GetWebClient()->IsSlimNavigationManagerEnabled()) { + // Free the web view. + [self removeWebView]; + [self presentNativeContentForNavigationItem:self.currentNavItem]; + [self didLoadNativeContentForNavigationItem:self.currentNavItem + rendererInitiated:rendererInitiated]; + } else { + // Just present the native view now. Leave the rest of native content load + // until the placeholder navigation finishes. + [self presentNativeContentForNavigationItem:self.currentNavItem]; + web::NavigationContextImpl* context = [self + loadPlaceholderInWebViewForURL:self.currentNavItem->GetVirtualURL() + rendererInitiated:rendererInitiated + forContext:nullptr]; + context->SetIsNativeContentPresented(true); + } +} + +// Presents native content using the native controller for |item| without +// notifying WebStateObservers. This method does not modify the underlying web +// view. It simply covers the web view with the native content. +// |-didLoadNativeContentForNavigationItem| must be called some time later +// to notify WebStateObservers. +- (void)presentNativeContentForNavigationItem:(web::NavigationItem*)item { + const GURL targetURL = item ? item->GetURL() : GURL::EmptyGURL(); + id<CRWNativeContent> nativeContent = + [_nativeProvider controllerForURL:targetURL webState:self.webState]; + // Unlike the WebView case, always create a new controller and view. + // TODO(crbug.com/759178): What to do if this does return nil? + [self setNativeController:nativeContent]; + if ([nativeContent respondsToSelector:@selector(virtualURL)]) { + item->SetVirtualURL([nativeContent virtualURL]); + } + + NSString* title = [self.nativeController title]; + if (title && item) { + base::string16 newTitle = base::SysNSStringToUTF16(title); + item->SetTitle(newTitle); + } +} + +// Notifies WebStateObservers the completion of this navigation. +- (void)didLoadNativeContentForNavigationItem:(web::NavigationItemImpl*)item + rendererInitiated:(BOOL)rendererInitiated { + const GURL targetURL = item ? item->GetURL() : GURL::EmptyGURL(); + const web::Referrer referrer; + std::unique_ptr<web::NavigationContextImpl> context = + [self registerLoadRequestForURL:targetURL + referrer:referrer + transition:self.currentTransition + sameDocumentNavigation:NO + hasUserGesture:YES + rendererInitiated:rendererInitiated + placeholderNavigation:NO]; + + self.webStateImpl->OnNavigationStarted(context.get()); + [self didStartLoading]; + self.navigationManagerImpl->CommitPendingItem(); + context->SetHasCommitted(true); + self.webStateImpl->OnNavigationFinished(context.get()); + + if (item && web::GetWebClient()->IsAppSpecificURL(item->GetURL())) { + // Report the successful navigation to the ErrorRetryStateMachine. + item->error_retry_state_machine().SetNoNavigationError(); + } + + NSString* title = [self.nativeController title]; + if (title) { + [self setNavigationItemTitle:title]; + } + + if ([self.nativeController respondsToSelector:@selector(setDelegate:)]) { + [self.nativeController setDelegate:self]; + } + + _loadPhase = web::PAGE_LOADED; + [self didFinishWithURL:targetURL loadSuccess:YES context:context.get()]; +} + +// Discards non committed items, only if the last committed URL was not loaded +// in native view. But if it was a native view, no discard will happen to avoid +// an ugly animation where the web view is inserted and quickly removed. - (void)discardNonCommittedItemsIfLastCommittedWasNotNativeView { GURL lastCommittedURL = self.webState->GetLastCommittedURL(); BOOL previousItemWasLoadedInNativeView = @@ -3192,7 +3189,11 @@ } #pragma mark - JavaScript message handlers +// Handlers for JavaScript messages. |message| contains a JavaScript command and +// data relevant to the message, and |context| contains contextual information +// about web view state needed for some handlers. +// Handles 'chrome.send' message. - (BOOL)handleChromeSendMessage:(base::DictionaryValue*)message context:(NSDictionary*)context { // Chrome message are only handled if sent from the main frame. @@ -3227,6 +3228,7 @@ return NO; } +// Handles 'document.favicons' message. - (BOOL)handleDocumentFaviconsMessage:(base::DictionaryValue*)message context:(NSDictionary*)context { if (![context[kIsMainFrame] boolValue]) @@ -3247,6 +3249,7 @@ return YES; } +// Handles 'window.error' message. - (BOOL)handleWindowErrorMessage:(base::DictionaryValue*)message context:(NSDictionary*)context { std::string errorMessage; @@ -3259,6 +3262,7 @@ return YES; } +// Handles 'window.hashchange' message. - (BOOL)handleWindowHashChangeMessage:(base::DictionaryValue*)message context:(NSDictionary*)context { if (![context[kIsMainFrame] boolValue]) @@ -3277,6 +3281,7 @@ return YES; } +// Handles 'window.history.back' message. - (BOOL)handleWindowHistoryBackMessage:(base::DictionaryValue*)message context:(NSDictionary*)context { if (![context[kIsMainFrame] boolValue]) @@ -3286,6 +3291,7 @@ return YES; } +// Handles 'window.history.forward' message. - (BOOL)handleWindowHistoryForwardMessage:(base::DictionaryValue*)message context:(NSDictionary*)context { if (![context[kIsMainFrame] boolValue]) @@ -3295,6 +3301,7 @@ return YES; } +// Handles 'window.history.go' message. - (BOOL)handleWindowHistoryGoMessage:(base::DictionaryValue*)message context:(NSDictionary*)context { if (![context[kIsMainFrame] boolValue]) @@ -3308,6 +3315,7 @@ return NO; } +// Handles 'window.history.willChangeState' message. - (BOOL)handleWindowHistoryWillChangeStateMessage:(base::DictionaryValue*)unused context:(NSDictionary*)context { if (![context[kIsMainFrame] boolValue]) @@ -3316,6 +3324,7 @@ return YES; } +// Handles 'window.history.didPushState' message. - (BOOL)handleWindowHistoryDidPushStateMessage:(base::DictionaryValue*)message context:(NSDictionary*)context { if (![context[kIsMainFrame] boolValue]) @@ -3391,6 +3400,7 @@ return YES; } +// Handles 'window.history.didReplaceState' message. - (BOOL)handleWindowHistoryDidReplaceStateMessage: (base::DictionaryValue*)message context:(NSDictionary*)context { @@ -3449,6 +3459,7 @@ return YES; } +// Handles 'restoresession.error' message. - (BOOL)handleRestoreSessionErrorMessage:(base::DictionaryValue*)message context:(NSDictionary*)context { if (![context[kIsMainFrame] boolValue]) @@ -3470,346 +3481,6 @@ return YES; } -#pragma mark - - -// TODO(stuartmorgan): This method conflates document changes and URL changes; -// we should be distinguishing better, and be clear about the expected -// WebDelegate and WCO callbacks in each case. -- (void)webPageChangedWithContext:(web::NavigationContextImpl*)context { - DCHECK_EQ(_loadPhase, web::LOAD_REQUESTED); - - web::Referrer referrer = [self currentReferrer]; - // If no referrer was known in advance, record it now. (If there was one, - // keep it since it will have a more accurate URL and policy than what can - // be extracted from the landing page.) - web::NavigationItem* currentItem = self.currentNavItem; - - // TODO(crbug.com/925304): Pending item (which should be used here) should be - // owned by NavigationContext object. Pending item should never be null. - if (currentItem && !currentItem->GetReferrer().url.is_valid()) { - currentItem->SetReferrer(referrer); - } - - // TODO(stuartmorgan): This shouldn't be called for hash state or - // push/replaceState. - [self resetDocumentSpecificState]; - - [self didStartLoading]; - // Do not commit pending item in the middle of loading a placeholder URL. The - // item will be committed when the native content or webUI is displayed. - if (!context->IsPlaceholderNavigation()) { - self.navigationManagerImpl->CommitPendingItem(context->ReleaseItem()); - // If a SafeBrowsing warning is currently displayed, the user has tapped - // the button on the warning page to proceed to the site, the site has - // started loading, and the warning is about to be removed. In this case, - // the transient item for the warning needs to be removed too. - if ([self isSafeBrowsingWarningDisplayedInWebView]) - self.navigationManagerImpl->DiscardNonCommittedItems(); - } -} - -- (void)resetDocumentSpecificState { - _lastUserInteraction = nullptr; - _clickInProgress = NO; -} - -- (void)didStartLoading { - _loadPhase = web::PAGE_LOADING; - _displayStateOnStartLoading = self.pageDisplayState; - - self.userInteractionRegistered = NO; - _pageHasZoomed = NO; -} - -+ (BOOL)webControllerCanShow:(const GURL&)url { - return web::UrlHasWebScheme(url) || - web::GetWebClient()->IsAppSpecificURL(url) || - url.SchemeIs(url::kFileScheme) || url.SchemeIs(url::kAboutScheme) || - url.SchemeIs(url::kBlobScheme); -} - -- (void)cachePOSTDataForRequest:(NSURLRequest*)request - inNavigationItem:(web::NavigationItemImpl*)item { - NSUInteger maxPOSTDataSizeInBytes = 4096; - NSString* cookieHeaderName = @"cookie"; - - DCHECK(item); - const bool shouldUpdateEntry = - ui::PageTransitionCoreTypeIs(item->GetTransitionType(), - ui::PAGE_TRANSITION_FORM_SUBMIT) && - ![request HTTPBodyStream] && // Don't cache streams. - !item->HasPostData() && - item->GetURL() == net::GURLWithNSURL([request URL]); - const bool belowSizeCap = - [[request HTTPBody] length] < maxPOSTDataSizeInBytes; - DLOG_IF(WARNING, shouldUpdateEntry && !belowSizeCap) - << "Data in POST request exceeds the size cap (" << maxPOSTDataSizeInBytes - << " bytes), and will not be cached."; - - if (shouldUpdateEntry && belowSizeCap) { - item->SetPostData([request HTTPBody]); - item->ResetHttpRequestHeaders(); - item->AddHttpRequestHeaders([request allHTTPHeaderFields]); - // Don't cache the "Cookie" header. - // According to NSURLRequest documentation, |-valueForHTTPHeaderField:| is - // case insensitive, so it's enough to test the lower case only. - if ([request valueForHTTPHeaderField:cookieHeaderName]) { - // Case insensitive search in |headers|. - NSSet* cookieKeys = [item->GetHttpRequestHeaders() - keysOfEntriesPassingTest:^(id key, id obj, BOOL* stop) { - NSString* header = (NSString*)key; - const BOOL found = - [header caseInsensitiveCompare:cookieHeaderName] == - NSOrderedSame; - *stop = found; - return found; - }]; - DCHECK_EQ(1u, [cookieKeys count]); - item->RemoveHttpRequestHeaderForKey([cookieKeys anyObject]); - } - } -} - -- (BOOL)shouldAllowAppSpecificURLNavigationAction:(WKNavigationAction*)action - transition: - (ui::PageTransition)pageTransition { - GURL requestURL = net::GURLWithNSURL(action.request.URL); - DCHECK(web::GetWebClient()->IsAppSpecificURL(requestURL)); - if (web::GetWebClient()->IsAppSpecificURL( - self.webStateImpl->GetLastCommittedURL())) { - // Last committed page is also app specific and navigation should be - // allowed. - return YES; - } - - if (!ui::PageTransitionIsNewNavigation(pageTransition)) { - // Allow reloads and back-forward navigations. - return YES; - } - - if (ui::PageTransitionTypeIncludingQualifiersIs(pageTransition, - ui::PAGE_TRANSITION_TYPED)) { - return YES; - } - - if (ui::PageTransitionTypeIncludingQualifiersIs( - pageTransition, ui::PAGE_TRANSITION_GENERATED)) { - return YES; - } - - if (ui::PageTransitionTypeIncludingQualifiersIs( - pageTransition, ui::PAGE_TRANSITION_AUTO_BOOKMARK)) { - return YES; - } - - GURL mainDocumentURL = net::GURLWithNSURL(action.request.mainDocumentURL); - if (web::GetWebClient()->IsAppSpecificURL(mainDocumentURL) && - !action.sourceFrame.mainFrame) { - // AppSpecific URLs are allowed inside iframe if the main frame is also - // app specific page. - return YES; - } - - return NO; -} - -- (void)handleLoadError:(NSError*)error - forNavigation:(WKNavigation*)navigation - provisionalLoad:(BOOL)provisionalLoad { - if (error.code == NSURLErrorCancelled) { - [self handleCancelledError:error - forNavigation:navigation - provisionalLoad:provisionalLoad]; - // NSURLErrorCancelled errors that aren't handled by aborting the load will - // automatically be retried by the web view, so early return in this case. - return; - } - - web::NavigationContextImpl* navigationContext = - [_navigationStates contextForNavigation:navigation]; - navigationContext->SetError(error); - navigationContext->SetIsPost([self isCurrentNavigationItemPOST]); - // TODO(crbug.com/803631) DCHECK that self.currentNavItem is the navigation - // item associated with navigationContext. - - if ([error.domain isEqual:base::SysUTF8ToNSString(web::kWebKitErrorDomain)]) { - if (error.code == web::kWebKitErrorPlugInLoadFailed) { - // In cases where a Plug-in handles the load do not take any further - // action. - return; - } - - if (error.code == web::kWebKitErrorUrlBlockedByContentFilter && - web::GetWebClient()->IsSlimNavigationManagerEnabled()) { - // If URL is blocked due to Restriction, do not take any further action as - // WKWebView will show a built-in error. - return; - } - - if (error.code == web::kWebKitErrorFrameLoadInterruptedByPolicyChange) { - // This method should not be called if the navigation was cancelled by - // embedder. - DCHECK(_pendingNavigationInfo && ![_pendingNavigationInfo cancelled]); - - // Handle Frame Load Interrupted errors from WebView. This block is - // executed when web controller rejected the load inside - // decidePolicyForNavigationResponse: to handle download or WKWebView - // opened a Universal Link. - if (!navigationContext->IsDownload()) { - // Non-download navigation was cancelled because WKWebView has opened a - // Universal Link and called webView:didFailProvisionalNavigation:. - self.navigationManagerImpl->DiscardNonCommittedItems(); - } - self.webStateImpl->SetIsLoading(false); - return; - } - } - - NavigationManager* navManager = self.webState->GetNavigationManager(); - web::NavigationItem* lastCommittedItem = navManager->GetLastCommittedItem(); - if (lastCommittedItem) { - // Reset SSL status for last committed navigation to avoid showing security - // status for error pages. - if (!lastCommittedItem->GetSSL().Equals(web::SSLStatus())) { - lastCommittedItem->GetSSL() = web::SSLStatus(); - self.webStateImpl->DidChangeVisibleSecurityState(); - } - } - - web::NavigationItemImpl* item = - web::GetItemWithUniqueID(self.navigationManagerImpl, navigationContext); - - if (item) { - GURL errorURL = - net::GURLWithNSURL(error.userInfo[NSURLErrorFailingURLErrorKey]); - web::ErrorRetryCommand command = web::ErrorRetryCommand::kDoNothing; - if (provisionalLoad) { - command = item->error_retry_state_machine().DidFailProvisionalNavigation( - net::GURLWithNSURL(self.webView.URL), errorURL); - } else { - command = item->error_retry_state_machine().DidFailNavigation( - net::GURLWithNSURL(self.webView.URL), errorURL); - } - [self handleErrorRetryCommand:command - navigationItem:item - navigationContext:navigationContext - originalNavigation:navigation]; - } - - // Don't commit the pending item or call OnNavigationFinished until the - // placeholder navigation finishes loading. -} - -- (void)handleCancelledError:(NSError*)error - forNavigation:(WKNavigation*)navigation - provisionalLoad:(BOOL)provisionalLoad { - if ([self shouldCancelLoadForCancelledError:error - provisionalLoad:provisionalLoad]) { - web::NavigationContextImpl* navigationContext = - [_navigationStates contextForNavigation:navigation]; - [self loadCancelled]; - self.navigationManagerImpl->DiscardNonCommittedItems(); - // If discarding the non-committed entries results in native content URL, - // reload it in its native view. For WKBasedNavigationManager, this is not - // necessary because WKWebView takes care of reloading the placeholder URL, - // which triggers native view upon completion. - if (!web::GetWebClient()->IsSlimNavigationManagerEnabled() && - !self.nativeController) { - GURL lastCommittedURL = self.webState->GetLastCommittedURL(); - if ([self shouldLoadURLInNativeView:lastCommittedURL]) { - [self loadCurrentURLInNativeViewWithRendererInitiatedNavigation: - navigationContext->IsRendererInitiated()]; - } - } - - if (provisionalLoad) { - self.webStateImpl->OnNavigationFinished(navigationContext); - } - } -} - -- (BOOL)shouldCancelLoadForCancelledError:(NSError*)error - provisionalLoad:(BOOL)provisionalLoad { - DCHECK(error.code == NSURLErrorCancelled || - error.code == web::kWebKitErrorFrameLoadInterruptedByPolicyChange); - // Do not cancel the load if it is for an app specific URL, as such errors - // are produced during the app specific URL load process. - const GURL errorURL = - net::GURLWithNSURL(error.userInfo[NSURLErrorFailingURLErrorKey]); - if (web::GetWebClient()->IsAppSpecificURL(errorURL)) - return NO; - - return provisionalLoad; -} - -- (void)didReceiveWebViewNavigationDelegateCallback { - if (_isBeingDestroyed) { - UMA_HISTOGRAM_BOOLEAN("Renderer.WKWebViewCallbackAfterDestroy", true); - } - _safeBrowsingWarningDetectionTimer.Stop(); -} - -- (BOOL)shouldRenderResponse:(WKNavigationResponse*)WKResponse { - if (!WKResponse.canShowMIMEType) { - return NO; - } - - BOOL mainFrame = WKResponse.forMainFrame; - if (!self.webStateImpl->ShouldAllowResponse(WKResponse.response, mainFrame)) { - return NO; - } - - GURL responseURL = net::GURLWithNSURL(WKResponse.response.URL); - if (responseURL.SchemeIs(url::kDataScheme) && mainFrame) { - // Block rendering data URLs for renderer-initiated navigations in main - // frame to prevent abusive behavior (crbug.com/890558). - web::NavigationContext* context = - [self contextForPendingMainFrameNavigationWithURL:responseURL]; - if (context->IsRendererInitiated()) { - return NO; - } - } - - return YES; -} - -- (void)createDownloadTaskForResponse:(WKNavigationResponse*)WKResponse - HTTPHeaders:(net::HttpResponseHeaders*)headers { - const GURL responseURL = net::GURLWithNSURL(WKResponse.response.URL); - const int64_t contentLength = WKResponse.response.expectedContentLength; - const std::string MIMEType = - base::SysNSStringToUTF8(WKResponse.response.MIMEType); - - std::string contentDisposition; - if (headers) { - headers->GetNormalizedHeader("content-disposition", &contentDisposition); - } - - ui::PageTransition transition = ui::PAGE_TRANSITION_AUTO_SUBFRAME; - if (WKResponse.forMainFrame) { - web::NavigationContextImpl* context = - [self contextForPendingMainFrameNavigationWithURL:responseURL]; - context->SetIsDownload(true); - // Navigation callbacks can only be called for the main frame. - self.webStateImpl->OnNavigationFinished(context); - transition = context->GetPageTransition(); - bool transitionIsLink = ui::PageTransitionTypeIncludingQualifiersIs( - transition, ui::PAGE_TRANSITION_LINK); - if (transitionIsLink && !context->HasUserGesture()) { - // Link click is not possible without user gesture, so this transition - // was incorrectly classified and should be "client redirect" instead. - // TODO(crbug.com/549301): Remove this workaround when transition - // detection is fixed. - transition = ui::PAGE_TRANSITION_CLIENT_REDIRECT; - } - } - web::DownloadController::FromBrowserState( - self.webStateImpl->GetBrowserState()) - ->CreateDownloadTask(self.webStateImpl, [NSUUID UUID].UUIDString, - responseURL, contentDisposition, contentLength, - MIMEType, transition); -} - #pragma mark - WebUI - (void)createWebUIForURL:(const GURL&)URL { @@ -4070,8 +3741,8 @@ UIView* contentView = [webView viewForZoomingInScrollView:self.webScrollView]; - if ([webView - respondsToSelector:@selector(scrollViewWillBeginZooming:withView:)]) { + if ([webView respondsToSelector:@selector(scrollViewWillBeginZooming: + withView:)]) { [webView scrollViewWillBeginZooming:self.webScrollView withView:contentView]; } @@ -4079,9 +3750,8 @@ - (void)finishApplyingWebViewScrollZoomScale { id webView = self.webView; - if ([webView respondsToSelector:@selector(scrollViewDidEndZooming: - withView: - atScale:)] && + if ([webView respondsToSelector:@selector + (scrollViewDidEndZooming:withView:atScale:)] && [webView respondsToSelector:@selector(viewForZoomingInScrollView:)]) { // This correctly sets the content's frame in the scroll view to // fit the web page and upscales the content so that it isn't @@ -4288,6 +3958,9 @@ [self loadCancelled]; } +#pragma mark - WebView helpers + +// Creates a container view if it's not yet created. - (void)ensureContainerViewCreated { if (_containerView) return; @@ -4326,12 +3999,14 @@ [_containerView addGestureRecognizer:[self touchTrackingRecognizer]]; } +// Creates a web view if it's not yet created. - (void)ensureWebViewCreated { WKWebViewConfiguration* config = [self webViewConfigurationProvider].GetWebViewConfiguration(); [self ensureWebViewCreatedWithConfiguration:config]; } +// Creates a web view with given |config|. No-op if web view is already created. - (void)ensureWebViewCreatedWithConfiguration:(WKWebViewConfiguration*)config { if (!self.webView) { [self setWebView:[self webViewWithConfiguration:config]]; @@ -4384,6 +4059,7 @@ } } +// Returns a new autoreleased web view created with given configuration. - (WKWebView*)webViewWithConfiguration:(WKWebViewConfiguration*)config { // Do not attach the context menu controller immediately as the JavaScript // delegate must be specified. @@ -4392,60 +4068,8 @@ [self userAgentType]); } -- (void)setWebView:(WKWebView*)webView { - DCHECK_NE(_webView, webView); - - // Unwind the old web view. - // TODO(eugenebut): Remove CRWWKScriptMessageRouter once crbug.com/543374 is - // fixed. - CRWWKScriptMessageRouter* messageRouter = - [self webViewConfigurationProvider].GetScriptMessageRouter(); - if (_webView) { - [messageRouter removeAllScriptMessageHandlersForWebView:_webView]; - } - [_webView setNavigationDelegate:nil]; - [_webView setUIDelegate:nil]; - for (NSString* keyPath in self.WKWebViewObservers) { - [_webView removeObserver:self forKeyPath:keyPath]; - } - - _webView = webView; - - // Set up the new web view. - if (webView) { - __weak CRWWebController* weakSelf = self; - [messageRouter setScriptMessageHandler:^(WKScriptMessage* message) { - [weakSelf didReceiveScriptMessage:message]; - } - name:kScriptMessageName - webView:webView]; - - [messageRouter setScriptMessageHandler:^(WKScriptMessage* message) { - [weakSelf frameBecameAvailableWithMessage:message]; - } - name:kFrameBecameAvailableMessageName - webView:webView]; - [messageRouter setScriptMessageHandler:^(WKScriptMessage* message) { - [weakSelf frameBecameUnavailableWithMessage:message]; - } - name:kFrameBecameUnavailableMessageName - webView:webView]; - - _windowIDJSManager = [[CRWJSWindowIDManager alloc] initWithWebView:webView]; - } else { - _windowIDJSManager = nil; - } - [_webView setNavigationDelegate:self]; - [_webView setUIDelegate:self]; - for (NSString* keyPath in self.WKWebViewObservers) { - [_webView addObserver:self forKeyPath:keyPath options:0 context:nullptr]; - } - _webView.allowsBackForwardNavigationGestures = - _allowsBackForwardNavigationGestures; - _injectedScriptManagers = [[NSMutableSet alloc] init]; - [self setDocumentURL:_defaultURL context:nullptr]; -} - +// Wraps the web view in a CRWWebViewContentView and adds it to the container +// view. - (void)displayWebView { if (!self.webView || [_containerView webViewContentView]) return; @@ -4477,6 +4101,7 @@ } } +// Called when web view process has been terminated. - (void)webViewWebProcessDidCrash { if (@available(iOS 11, *)) { // On iOS 11 WKWebView does not repaint after crash and reload. Recreating @@ -4489,80 +4114,13 @@ self.webStateImpl->OnRenderProcessGone(); } +// Returns the WKWebViewConfigurationProvider associated with the web +// controller's BrowserState. - (web::WKWebViewConfigurationProvider&)webViewConfigurationProvider { web::BrowserState* browserState = self.webStateImpl->GetBrowserState(); return web::WKWebViewConfigurationProvider::FromBrowserState(browserState); } -- (WKNavigation*)loadPOSTRequest:(NSMutableURLRequest*)request { - if (!_POSTRequestLoader) { - _POSTRequestLoader = [[CRWJSPOSTRequestLoader alloc] init]; - } - - CRWWKScriptMessageRouter* messageRouter = - [self webViewConfigurationProvider].GetScriptMessageRouter(); - - return [_POSTRequestLoader - loadPOSTRequest:request - inWebView:self.webView - messageRouter:messageRouter - completionHandler:^(NSError* loadError) { - if (loadError) - [self handleLoadError:loadError - forNavigation:nil - provisionalLoad:YES]; - else - self.webStateImpl->SetContentsMimeType("text/html"); - }]; -} - -- (void)loadHTML:(NSString*)HTML forURL:(const GURL&)URL { - DCHECK(HTML.length); - // Remove the transient content view. - self.webStateImpl->ClearTransientContent(); - - _loadPhase = web::LOAD_REQUESTED; - - // Web View should not be created for App Specific URLs. - if (!web::GetWebClient()->IsAppSpecificURL(URL)) { - [self ensureWebViewCreated]; - DCHECK(self.webView) << "self.webView null while trying to load HTML"; - } - WKNavigation* navigation = - [self.webView loadHTMLString:HTML baseURL:net::NSURLWithGURL(URL)]; - [_navigationStates setState:web::WKNavigationState::REQUESTED - forNavigation:navigation]; - std::unique_ptr<web::NavigationContextImpl> context; - const ui::PageTransition loadHTMLTransition = - ui::PageTransition::PAGE_TRANSITION_TYPED; - if (self.webStateImpl->HasWebUI()) { - // WebUI uses |loadHTML:forURL:| to feed the content to web view. This - // should not be treated as a navigation, but WKNavigationDelegate callbacks - // still expect a valid context. - context = web::NavigationContextImpl::CreateNavigationContext( - self.webStateImpl, URL, /*has_user_gesture=*/true, loadHTMLTransition, - /*is_renderer_initiated=*/false); - context->SetNavigationItemUniqueID(self.currentNavItem->GetUniqueID()); - if (web::features::StorePendingItemInContext()) { - // Transfer pending item ownership to NavigationContext. - // NavigationManager owns pending item after navigation is requested and - // until navigation context is created. - context->SetItem([self.sessionController releasePendingItem]); - } - } else { - context = [self registerLoadRequestForURL:URL - referrer:web::Referrer() - transition:loadHTMLTransition - sameDocumentNavigation:NO - hasUserGesture:YES - rendererInitiated:NO - placeholderNavigation:NO]; - } - context->SetLoadingHtmlString(true); - context->SetMimeType(@"text/html"); - [_navigationStates setContext:std::move(context) forNavigation:navigation]; -} - #pragma mark - WKUIDelegate Methods - (WKWebView*)webView:(WKWebView*)webView @@ -4879,7 +4437,13 @@ // If the URL doesn't look like one that can be shown as a web page, it may // handled by the embedder. In that case, update the web controller to // correctly reflect the current state. - if (![CRWWebController webControllerCanShow:requestURL]) { + BOOL webControllerCanShow = + web::UrlHasWebScheme(requestURL) || + web::GetWebClient()->IsAppSpecificURL(requestURL) || + requestURL.SchemeIs(url::kFileScheme) || + requestURL.SchemeIs(url::kAboutScheme) || + requestURL.SchemeIs(url::kBlobScheme); + if (!webControllerCanShow) { // Stop load if navigation is believed to be happening on the main frame. if ([self isMainFrameNavigationAction:action]) [self stopLoading]; @@ -5656,7 +5220,372 @@ [self webViewWebProcessDidCrash]; } -#pragma mark - WKNavigationDelegate helper method +#pragma mark - WKNavigationDelegate Helpers + +// Called when the web page has changed document and/or URL, and so the page +// navigation should be reported to the delegate, and internal state updated to +// reflect the fact that the navigation has occurred. |context| contains +// information about the navigation that triggered the document/URL change. +// TODO(stuartmorgan): This method conflates document changes and URL changes; +// we should be distinguishing better, and be clear about the expected +// WebDelegate and WCO callbacks in each case. +- (void)webPageChangedWithContext:(web::NavigationContextImpl*)context { + DCHECK_EQ(_loadPhase, web::LOAD_REQUESTED); + + web::Referrer referrer = [self currentReferrer]; + // If no referrer was known in advance, record it now. (If there was one, + // keep it since it will have a more accurate URL and policy than what can + // be extracted from the landing page.) + web::NavigationItem* currentItem = self.currentNavItem; + + // TODO(crbug.com/925304): Pending item (which should be used here) should be + // owned by NavigationContext object. Pending item should never be null. + if (currentItem && !currentItem->GetReferrer().url.is_valid()) { + currentItem->SetReferrer(referrer); + } + + // TODO(stuartmorgan): This shouldn't be called for hash state or + // push/replaceState. + [self resetDocumentSpecificState]; + + [self didStartLoading]; + // Do not commit pending item in the middle of loading a placeholder URL. The + // item will be committed when the native content or webUI is displayed. + if (!context->IsPlaceholderNavigation()) { + self.navigationManagerImpl->CommitPendingItem(context->ReleaseItem()); + // If a SafeBrowsing warning is currently displayed, the user has tapped + // the button on the warning page to proceed to the site, the site has + // started loading, and the warning is about to be removed. In this case, + // the transient item for the warning needs to be removed too. + if ([self isSafeBrowsingWarningDisplayedInWebView]) + self.navigationManagerImpl->DiscardNonCommittedItems(); + } +} + +// Resets any state that is associated with a specific document object (e.g., +// page interaction tracking). +- (void)resetDocumentSpecificState { + _lastUserInteraction = nullptr; + _clickInProgress = NO; +} + +// Called when a page (native or web) has actually started loading (i.e., for +// a web page the document has actually changed), or after the load request has +// been registered for a non-document-changing URL change. Updates internal +// state not specific to web pages. +- (void)didStartLoading { + _loadPhase = web::PAGE_LOADING; + _displayStateOnStartLoading = self.pageDisplayState; + + self.userInteractionRegistered = NO; + _pageHasZoomed = NO; +} + +// Caches request POST data in the given session entry. +- (void)cachePOSTDataForRequest:(NSURLRequest*)request + inNavigationItem:(web::NavigationItemImpl*)item { + NSUInteger maxPOSTDataSizeInBytes = 4096; + NSString* cookieHeaderName = @"cookie"; + + DCHECK(item); + const bool shouldUpdateEntry = + ui::PageTransitionCoreTypeIs(item->GetTransitionType(), + ui::PAGE_TRANSITION_FORM_SUBMIT) && + ![request HTTPBodyStream] && // Don't cache streams. + !item->HasPostData() && + item->GetURL() == net::GURLWithNSURL([request URL]); + const bool belowSizeCap = + [[request HTTPBody] length] < maxPOSTDataSizeInBytes; + DLOG_IF(WARNING, shouldUpdateEntry && !belowSizeCap) + << "Data in POST request exceeds the size cap (" << maxPOSTDataSizeInBytes + << " bytes), and will not be cached."; + + if (shouldUpdateEntry && belowSizeCap) { + item->SetPostData([request HTTPBody]); + item->ResetHttpRequestHeaders(); + item->AddHttpRequestHeaders([request allHTTPHeaderFields]); + // Don't cache the "Cookie" header. + // According to NSURLRequest documentation, |-valueForHTTPHeaderField:| is + // case insensitive, so it's enough to test the lower case only. + if ([request valueForHTTPHeaderField:cookieHeaderName]) { + // Case insensitive search in |headers|. + NSSet* cookieKeys = [item->GetHttpRequestHeaders() + keysOfEntriesPassingTest:^(id key, id obj, BOOL* stop) { + NSString* header = (NSString*)key; + const BOOL found = + [header caseInsensitiveCompare:cookieHeaderName] == + NSOrderedSame; + *stop = found; + return found; + }]; + DCHECK_EQ(1u, [cookieKeys count]); + item->RemoveHttpRequestHeaderForKey([cookieKeys anyObject]); + } + } +} + +// Returns YES if the given |action| should be allowed to continue for app +// specific URL. If this returns NO, the navigation should be cancelled. +// App specific pages have elevated privileges and WKWebView uses the same +// renderer process for all page frames. With that Chromium does not allow +// running App specific pages in the same process as a web site from the +// internet. Allows navigation to app specific URL in the following cases: +// - last committed URL is app specific +// - navigation not a new navigation (back-forward or reload) +// - navigation is typed, generated or bookmark +// - navigation is performed in iframe and main frame is app-specific page +- (BOOL)shouldAllowAppSpecificURLNavigationAction:(WKNavigationAction*)action + transition: + (ui::PageTransition)pageTransition { + GURL requestURL = net::GURLWithNSURL(action.request.URL); + DCHECK(web::GetWebClient()->IsAppSpecificURL(requestURL)); + if (web::GetWebClient()->IsAppSpecificURL( + self.webStateImpl->GetLastCommittedURL())) { + // Last committed page is also app specific and navigation should be + // allowed. + return YES; + } + + if (!ui::PageTransitionIsNewNavigation(pageTransition)) { + // Allow reloads and back-forward navigations. + return YES; + } + + if (ui::PageTransitionTypeIncludingQualifiersIs(pageTransition, + ui::PAGE_TRANSITION_TYPED)) { + return YES; + } + + if (ui::PageTransitionTypeIncludingQualifiersIs( + pageTransition, ui::PAGE_TRANSITION_GENERATED)) { + return YES; + } + + if (ui::PageTransitionTypeIncludingQualifiersIs( + pageTransition, ui::PAGE_TRANSITION_AUTO_BOOKMARK)) { + return YES; + } + + GURL mainDocumentURL = net::GURLWithNSURL(action.request.mainDocumentURL); + if (web::GetWebClient()->IsAppSpecificURL(mainDocumentURL) && + !action.sourceFrame.mainFrame) { + // AppSpecific URLs are allowed inside iframe if the main frame is also + // app specific page. + return YES; + } + + return NO; +} + +// Called when a load ends in an error. +- (void)handleLoadError:(NSError*)error + forNavigation:(WKNavigation*)navigation + provisionalLoad:(BOOL)provisionalLoad { + if (error.code == NSURLErrorCancelled) { + [self handleCancelledError:error + forNavigation:navigation + provisionalLoad:provisionalLoad]; + // NSURLErrorCancelled errors that aren't handled by aborting the load will + // automatically be retried by the web view, so early return in this case. + return; + } + + web::NavigationContextImpl* navigationContext = + [_navigationStates contextForNavigation:navigation]; + navigationContext->SetError(error); + navigationContext->SetIsPost([self isCurrentNavigationItemPOST]); + // TODO(crbug.com/803631) DCHECK that self.currentNavItem is the navigation + // item associated with navigationContext. + + if ([error.domain isEqual:base::SysUTF8ToNSString(web::kWebKitErrorDomain)]) { + if (error.code == web::kWebKitErrorPlugInLoadFailed) { + // In cases where a Plug-in handles the load do not take any further + // action. + return; + } + + if (error.code == web::kWebKitErrorUrlBlockedByContentFilter && + web::GetWebClient()->IsSlimNavigationManagerEnabled()) { + // If URL is blocked due to Restriction, do not take any further action as + // WKWebView will show a built-in error. + return; + } + + if (error.code == web::kWebKitErrorFrameLoadInterruptedByPolicyChange) { + // This method should not be called if the navigation was cancelled by + // embedder. + DCHECK(_pendingNavigationInfo && ![_pendingNavigationInfo cancelled]); + + // Handle Frame Load Interrupted errors from WebView. This block is + // executed when web controller rejected the load inside + // decidePolicyForNavigationResponse: to handle download or WKWebView + // opened a Universal Link. + if (!navigationContext->IsDownload()) { + // Non-download navigation was cancelled because WKWebView has opened a + // Universal Link and called webView:didFailProvisionalNavigation:. + self.navigationManagerImpl->DiscardNonCommittedItems(); + } + self.webStateImpl->SetIsLoading(false); + return; + } + } + + NavigationManager* navManager = self.webState->GetNavigationManager(); + web::NavigationItem* lastCommittedItem = navManager->GetLastCommittedItem(); + if (lastCommittedItem) { + // Reset SSL status for last committed navigation to avoid showing security + // status for error pages. + if (!lastCommittedItem->GetSSL().Equals(web::SSLStatus())) { + lastCommittedItem->GetSSL() = web::SSLStatus(); + self.webStateImpl->DidChangeVisibleSecurityState(); + } + } + + web::NavigationItemImpl* item = + web::GetItemWithUniqueID(self.navigationManagerImpl, navigationContext); + + if (item) { + GURL errorURL = + net::GURLWithNSURL(error.userInfo[NSURLErrorFailingURLErrorKey]); + web::ErrorRetryCommand command = web::ErrorRetryCommand::kDoNothing; + if (provisionalLoad) { + command = item->error_retry_state_machine().DidFailProvisionalNavigation( + net::GURLWithNSURL(self.webView.URL), errorURL); + } else { + command = item->error_retry_state_machine().DidFailNavigation( + net::GURLWithNSURL(self.webView.URL), errorURL); + } + [self handleErrorRetryCommand:command + navigationItem:item + navigationContext:navigationContext + originalNavigation:navigation]; + } + + // Don't commit the pending item or call OnNavigationFinished until the + // placeholder navigation finishes loading. +} + +// Handles cancelled load in WKWebView (error with NSURLErrorCancelled code). +- (void)handleCancelledError:(NSError*)error + forNavigation:(WKNavigation*)navigation + provisionalLoad:(BOOL)provisionalLoad { + if ([self shouldCancelLoadForCancelledError:error + provisionalLoad:provisionalLoad]) { + web::NavigationContextImpl* navigationContext = + [_navigationStates contextForNavigation:navigation]; + [self loadCancelled]; + self.navigationManagerImpl->DiscardNonCommittedItems(); + // If discarding the non-committed entries results in native content URL, + // reload it in its native view. For WKBasedNavigationManager, this is not + // necessary because WKWebView takes care of reloading the placeholder URL, + // which triggers native view upon completion. + if (!web::GetWebClient()->IsSlimNavigationManagerEnabled() && + !self.nativeController) { + GURL lastCommittedURL = self.webState->GetLastCommittedURL(); + if ([self shouldLoadURLInNativeView:lastCommittedURL]) { + [self loadCurrentURLInNativeViewWithRendererInitiatedNavigation: + navigationContext->IsRendererInitiated()]; + } + } + + if (provisionalLoad) { + self.webStateImpl->OnNavigationFinished(navigationContext); + } + } +} + +// Used to decide whether a load that generates errors with the +// NSURLErrorCancelled code should be cancelled. +- (BOOL)shouldCancelLoadForCancelledError:(NSError*)error + provisionalLoad:(BOOL)provisionalLoad { + DCHECK(error.code == NSURLErrorCancelled || + error.code == web::kWebKitErrorFrameLoadInterruptedByPolicyChange); + // Do not cancel the load if it is for an app specific URL, as such errors + // are produced during the app specific URL load process. + const GURL errorURL = + net::GURLWithNSURL(error.userInfo[NSURLErrorFailingURLErrorKey]); + if (web::GetWebClient()->IsAppSpecificURL(errorURL)) + return NO; + + return provisionalLoad; +} + +// This method should be called on receiving WKNavigationDelegate callbacks. It +// will log a metric if the callback occurs after the reciever has already been +// closed. It also stops the SafeBrowsing warning detection timer, since after +// this point it's too late for a SafeBrowsing warning to be displayed for the +// navigation for which the timer was started. +- (void)didReceiveWebViewNavigationDelegateCallback { + if (_isBeingDestroyed) { + UMA_HISTOGRAM_BOOLEAN("Renderer.WKWebViewCallbackAfterDestroy", true); + } + _safeBrowsingWarningDetectionTimer.Stop(); +} + +// Returns YES if response should be rendered in WKWebView. +- (BOOL)shouldRenderResponse:(WKNavigationResponse*)WKResponse { + if (!WKResponse.canShowMIMEType) { + return NO; + } + + BOOL mainFrame = WKResponse.forMainFrame; + if (!self.webStateImpl->ShouldAllowResponse(WKResponse.response, mainFrame)) { + return NO; + } + + GURL responseURL = net::GURLWithNSURL(WKResponse.response.URL); + if (responseURL.SchemeIs(url::kDataScheme) && mainFrame) { + // Block rendering data URLs for renderer-initiated navigations in main + // frame to prevent abusive behavior (crbug.com/890558). + web::NavigationContext* context = + [self contextForPendingMainFrameNavigationWithURL:responseURL]; + if (context->IsRendererInitiated()) { + return NO; + } + } + + return YES; +} + +// Creates DownloadTask for the given navigation response. Headers are passed +// as argument to avoid extra NSDictionary -> net::HttpResponseHeaders +// conversion. +- (void)createDownloadTaskForResponse:(WKNavigationResponse*)WKResponse + HTTPHeaders:(net::HttpResponseHeaders*)headers { + const GURL responseURL = net::GURLWithNSURL(WKResponse.response.URL); + const int64_t contentLength = WKResponse.response.expectedContentLength; + const std::string MIMEType = + base::SysNSStringToUTF8(WKResponse.response.MIMEType); + + std::string contentDisposition; + if (headers) { + headers->GetNormalizedHeader("content-disposition", &contentDisposition); + } + + ui::PageTransition transition = ui::PAGE_TRANSITION_AUTO_SUBFRAME; + if (WKResponse.forMainFrame) { + web::NavigationContextImpl* context = + [self contextForPendingMainFrameNavigationWithURL:responseURL]; + context->SetIsDownload(true); + // Navigation callbacks can only be called for the main frame. + self.webStateImpl->OnNavigationFinished(context); + transition = context->GetPageTransition(); + bool transitionIsLink = ui::PageTransitionTypeIncludingQualifiersIs( + transition, ui::PAGE_TRANSITION_LINK); + if (transitionIsLink && !context->HasUserGesture()) { + // Link click is not possible without user gesture, so this transition + // was incorrectly classified and should be "client redirect" instead. + // TODO(crbug.com/549301): Remove this workaround when transition + // detection is fixed. + transition = ui::PAGE_TRANSITION_CLIENT_REDIRECT; + } + } + web::DownloadController::FromBrowserState( + self.webStateImpl->GetBrowserState()) + ->CreateDownloadTask(self.webStateImpl, [NSUUID UUID].UUIDString, + responseURL, contentDisposition, contentLength, + MIMEType, transition); +} // WKNavigation objects are used as a weak key to store web::NavigationContext. // WKWebView manages WKNavigation lifetime and destroys them after the
diff --git a/media/webrtc/BUILD.gn b/media/webrtc/BUILD.gn index b2856da9..6c4bc4e 100644 --- a/media/webrtc/BUILD.gn +++ b/media/webrtc/BUILD.gn
@@ -18,8 +18,6 @@ sources = [ "audio_delay_stats_reporter.cc", "audio_delay_stats_reporter.h", - "echo_information.cc", - "echo_information.h", "webrtc_switches.cc", "webrtc_switches.h", ]
diff --git a/media/webrtc/audio_processor.cc b/media/webrtc/audio_processor.cc index 7ecbc26..991213df 100644 --- a/media/webrtc/audio_processor.cc +++ b/media/webrtc/audio_processor.cc
@@ -46,6 +46,12 @@ } } +bool EchoCancellationIsWebRtcProvided( + const EchoCancellationType& echo_cancellation_type) { + return echo_cancellation_type == EchoCancellationType::kAec2 || + echo_cancellation_type == EchoCancellationType::kAec3; +} + } // namespace AudioProcessor::ProcessingResult::ProcessingResult( @@ -76,9 +82,6 @@ StopEchoCancellationDump(); if (audio_processing_) audio_processing_->UpdateHistogramsOnCallEnd(); - // EchoInformation does this by itself on destruction, but since the stats are - // reset, they won't get doubly reported. - echo_information_.ReportAndResetAecDivergentFilterStats(); } // Process the audio from source and return a pointer to the processed data. @@ -138,12 +141,6 @@ DCHECK_EQ(apm_error, webrtc::AudioProcessing::kNoError); } -void AudioProcessor::UpdateInternalStats() { - if (audio_processing_) - echo_information_.UpdateAecStats( - audio_processing_->GetStatistics(has_reverse_stream_)); -} - void AudioProcessor::GetStats(GetStatsCB callback) { webrtc::AudioProcessorInterface::AudioProcessorStatistics out = {}; if (audio_processing_) { @@ -199,8 +196,7 @@ // 2" in those cases. // If we use nothing but, possibly, audio mirroring, don't initialize the APM. - if (settings_.echo_cancellation != EchoCancellationType::kAec2 && - settings_.echo_cancellation != EchoCancellationType::kAec3 && + if (!EchoCancellationIsWebRtcProvided(settings_.echo_cancellation) && settings_.noise_suppression == NoiseSuppressionType::kDisabled && settings_.automatic_gain_control == AutomaticGainControlType::kDisabled && !settings_.high_pass_filter && !settings_.typing_detection) { @@ -212,17 +208,10 @@ // AEC setup part 1. - // AEC2 options. Doesn't do anything if AEC2 isn't used. - ap_config.Set<webrtc::RefinedAdaptiveFilter>( - new webrtc::RefinedAdaptiveFilter( - base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kAecRefinedAdaptiveFilter))); - ap_config.Set<webrtc::ExtendedFilter>(new webrtc::ExtendedFilter(true)); - ap_config.Set<webrtc::DelayAgnostic>(new webrtc::DelayAgnostic(true)); // Echo cancellation is configured both before and after AudioProcessing // construction, but before Initialize. - if (settings_.echo_cancellation == EchoCancellationType::kAec3) { + if (EchoCancellationIsWebRtcProvided(settings_.echo_cancellation)) { ap_builder.SetEchoControlFactory( std::make_unique<webrtc::EchoCanceller3Factory>()); } @@ -285,8 +274,7 @@ // AEC setup part 2. apm_config.echo_canceller.enabled = - settings_.echo_cancellation == EchoCancellationType::kAec2 || - settings_.echo_cancellation == EchoCancellationType::kAec3; + EchoCancellationIsWebRtcProvided(settings_.echo_cancellation); apm_config.echo_canceller.mobile_mode = false; // High-pass filter setup.
diff --git a/media/webrtc/audio_processor.h b/media/webrtc/audio_processor.h index c7e7c93..68c0a58 100644 --- a/media/webrtc/audio_processor.h +++ b/media/webrtc/audio_processor.h
@@ -19,7 +19,6 @@ #include "media/base/audio_processing.h" #include "media/webrtc/audio_delay_stats_reporter.h" #include "media/webrtc/audio_processor_controls.h" -#include "media/webrtc/echo_information.h" #include "third_party/webrtc/modules/audio_processing/include/audio_processing.h" #include "third_party/webrtc/modules/audio_processing/typing_detection.h" #include "third_party/webrtc/rtc_base/task_queue.h" @@ -63,8 +62,6 @@ const AudioParameters& parameters, base::TimeTicks playout_time); - void UpdateInternalStats(); - void set_has_reverse_stream(bool has_reverse_stream) { has_reverse_stream_ = has_reverse_stream; } @@ -109,8 +106,6 @@ // thread. std::unique_ptr<rtc::TaskQueue> worker_queue_; - EchoInformation echo_information_; - DISALLOW_COPY_AND_ASSIGN(AudioProcessor); };
diff --git a/media/webrtc/echo_information.cc b/media/webrtc/echo_information.cc deleted file mode 100644 index b5a3fb2..0000000 --- a/media/webrtc/echo_information.cc +++ /dev/null
@@ -1,66 +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 "media/webrtc/echo_information.h" - -#include "base/metrics/histogram_macros.h" -#include "third_party/webrtc/modules/audio_processing/include/audio_processing.h" - -namespace media { - -EchoInformation::EchoInformation() - : divergent_filter_stats_time_ms_(0), - num_divergent_filter_fraction_(0), - num_non_zero_divergent_filter_fraction_(0) {} - -EchoInformation::~EchoInformation() { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - ReportAndResetAecDivergentFilterStats(); -} - -void EchoInformation::UpdateAecStats( - const webrtc::AudioProcessingStats& audio_processing_stats) { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - - if (!audio_processing_stats.divergent_filter_fraction) { - return; - } - - divergent_filter_stats_time_ms_ += webrtc::AudioProcessing::kChunkSizeMs; - if (divergent_filter_stats_time_ms_ < - 100 * webrtc::AudioProcessing::kChunkSizeMs) { // 1 second - return; - } - - double divergent_filter_fraction = - *audio_processing_stats.divergent_filter_fraction; - // If not yet calculated, |metrics.divergent_filter_fraction| is -1.0. After - // being calculated the first time, it is updated periodically. - if (divergent_filter_fraction < 0.0f) { - DCHECK_EQ(num_divergent_filter_fraction_, 0); - return; - } - if (divergent_filter_fraction > 0.0f) { - ++num_non_zero_divergent_filter_fraction_; - } - ++num_divergent_filter_fraction_; - divergent_filter_stats_time_ms_ = 0; -} - -void EchoInformation::ReportAndResetAecDivergentFilterStats() { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - - if (num_divergent_filter_fraction_ == 0) - return; - - int non_zero_percent = 100 * num_non_zero_divergent_filter_fraction_ / - num_divergent_filter_fraction_; - UMA_HISTOGRAM_PERCENTAGE("WebRTC.AecFilterHasDivergence", non_zero_percent); - - divergent_filter_stats_time_ms_ = 0; - num_non_zero_divergent_filter_fraction_ = 0; - num_divergent_filter_fraction_ = 0; -} - -} // namespace media
diff --git a/media/webrtc/echo_information.h b/media/webrtc/echo_information.h deleted file mode 100644 index 49460bf..0000000 --- a/media/webrtc/echo_information.h +++ /dev/null
@@ -1,48 +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 MEDIA_WEBRTC_ECHO_INFORMATION_H_ -#define MEDIA_WEBRTC_ECHO_INFORMATION_H_ - -#include "base/component_export.h" -#include "base/threading/thread_checker.h" -#include "third_party/webrtc/modules/audio_processing/include/audio_processing.h" - -namespace media { - -// A helper class to log echo information in general and AEC2 -// quality in particular. -class COMPONENT_EXPORT(MEDIA_WEBRTC) EchoInformation { - public: - EchoInformation(); - virtual ~EchoInformation(); - - // Updates stats, and reports metrics as UMA stats every 5 seconds. - // Must be called every time AudioProcessing::ProcessStream() is called. - void UpdateAecStats( - const webrtc::AudioProcessingStats& audio_processing_stats); - - // Reports AEC divergent filter metrics as UMA and resets the associated data. - void ReportAndResetAecDivergentFilterStats(); - - private: - // Counter to store a new value for the divergent filter fraction metric in - // AEC2, once every second. - int divergent_filter_stats_time_ms_; - - // Total number of times we queried for the divergent filter fraction metric. - int num_divergent_filter_fraction_; - - // Number of non-zero divergent filter fraction metrics. - int num_non_zero_divergent_filter_fraction_; - - // Ensures that this class is accessed on the same thread. - THREAD_CHECKER(thread_checker_); - - DISALLOW_COPY_AND_ASSIGN(EchoInformation); -}; - -} // namespace media - -#endif // MEDIA_WEBRTC_ECHO_INFORMATION_H_
diff --git a/media/webrtc/webrtc_switches.cc b/media/webrtc/webrtc_switches.cc index c3645ec..8224fc1b 100644 --- a/media/webrtc/webrtc_switches.cc +++ b/media/webrtc/webrtc_switches.cc
@@ -6,14 +6,6 @@ namespace switches { -// Enables a new tuning of the WebRTC Acoustic Echo Canceler (AEC). The new -// tuning aims at resolving two issues with the AEC: -// https://bugs.chromium.org/p/webrtc/issues/detail?id=5777 -// https://bugs.chromium.org/p/webrtc/issues/detail?id=5778 -// TODO(hlundin): Remove this switch when experimentation is over; -// crbug.com/603821. -const char kAecRefinedAdaptiveFilter[] = "aec-refined-adaptive-filter"; - // Override the default minimum starting volume of the Automatic Gain Control // algorithm in WebRTC used with audio tracks from getUserMedia. // The valid range is 12-255. Values outside that range will be clamped
diff --git a/media/webrtc/webrtc_switches.h b/media/webrtc/webrtc_switches.h index b08ce314..0539b5b6 100644 --- a/media/webrtc/webrtc_switches.h +++ b/media/webrtc/webrtc_switches.h
@@ -12,7 +12,6 @@ namespace switches { -COMPONENT_EXPORT(MEDIA_WEBRTC) extern const char kAecRefinedAdaptiveFilter[]; COMPONENT_EXPORT(MEDIA_WEBRTC) extern const char kAgcStartupMinVolume[]; } // namespace switches
diff --git a/net/cookies/canonical_cookie.cc b/net/cookies/canonical_cookie.cc index 3b03a50c..aec043d3 100644 --- a/net/cookies/canonical_cookie.cc +++ b/net/cookies/canonical_cookie.cc
@@ -44,6 +44,8 @@ #include "net/cookies/canonical_cookie.h" +#include <utility> + #include "base/format_macros.h" #include "base/logging.h" #include "base/metrics/histogram_macros.h" @@ -552,4 +554,9 @@ return domain_.substr(1); } +CookieLineWithStatus::CookieLineWithStatus( + std::string cookie_string, + CanonicalCookie::CookieInclusionStatus status) + : cookie_string(std::move(cookie_string)), status(status) {} + } // namespace net
diff --git a/net/cookies/canonical_cookie.h b/net/cookies/canonical_cookie.h index 2fca15f..f82e9e5 100644 --- a/net/cookies/canonical_cookie.h +++ b/net/cookies/canonical_cookie.h
@@ -66,7 +66,8 @@ EXCLUDE_OVERWRITE_SECURE, EXCLUDE_OVERWRITE_HTTP_ONLY, EXCLUDE_INVALID_DOMAIN, - EXCLUDE_INVALID_PREFIX + EXCLUDE_INVALID_PREFIX, + EXCLUDE_THIRD_PARTY_POLICY }; // Creates a new |CanonicalCookie| from the |cookie_line| and the @@ -265,6 +266,15 @@ CanonicalCookie::CookieInclusionStatus status; }; +// Just used for the next function to send the cookie string with it's status +struct CookieLineWithStatus { + CookieLineWithStatus(std::string cookie_string, + CanonicalCookie::CookieInclusionStatus status); + + std::string cookie_string; + CanonicalCookie::CookieInclusionStatus status; +}; + typedef std::vector<CanonicalCookie> CookieList; typedef std::vector<CookieWithStatus> CookieStatusList;
diff --git a/net/test/embedded_test_server/default_handlers.cc b/net/test/embedded_test_server/default_handlers.cc index 176ca7b..e438785 100644 --- a/net/test/embedded_test_server/default_handlers.cc +++ b/net/test/embedded_test_server/default_handlers.cc
@@ -376,6 +376,9 @@ return std::move(http_response); } + if (query.find("set-cookie-if-not-challenged") != query.end()) + http_response->AddCustomHeader("Set-Cookie", "got_challenged=true"); + if (request.headers.find("If-None-Match") != request.headers.end() && request.headers.at("If-None-Match") == kEtag) { http_response->set_code(HTTP_NOT_MODIFIED);
diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc index 9a51c8e..d853324e 100644 --- a/net/url_request/url_request_http_job.cc +++ b/net/url_request/url_request_http_job.cc
@@ -363,6 +363,7 @@ NetworkDelegate* network_delegate, const HttpUserAgentSettings* http_user_agent_settings) : URLRequestJob(request, network_delegate), + num_cookie_lines_left_(0), priority_(DEFAULT_PRIORITY), response_info_(nullptr), proxy_auth_state_(AUTH_STATE_DONT_NEED_AUTH), @@ -474,6 +475,7 @@ void URLRequestHttpJob::NotifyHeadersComplete() { DCHECK(!response_info_); + DCHECK_EQ(0, num_cookie_lines_left_); response_info_ = transaction_->GetResponseInfo(); @@ -488,6 +490,10 @@ ProcessStrictTransportSecurityHeader(); ProcessExpectCTHeader(); + // Clear |cs_status_list_| after any processing in case + // SaveCookiesAndNotifyHeadersComplete is called again. + cs_status_list_.clear(); + // The HTTP transaction may be restarted several times for the purposes // of sending authorization information. Each time it restarts, we get // notified of the headers completion so that we can update the cookie store. @@ -723,6 +729,9 @@ } void URLRequestHttpJob::SaveCookiesAndNotifyHeadersComplete(int result) { + DCHECK(cs_status_list_.empty()); + DCHECK_EQ(0, num_cookie_lines_left_); + // End of the call started in OnStartCompleted. OnCallToDelegateComplete(); @@ -734,34 +743,82 @@ return; } + if ((request_info_.load_flags & LOAD_DO_NOT_SAVE_COOKIES) || + !request_->context()->cookie_store()) { + NotifyHeadersComplete(); + return; + } + base::Time response_date; if (!GetResponseHeaders()->GetDateValue(&response_date)) response_date = base::Time(); - if (!(request_info_.load_flags & LOAD_DO_NOT_SAVE_COOKIES) && - request_->context()->cookie_store()) { - CookieOptions options; - options.set_include_httponly(); - options.set_server_time(response_date); + CookieOptions options; + options.set_include_httponly(); + options.set_server_time(response_date); - // Set all cookies, without waiting for them to be set. Any subsequent read - // will see the combined result of all cookie operation. - const base::StringPiece name("Set-Cookie"); - std::string cookie_line; - size_t iter = 0; - HttpResponseHeaders* headers = GetResponseHeaders(); - while (headers->EnumerateHeader(&iter, name, &cookie_line)) { - std::unique_ptr<CanonicalCookie> cookie = net::CanonicalCookie::Create( - request_->url(), cookie_line, base::Time::Now(), options); - if (!cookie || !CanSetCookie(*cookie, &options)) - continue; - request_->context()->cookie_store()->SetCookieWithOptionsAsync( - request_->url(), cookie_line, options, - CookieStore::SetCookiesCallback()); + // Set all cookies, without waiting for them to be set. Any subsequent read + // will see the combined result of all cookie operation. + const base::StringPiece name("Set-Cookie"); + std::string cookie_string; + size_t iter = 0; + HttpResponseHeaders* headers = GetResponseHeaders(); + + // NotifyHeadersComplete needs to be called once and only once after the + // list has been fully processed, and it can either be called in the + // callback or after the loop is called, depending on how the last element + // was handled. |num_cookie_lines_left_| keeps track of how many async + // callbacks are currently out (starting from 1 to make sure the loop runs all + // the way through before trying to exit). If there are any callbacks still + // waiting when the loop ends, then NotifyHeadersComplete will be called when + // it reaches 0 in the callback itself. + num_cookie_lines_left_ = 1; + while (headers->EnumerateHeader(&iter, name, &cookie_string)) { + CanonicalCookie::CookieInclusionStatus returned_status; + + num_cookie_lines_left_++; + + std::unique_ptr<CanonicalCookie> cookie = net::CanonicalCookie::Create( + request_->url(), cookie_string, base::Time::Now(), options, + &returned_status); + + if (returned_status != CanonicalCookie::CookieInclusionStatus::INCLUDE) { + OnSetCookieResult(std::move(cookie_string), returned_status); + continue; } - } - NotifyHeadersComplete(); + if (!CanSetCookie(*cookie, &options)) { + OnSetCookieResult( + std::move(cookie_string), + CanonicalCookie::CookieInclusionStatus::EXCLUDE_THIRD_PARTY_POLICY); + continue; + } + + request_->context()->cookie_store()->SetCookieWithOptionsAsync( + request_->url(), cookie_string, options, + base::BindOnce(&URLRequestHttpJob::OnSetCookieResult, + weak_factory_.GetWeakPtr(), cookie_string)); + } + // Removing the 1 that |num_cookie_lines_left| started with, signifing that + // loop has been exited. + num_cookie_lines_left_--; + + if (num_cookie_lines_left_ == 0) + NotifyHeadersComplete(); +} + +void URLRequestHttpJob::OnSetCookieResult( + std::string cookie_string, + CanonicalCookie::CookieInclusionStatus status) { + if (status != CanonicalCookie::CookieInclusionStatus::INCLUDE) + cs_status_list_.emplace_back(std::move(cookie_string), status); + + num_cookie_lines_left_--; + + // If all the cookie lines have been handled, |cs_status_list_| now reflects + // the result of all Set-Cookie lines, and the request can be continued. + if (num_cookie_lines_left_ == 0) + NotifyHeadersComplete(); } void URLRequestHttpJob::ProcessStrictTransportSecurityHeader() {
diff --git a/net/url_request/url_request_http_job.h b/net/url_request/url_request_http_job.h index 3f16164..6212aa61 100644 --- a/net/url_request/url_request_http_job.h +++ b/net/url_request/url_request_http_job.h
@@ -10,6 +10,7 @@ #include <memory> #include <string> +#include <vector> #include "base/compiler_specific.h" #include "base/macros.h" @@ -152,6 +153,12 @@ void SetCookieHeaderAndStart(const CookieList& cookie_list, const CookieStatusList& excluded_list); + // Another Cookie Monster callback + void OnSetCookieResult(std::string cookie_string, + CanonicalCookie::CookieInclusionStatus status); + int num_cookie_lines_left_; + std::vector<CookieLineWithStatus> cs_status_list_; + // Some servers send the body compressed, but specify the content length as // the uncompressed size. If this is the case, we return true in order // to request to work around this non-adherence to the HTTP standard.
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc index e8aad11..c6323ed 100644 --- a/net/url_request/url_request_unittest.cc +++ b/net/url_request/url_request_unittest.cc
@@ -53,6 +53,7 @@ #include "net/base/chunked_upload_data_stream.h" #include "net/base/directory_listing.h" #include "net/base/elements_upload_data_stream.h" +#include "net/base/layered_network_delegate.h" #include "net/base/load_flags.h" #include "net/base/load_timing_info.h" #include "net/base/load_timing_info_test_util.h" @@ -2591,6 +2592,154 @@ } } +class FilteringTestLayeredNetworkDelegate : public LayeredNetworkDelegate { + public: + FilteringTestLayeredNetworkDelegate( + std::unique_ptr<NetworkDelegate> network_delegate) + : LayeredNetworkDelegate(std::move((network_delegate))), + set_cookie_called_count_(0), + blocked_set_cookie_count_(0) {} + ~FilteringTestLayeredNetworkDelegate() override = default; + + bool OnCanSetCookieInternal(const URLRequest& request, + const net::CanonicalCookie& cookie, + CookieOptions* options, + bool allowed_from_caller) override { + // Filter out cookies with the same name as |cookie_name_filter_| and + // combine with |allowed_from_caller|. + bool allowed = + allowed_from_caller && !(cookie.Name() == cookie_name_filter_); + + ++set_cookie_called_count_; + + if (!allowed) + ++blocked_set_cookie_count_; + + return allowed; + } + + void SetCookieFilter(std::string filter) { + cookie_name_filter_ = std::move(filter); + } + + int set_cookie_called_count() { return set_cookie_called_count_; } + + int blocked_set_cookie_count() { return blocked_set_cookie_count_; } + + void ResetSetCookieCalledCount() { set_cookie_called_count_ = 0; } + + void ResetBlockedSetCookieCount() { blocked_set_cookie_count_ = 0; } + + private: + std::string cookie_name_filter_; + int set_cookie_called_count_; + int blocked_set_cookie_count_; +}; + +TEST_F(URLRequestTest, DelayedCookieCallbackAsync) { + HttpTestServer test_server; + ASSERT_TRUE(test_server.Start()); + + TestURLRequestContext async_context; + std::unique_ptr<DelayedCookieMonster> delayed_cm = + std::make_unique<DelayedCookieMonster>(); + async_context.set_cookie_store(delayed_cm.get()); + FilteringTestLayeredNetworkDelegate async_filter_network_delegate( + std::make_unique<TestNetworkDelegate>()); + async_filter_network_delegate.SetCookieFilter("CookieBlockedOnCanGetCookie"); + async_context.set_network_delegate(&async_filter_network_delegate); + TestDelegate async_delegate; + + TestURLRequestContext sync_context; + std::unique_ptr<CookieMonster> cm = + std::make_unique<CookieMonster>(nullptr, nullptr, nullptr); + sync_context.set_cookie_store(cm.get()); + FilteringTestLayeredNetworkDelegate sync_filter_network_delegate( + std::make_unique<TestNetworkDelegate>()); + sync_filter_network_delegate.SetCookieFilter("CookieBlockedOnCanGetCookie"); + sync_context.set_network_delegate(&sync_filter_network_delegate); + TestDelegate sync_delegate; + + // Add a secure cookie so we can try to set an insecure cookie and have + // SetCanonicalCookie (and therefore SetCookieWithOptions) fail. + GURL::Replacements replace_scheme; + replace_scheme.SetSchemeStr("https"); + GURL url = test_server.base_url().ReplaceComponents(replace_scheme); + + delayed_cm->SetCookieWithOptionsAsync(url, "AlreadySetCookie=1;Secure", + CookieOptions(), + CookieStore::SetCookiesCallback()); + cm->SetCookieWithOptionsAsync(url, "AlreadySetCookie=1;Secure", + CookieOptions(), + CookieStore::SetCookiesCallback()); + + std::vector<std::string> cookie_lines( + {// Fails on CanonicalCookie::Create for trying to create a secure cookie + // on an insecure host. + "CookieNotSet=1;Secure", + // Fail in FilteringTestLayeredNetworkDelegate::CanGetCookie. + "CookieBlockedOnCanGetCookie=1", + // Fails in SetCanonicalCookie for trying to overwrite a secure cookie + // with an insecure cookie. + "AlreadySetCookie=1", + // Succeeds and added cookie to store. Delayed (which makes the callback + // run asynchronously) in DelayedCookieMonster. + "CookieSet=1"}); + + for (auto first_cookie_line : cookie_lines) { + for (auto second_cookie_line : cookie_lines) { + // Run with the delayed cookie monster. + std::unique_ptr<URLRequest> request = async_context.CreateRequest( + test_server.GetURL("/set-cookie?" + first_cookie_line + "&" + + second_cookie_line), + DEFAULT_PRIORITY, &async_delegate, TRAFFIC_ANNOTATION_FOR_TESTS); + + request->Start(); + async_delegate.RunUntilComplete(); + EXPECT_THAT(async_delegate.request_status(), IsOk()); + + // Run with the regular cookie monster. + request = sync_context.CreateRequest( + test_server.GetURL("/set-cookie?" + first_cookie_line + "&" + + second_cookie_line), + DEFAULT_PRIORITY, &sync_delegate, TRAFFIC_ANNOTATION_FOR_TESTS); + + request->Start(); + sync_delegate.RunUntilComplete(); + EXPECT_THAT(sync_delegate.request_status(), IsOk()); + + int expected_set_cookie_count = 0; + int expected_blocked_cookie_count = 0; + + if (first_cookie_line != "CookieNotSet=1;Secure") + ++expected_set_cookie_count; + if (second_cookie_line != "CookieNotSet=1;Secure") + ++expected_set_cookie_count; + + if (first_cookie_line == "CookieBlockedOnCanGetCookie=1") + ++expected_blocked_cookie_count; + if (second_cookie_line == "CookieBlockedOnCanGetCookie=1") + ++expected_blocked_cookie_count; + + EXPECT_EQ(expected_set_cookie_count, + async_filter_network_delegate.set_cookie_called_count()); + EXPECT_EQ(expected_blocked_cookie_count, + async_filter_network_delegate.blocked_set_cookie_count()); + + EXPECT_EQ(expected_set_cookie_count, + sync_filter_network_delegate.set_cookie_called_count()); + EXPECT_EQ(expected_blocked_cookie_count, + sync_filter_network_delegate.blocked_set_cookie_count()); + + async_filter_network_delegate.ResetSetCookieCalledCount(); + async_filter_network_delegate.ResetBlockedSetCookieCount(); + + sync_filter_network_delegate.ResetSetCookieCalledCount(); + sync_filter_network_delegate.ResetBlockedSetCookieCount(); + } + } +} + TEST_F(URLRequestTest, DoNotSendCookies) { HttpTestServer test_server; ASSERT_TRUE(test_server.Start()); @@ -8137,6 +8286,39 @@ } } +TEST_F(URLRequestTestHTTP, AuthChallengeWithFilteredCookie) { + ASSERT_TRUE(http_test_server()->Start()); + + GURL url_requiring_auth = http_test_server()->GetURL( + "/auth-basic?set-cookie-if-not-challenged&set-cookie-if-challenged"); + + FilteringTestLayeredNetworkDelegate filtering_network_delegate( + std::make_unique<TestNetworkDelegate>()); // Must outlive URLRequest. + filtering_network_delegate.SetCookieFilter( + "got_challenged"); // Filter the cookie auth-basic sets + TestURLRequestContext context(true); + context.set_network_delegate(&filtering_network_delegate); + context.Init(); + + TestDelegate delegate; + + delegate.set_credentials(AuthCredentials(kUser, kSecret)); + + std::unique_ptr<URLRequest> request( + context.CreateRequest(url_requiring_auth, DEFAULT_PRIORITY, &delegate, + TRAFFIC_ANNOTATION_FOR_TESTS)); + request->Start(); + + delegate.RunUntilComplete(); + EXPECT_THAT(delegate.request_status(), IsOk()); + + // Make sure the cookie was actually filtered. + EXPECT_EQ(std::string::npos, + delegate.data_received().find("Cookie: got_challenged=true")); + // Make sure it was blocked twice. + EXPECT_EQ(2, filtering_network_delegate.blocked_set_cookie_count()); +} + // Tests that load timing works as expected with auth and the cache. TEST_F(URLRequestTestHTTP, BasicAuthLoadTiming) { ASSERT_TRUE(http_test_server()->Start());
diff --git a/services/audio/input_controller.cc b/services/audio/input_controller.cc index 9f6f0c49..3657131a 100644 --- a/services/audio/input_controller.cc +++ b/services/audio/input_controller.cc
@@ -803,7 +803,6 @@ void InputController::UpdateVolumeAndAPMStats( base::Optional<double> new_volume) { DCHECK_CALLED_ON_VALID_THREAD(owning_thread_); - processing_helper_->GetAudioProcessor()->UpdateInternalStats(); if (new_volume) SetVolume(*new_volume); }
diff --git a/services/identity/DEPS b/services/identity/DEPS index d0fada9e..9eb4337 100644 --- a/services/identity/DEPS +++ b/services/identity/DEPS
@@ -3,7 +3,7 @@ "+components/signin/core/browser/account_info.h", "+components/signin/core/browser/account_tracker_service.h", "+components/signin/core/browser/device_id_helper.h", - "+components/signin/core/browser/fake_account_fetcher_service.h", + "+components/signin/core/browser/test_image_decoder.h", "+components/signin/core/browser/fake_profile_oauth2_token_service.h", "+components/signin/core/browser/fake_signin_manager.h", "+components/signin/core/browser/profile_oauth2_token_service.h",
diff --git a/services/identity/identity_accessor_impl.cc b/services/identity/identity_accessor_impl.cc index d6faa858..659d095 100644 --- a/services/identity/identity_accessor_impl.cc +++ b/services/identity/identity_accessor_impl.cc
@@ -35,18 +35,11 @@ GoogleServiceAuthError error, AccessTokenInfo access_token_info) { if (error.state() == GoogleServiceAuthError::NONE) { - OnRequestCompleted(access_token_info.token, - access_token_info.expiration_time, error); + std::move(consumer_callback_) + .Run(access_token_info.token, access_token_info.expiration_time, error); } else { - OnRequestCompleted(base::nullopt, base::Time(), error); + std::move(consumer_callback_).Run(base::nullopt, base::Time(), error); } -} - -void IdentityAccessorImpl::AccessTokenRequest::OnRequestCompleted( - const base::Optional<std::string>& access_token, - base::Time expiration_time, - const GoogleServiceAuthError& error) { - std::move(consumer_callback_).Run(access_token, expiration_time, error); // Causes |this| to be deleted. manager_->AccessTokenRequestCompleted(this);
diff --git a/services/identity/identity_accessor_impl.h b/services/identity/identity_accessor_impl.h index b5ca967..9a41e62 100644 --- a/services/identity/identity_accessor_impl.h +++ b/services/identity/identity_accessor_impl.h
@@ -46,14 +46,10 @@ private: // Invoked after access token request completes (successful or not). + // Completes the pending access token request by calling back the consumer. void OnTokenRequestCompleted(GoogleServiceAuthError error, AccessTokenInfo access_token_info); - // Completes the pending access token request by calling back the consumer. - void OnRequestCompleted(const base::Optional<std::string>& access_token, - base::Time expiration_time, - const GoogleServiceAuthError& error); - std::unique_ptr<AccessTokenFetcher> access_token_fetcher_; GetAccessTokenCallback consumer_callback_; IdentityAccessorImpl* manager_;
diff --git a/services/identity/identity_accessor_impl_unittest.cc b/services/identity/identity_accessor_impl_unittest.cc index 0a70b55..f18ac111 100644 --- a/services/identity/identity_accessor_impl_unittest.cc +++ b/services/identity/identity_accessor_impl_unittest.cc
@@ -8,9 +8,9 @@ #include "build/build_config.h" #include "components/signin/core/browser/account_info.h" #include "components/signin/core/browser/account_tracker_service.h" -#include "components/signin/core/browser/fake_account_fetcher_service.h" #include "components/signin/core/browser/fake_profile_oauth2_token_service.h" #include "components/signin/core/browser/signin_manager.h" +#include "components/signin/core/browser/test_image_decoder.h" #include "components/signin/core/browser/test_signin_client.h" #include "components/sync_preferences/testing_pref_service_syncable.h" #include "services/identity/identity_service.h" @@ -28,7 +28,6 @@ const char kTestGaiaId[] = "gaia_id_for_me_dummy.com"; const char kTestEmail[] = "me@dummy.com"; -const char kTestRefreshToken[] = "dummy-refresh-token"; const char kTestAccessToken[] = "access_token"; class IdentityAccessorImplTest : public testing::Test { @@ -75,14 +74,13 @@ account_fetcher_.Initialize(&signin_client_, &token_service_, &account_tracker_, std::make_unique<TestImageDecoder>()); + signin_manager_.Initialize(&pref_service_); } ~IdentityAccessorImplTest() override { - token_service_.Shutdown(); - signin_client_.Shutdown(); - account_tracker_.Shutdown(); - gaia_cookie_manager_service_.Shutdown(); + signin_manager_.Shutdown(); account_fetcher_.Shutdown(); + account_tracker_.Shutdown(); } void TearDown() override { @@ -181,7 +179,7 @@ private: sync_preferences::TestingPrefServiceSyncable pref_service_; AccountTrackerService account_tracker_; - FakeAccountFetcherService account_fetcher_; + AccountFetcherService account_fetcher_; TestSigninClient signin_client_; FakeProfileOAuth2TokenService token_service_; #if defined(OS_CHROMEOS) @@ -211,17 +209,17 @@ // Check that the primary account info has expected values if signed in without // a refresh token available. TEST_F(IdentityAccessorImplTest, GetPrimaryAccountInfoSignedInNoRefreshToken) { - identity_test_environment()->SetPrimaryAccount(kTestEmail); - IdentityManager* identity_manager = - identity_test_environment()->identity_manager(); + std::string primary_account_id = + identity_test_environment()->SetPrimaryAccount(kTestEmail).account_id; + base::RunLoop run_loop; GetIdentityAccessorImpl()->GetPrimaryAccountInfo(base::BindRepeating( &IdentityAccessorImplTest::OnReceivedPrimaryAccountInfo, base::Unretained(this), run_loop.QuitClosure())); run_loop.Run(); + EXPECT_TRUE(primary_account_info_); - EXPECT_EQ(identity_manager->GetPrimaryAccountId(), - primary_account_info_->account_id); + EXPECT_EQ(primary_account_id, primary_account_info_->account_id); EXPECT_EQ(kTestGaiaId, primary_account_info_->gaia); EXPECT_EQ(kTestEmail, primary_account_info_->email); EXPECT_FALSE(primary_account_state_.has_refresh_token); @@ -231,19 +229,18 @@ // Check that the primary account info has expected values if signed in with a // refresh token available. TEST_F(IdentityAccessorImplTest, GetPrimaryAccountInfoSignedInRefreshToken) { - identity_test_environment()->SetPrimaryAccount(kTestEmail); - IdentityManager* identity_manager = - identity_test_environment()->identity_manager(); - token_service()->UpdateCredentials(identity_manager->GetPrimaryAccountId(), - kTestRefreshToken); + std::string primary_account_id = identity_test_environment() + ->MakePrimaryAccountAvailable(kTestEmail) + .account_id; + base::RunLoop run_loop; GetIdentityAccessorImpl()->GetPrimaryAccountInfo(base::BindRepeating( &IdentityAccessorImplTest::OnReceivedPrimaryAccountInfo, base::Unretained(this), run_loop.QuitClosure())); run_loop.Run(); + EXPECT_TRUE(primary_account_info_); - EXPECT_EQ(identity_manager->GetPrimaryAccountId(), - primary_account_info_->account_id); + EXPECT_EQ(primary_account_id, primary_account_info_->account_id); EXPECT_EQ(kTestGaiaId, primary_account_info_->gaia); EXPECT_EQ(kTestEmail, primary_account_info_->email); EXPECT_TRUE(primary_account_state_.has_refresh_token); @@ -253,11 +250,9 @@ // Check that GetPrimaryAccountWhenAvailable() returns immediately in the // case where the primary account is available when the call is received. TEST_F(IdentityAccessorImplTest, GetPrimaryAccountWhenAvailableSignedIn) { - identity_test_environment()->SetPrimaryAccount(kTestEmail); - IdentityManager* identity_manager = - identity_test_environment()->identity_manager(); - token_service()->UpdateCredentials(identity_manager->GetPrimaryAccountId(), - kTestRefreshToken); + std::string primary_account_id = identity_test_environment() + ->MakePrimaryAccountAvailable(kTestEmail) + .account_id; AccountInfo account_info; AccountState account_state; @@ -268,7 +263,7 @@ base::Unretained(&account_info), base::Unretained(&account_state))); run_loop.Run(); - EXPECT_EQ(identity_manager->GetPrimaryAccountId(), account_info.account_id); + EXPECT_EQ(primary_account_id, account_info.account_id); EXPECT_EQ(kTestGaiaId, account_info.gaia); EXPECT_EQ(kTestEmail, account_info.email); EXPECT_TRUE(account_state.has_refresh_token); @@ -298,17 +293,14 @@ run_loop2.Run(); EXPECT_FALSE(primary_account_info_); - IdentityManager* identity_manager = - identity_test_environment()->identity_manager(); - // Make the primary account available and check that the callback is invoked // as expected. - identity_test_environment()->SetPrimaryAccount(kTestEmail); - token_service()->UpdateCredentials(identity_manager->GetPrimaryAccountId(), - kTestRefreshToken); + std::string primary_account_id = identity_test_environment() + ->MakePrimaryAccountAvailable(kTestEmail) + .account_id; run_loop.Run(); - EXPECT_EQ(identity_manager->GetPrimaryAccountId(), account_info.account_id); + EXPECT_EQ(primary_account_id, account_info.account_id); EXPECT_EQ(kTestGaiaId, account_info.gaia); EXPECT_EQ(kTestEmail, account_info.email); EXPECT_TRUE(account_state.has_refresh_token); @@ -324,7 +316,8 @@ AccountState account_state; // Sign in, but don't set the refresh token yet. - identity_test_environment()->SetPrimaryAccount(kTestEmail); + std::string primary_account_id = + identity_test_environment()->SetPrimaryAccount(kTestEmail).account_id; base::RunLoop run_loop; GetIdentityAccessorImpl()->GetPrimaryAccountWhenAvailable(base::BindRepeating( &IdentityAccessorImplTest::OnPrimaryAccountAvailable, @@ -341,21 +334,16 @@ base::Unretained(this), run_loop2.QuitClosure())); run_loop2.Run(); - IdentityManager* identity_manager = - identity_test_environment()->identity_manager(); - EXPECT_TRUE(primary_account_info_); - EXPECT_EQ(identity_manager->GetPrimaryAccountId(), - primary_account_info_->account_id); + EXPECT_EQ(primary_account_id, primary_account_info_->account_id); EXPECT_TRUE(account_info.account_id.empty()); // Set the refresh token and check that the callback is invoked as expected // (i.e., the primary account is now considered available). - token_service()->UpdateCredentials(identity_manager->GetPrimaryAccountId(), - kTestRefreshToken); + identity_test_environment()->SetRefreshTokenForPrimaryAccount(); run_loop.Run(); - EXPECT_EQ(identity_manager->GetPrimaryAccountId(), account_info.account_id); + EXPECT_EQ(primary_account_id, account_info.account_id); EXPECT_EQ(kTestGaiaId, account_info.gaia); EXPECT_EQ(kTestEmail, account_info.email); EXPECT_TRUE(account_state.has_refresh_token); @@ -376,7 +364,7 @@ // Set the refresh token, but don't sign in yet. std::string account_id_to_use = account_tracker()->SeedAccountInfo(kTestGaiaId, kTestEmail); - token_service()->UpdateCredentials(account_id_to_use, kTestRefreshToken); + identity_test_environment()->SetRefreshTokenForAccount(account_id_to_use); base::RunLoop run_loop; GetIdentityAccessorImpl()->GetPrimaryAccountWhenAvailable(base::BindRepeating( &IdentityAccessorImplTest::OnPrimaryAccountAvailable, @@ -406,14 +394,12 @@ // Sign the user in and check that the callback is invoked as expected (i.e., // the primary account is now considered available). - identity_test_environment()->SetPrimaryAccount(kTestEmail); + std::string primary_account_id = + identity_test_environment()->SetPrimaryAccount(kTestEmail).account_id; run_loop.Run(); - IdentityManager* identity_manager = - identity_test_environment()->identity_manager(); - - EXPECT_EQ(identity_manager->GetPrimaryAccountId(), account_info.account_id); + EXPECT_EQ(primary_account_id, account_info.account_id); EXPECT_EQ(kTestGaiaId, account_info.gaia); EXPECT_EQ(kTestEmail, account_info.email); EXPECT_TRUE(account_state.has_refresh_token); @@ -452,24 +438,22 @@ run_loop3.Run(); EXPECT_FALSE(primary_account_info_); - IdentityManager* identity_manager = - identity_test_environment()->identity_manager(); - // Make the primary account available and check that the callbacks are invoked // as expected. - identity_test_environment()->SetPrimaryAccount(kTestEmail); - token_service()->UpdateCredentials(identity_manager->GetPrimaryAccountId(), - kTestRefreshToken); + std::string primary_account_id = identity_test_environment() + ->MakePrimaryAccountAvailable(kTestEmail) + .account_id; + run_loop.Run(); run_loop2.Run(); - EXPECT_EQ(identity_manager->GetPrimaryAccountId(), account_info1.account_id); + EXPECT_EQ(primary_account_id, account_info1.account_id); EXPECT_EQ(kTestGaiaId, account_info1.gaia); EXPECT_EQ(kTestEmail, account_info1.email); EXPECT_TRUE(account_state1.has_refresh_token); EXPECT_TRUE(account_state1.is_primary_account); - EXPECT_EQ(identity_manager->GetPrimaryAccountId(), account_info2.account_id); + EXPECT_EQ(primary_account_id, account_info2.account_id); EXPECT_EQ(kTestGaiaId, account_info2.gaia); EXPECT_EQ(kTestEmail, account_info2.email); EXPECT_TRUE(account_state2.has_refresh_token); @@ -480,15 +464,12 @@ // available if the refresh token has an auth error. TEST_F(IdentityAccessorImplTest, GetPrimaryAccountWhenAvailableRefreshTokenHasAuthError) { - IdentityManager* identity_manager = - identity_test_environment()->identity_manager(); - identity_test_environment()->SetPrimaryAccount(kTestEmail); - token_service()->UpdateCredentials(identity_manager->GetPrimaryAccountId(), - kTestRefreshToken); - token_service()->UpdateAuthErrorForTesting( - identity_manager->GetPrimaryAccountId(), - GoogleServiceAuthError( - GoogleServiceAuthError::State::INVALID_GAIA_CREDENTIALS)); + std::string primary_account_id = identity_test_environment() + ->MakePrimaryAccountAvailable(kTestEmail) + .account_id; + identity_test_environment()->UpdatePersistentErrorOfRefreshTokenForAccount( + primary_account_id, + GoogleServiceAuthError(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)); AccountInfo account_info; AccountState account_state; @@ -504,13 +485,12 @@ // Clear the auth error, update credentials, and check that the callback // fires. - token_service()->UpdateAuthErrorForTesting( - identity_manager->GetPrimaryAccountId(), GoogleServiceAuthError()); - token_service()->UpdateCredentials(identity_manager->GetPrimaryAccountId(), - kTestRefreshToken); + identity_test_environment()->UpdatePersistentErrorOfRefreshTokenForAccount( + primary_account_id, GoogleServiceAuthError()); + identity_test_environment()->SetRefreshTokenForPrimaryAccount(); run_loop.Run(); - EXPECT_EQ(identity_manager->GetPrimaryAccountId(), account_info.account_id); + EXPECT_EQ(primary_account_id, account_info.account_id); EXPECT_EQ(kTestGaiaId, account_info.gaia); EXPECT_EQ(kTestEmail, account_info.email); EXPECT_TRUE(account_state.has_refresh_token); @@ -555,7 +535,8 @@ TEST_F(IdentityAccessorImplTest, GetAccountInfoForKnownGaiaIdRefreshToken) { std::string account_id = account_tracker()->SeedAccountInfo(kTestGaiaId, kTestEmail); - token_service()->UpdateCredentials(account_id, kTestRefreshToken); + identity_test_environment()->SetRefreshTokenForAccount(account_id); + base::RunLoop run_loop; GetIdentityAccessorImpl()->GetAccountInfoFromGaiaId( kTestGaiaId, @@ -588,19 +569,19 @@ // Check that the expected access token is received if requesting an access // token when signed in. TEST_F(IdentityAccessorImplTest, GetAccessTokenSignedIn) { - IdentityManager* identity_manager = - identity_test_environment()->identity_manager(); - identity_test_environment()->SetPrimaryAccount(kTestEmail); - std::string account_id = identity_manager->GetPrimaryAccountId(); - token_service()->UpdateCredentials(account_id, kTestRefreshToken); - token_service()->set_auto_post_fetch_response_on_message_loop(true); + std::string primary_account_id = identity_test_environment() + ->MakePrimaryAccountAvailable(kTestEmail) + .account_id; base::RunLoop run_loop; - GetIdentityAccessorImpl()->GetAccessToken( - account_id, ScopeSet(), "dummy_consumer", + primary_account_id, ScopeSet(), "dummy_consumer", base::BindRepeating(&IdentityAccessorImplTest::OnReceivedAccessToken, base::Unretained(this), run_loop.QuitClosure())); + identity_test_environment() + ->WaitForAccessTokenRequestIfNecessaryAndRespondWithToken( + kTestAccessToken, base::Time::Max()); run_loop.Run(); + EXPECT_TRUE(access_token_); EXPECT_EQ(kTestAccessToken, access_token_.value()); EXPECT_EQ(GoogleServiceAuthError::State::NONE, access_token_error_.state());
diff --git a/services/identity/public/cpp/DEPS b/services/identity/public/cpp/DEPS index 8f047c21..5f3ccaf 100644 --- a/services/identity/public/cpp/DEPS +++ b/services/identity/public/cpp/DEPS
@@ -4,7 +4,7 @@ "+components/signin/core/browser/account_fetcher_service.h", "+components/signin/core/browser/account_info.h", "+components/signin/core/browser/child_account_info_fetcher_android.h", - "+components/signin/core/browser/fake_account_fetcher_service.h", + "+components/signin/core/browser/test_image_decoder.h", "+components/signin/core/browser/gaia_cookie_manager_service.h", "+components/signin/core/browser/list_accounts_test_utils.h", "+components/signin/core/browser/oauth2_token_service_delegate_android.h",
diff --git a/services/identity/public/cpp/identity_manager.cc b/services/identity/public/cpp/identity_manager.cc index 7403d91..f6a76448c 100644 --- a/services/identity/public/cpp/identity_manager.cc +++ b/services/identity/public/cpp/identity_manager.cc
@@ -149,11 +149,6 @@ if (!HasAccountWithRefreshToken(extended_account_info.account_id)) return base::nullopt; - // If the extended information is not available, AccountInfo::IsValid() will - // return false. If this is the case, return base::nullopt. - if (!extended_account_info.IsValid()) - return base::nullopt; - return GetAccountInfoForAccountWithRefreshToken(account_info.account_id); }
diff --git a/services/identity/public/cpp/identity_manager_unittest.cc b/services/identity/public/cpp/identity_manager_unittest.cc index 469d187..c74f6b67 100644 --- a/services/identity/public/cpp/identity_manager_unittest.cc +++ b/services/identity/public/cpp/identity_manager_unittest.cc
@@ -18,11 +18,11 @@ #include "build/build_config.h" #include "components/signin/core/browser/account_consistency_method.h" #include "components/signin/core/browser/account_tracker_service.h" -#include "components/signin/core/browser/fake_account_fetcher_service.h" #include "components/signin/core/browser/fake_profile_oauth2_token_service.h" #include "components/signin/core/browser/list_accounts_test_utils.h" #include "components/signin/core/browser/signin_manager.h" #include "components/signin/core/browser/signin_switches.h" +#include "components/signin/core/browser/test_image_decoder.h" #include "components/signin/core/browser/test_signin_client.h" #include "components/sync_preferences/testing_pref_service_syncable.h" #include "google_apis/gaia/google_service_auth_error.h" @@ -367,7 +367,7 @@ return identity_manager_diagnostics_observer_.get(); } AccountTrackerServiceForTest* account_tracker() { return &account_tracker_; } - FakeAccountFetcherService* account_fetcher() { return &account_fetcher_; } + AccountFetcherService* account_fetcher() { return &account_fetcher_; } SigninManagerBase* signin_manager() { return signin_manager_.get(); } CustomFakeProfileOAuth2TokenService* token_service() { return &token_service_; @@ -486,7 +486,7 @@ base::MessageLoop message_loop_; sync_preferences::TestingPrefServiceSyncable pref_service_; AccountTrackerServiceForTest account_tracker_; - FakeAccountFetcherService account_fetcher_; + AccountFetcherService account_fetcher_; TestSigninClient signin_client_; CustomFakeProfileOAuth2TokenService token_service_; network::TestURLLoaderFactory test_url_loader_factory_; @@ -2473,27 +2473,8 @@ SetRefreshTokenForAccount(identity_manager(), account_info.account_id, "refresh-token"); - // FindExtendedAccountInfoForAccount() returns empty optional if the account - // has not extended information. - EXPECT_FALSE(identity_manager() - ->FindExtendedAccountInfoForAccount(account_info) - .has_value()); - - // Populate the extended information of the account. - base::DictionaryValue user_info; - user_info.SetString("id", account_info.gaia); - user_info.SetString("email", account_info.email); - user_info.SetString("hd", "hosted_domain"); - user_info.SetString("name", "full_name"); - user_info.SetString("given_name", "given_name"); - user_info.SetString("locale", "locale"); - user_info.SetString("picture", "picture_url"); - account_tracker()->SetAccountInfoFromUserInfo(account_info.account_id, - &user_info); - // FindExtendedAccountInfoForAccount() returns extended account information if - // the account is know, has valid refresh token and has extended account - // information. + // the account is known and has valid refresh token. const base::Optional<AccountInfo> extended_account_info = identity_manager()->FindExtendedAccountInfoForAccount(account_info);
diff --git a/services/identity/public/cpp/identity_test_environment.cc b/services/identity/public/cpp/identity_test_environment.cc index 83e062e7..d2b1c93 100644 --- a/services/identity/public/cpp/identity_test_environment.cc +++ b/services/identity/public/cpp/identity_test_environment.cc
@@ -10,10 +10,10 @@ #include "base/run_loop.h" #include "base/threading/thread_task_runner_handle.h" #include "components/signin/core/browser/account_tracker_service.h" -#include "components/signin/core/browser/fake_account_fetcher_service.h" #include "components/signin/core/browser/fake_profile_oauth2_token_service.h" #include "components/signin/core/browser/gaia_cookie_manager_service.h" #include "components/signin/core/browser/signin_manager.h" +#include "components/signin/core/browser/test_image_decoder.h" #include "components/signin/core/browser/test_signin_client.h" #include "components/sync_preferences/testing_pref_service_syncable.h" #include "google_apis/gaia/oauth2_access_token_consumer.h" @@ -50,7 +50,7 @@ AccountTrackerService* account_tracker_service(); - FakeAccountFetcherService* account_fetcher_service(); + AccountFetcherService* account_fetcher_service(); SigninManagerBase* signin_manager(); @@ -73,7 +73,7 @@ TestSigninClient* raw_signin_client_ = nullptr; AccountTrackerService account_tracker_; - FakeAccountFetcherService account_fetcher_; + AccountFetcherService account_fetcher_; FakeProfileOAuth2TokenService token_service_; #if defined(OS_CHROMEOS) SigninManagerBase signin_manager_; @@ -148,7 +148,7 @@ return &account_tracker_; } -FakeAccountFetcherService* +AccountFetcherService* IdentityManagerDependenciesOwner::account_fetcher_service() { return &account_fetcher_; } @@ -205,7 +205,7 @@ IdentityTestEnvironment::IdentityTestEnvironment( PrefService* pref_service, AccountTrackerService* account_tracker_service, - FakeAccountFetcherService* account_fetcher_service, + AccountFetcherService* account_fetcher_service, FakeProfileOAuth2TokenService* token_service, SigninManagerBase* signin_manager, GaiaCookieManagerService* gaia_cookie_manager_service, @@ -223,7 +223,7 @@ IdentityTestEnvironment::IdentityTestEnvironment( PrefService* pref_service, AccountTrackerService* account_tracker_service, - FakeAccountFetcherService* account_fetcher_service, + AccountFetcherService* account_fetcher_service, FakeProfileOAuth2TokenService* token_service, SigninManagerBase* signin_manager, GaiaCookieManagerService* gaia_cookie_manager_service, @@ -242,7 +242,7 @@ IdentityTestEnvironment::IdentityTestEnvironment( PrefService* pref_service, AccountTrackerService* account_tracker_service, - FakeAccountFetcherService* account_fetcher_service, + AccountFetcherService* account_fetcher_service, FakeProfileOAuth2TokenService* token_service, SigninManagerBase* signin_manager, GaiaCookieManagerService* gaia_cookie_manager_service,
diff --git a/services/identity/public/cpp/identity_test_environment.h b/services/identity/public/cpp/identity_test_environment.h index e00a9de..9a392095 100644 --- a/services/identity/public/cpp/identity_test_environment.h +++ b/services/identity/public/cpp/identity_test_environment.h
@@ -10,8 +10,8 @@ #include "services/identity/public/cpp/identity_manager.h" #include "services/identity/public/cpp/identity_test_utils.h" +class AccountFetcherService; class AccountTrackerService; -class FakeAccountFetcherService; class FakeProfileOAuth2TokenService; class GaiaCookieManagerService; class IdentityTestEnvironmentChromeBrowserStateAdaptor; @@ -303,7 +303,7 @@ IdentityTestEnvironment( PrefService* pref_service, AccountTrackerService* account_tracker_service, - FakeAccountFetcherService* account_fetcher_service, + AccountFetcherService* account_fetcher_service, FakeProfileOAuth2TokenService* token_service, SigninManagerBase* signin_manager, GaiaCookieManagerService* gaia_cookie_manager_service, @@ -327,7 +327,7 @@ IdentityTestEnvironment( PrefService* pref_service, AccountTrackerService* account_tracker_service, - FakeAccountFetcherService* account_fetcher_service, + AccountFetcherService* account_fetcher_service, FakeProfileOAuth2TokenService* token_service, SigninManagerBase* signin_manager, GaiaCookieManagerService* gaia_cookie_manager_service, @@ -348,7 +348,7 @@ IdentityTestEnvironment( PrefService* pref_service, AccountTrackerService* account_tracker_service, - FakeAccountFetcherService* account_fetcher_service, + AccountFetcherService* account_fetcher_service, FakeProfileOAuth2TokenService* token_service, SigninManagerBase* signin_manager, GaiaCookieManagerService* gaia_cookie_manager_service, @@ -380,7 +380,7 @@ std::unique_ptr<IdentityManagerDependenciesOwner> dependencies_owner_; PrefService* pref_service_ = nullptr; AccountTrackerService* account_tracker_service_ = nullptr; - FakeAccountFetcherService* account_fetcher_service_ = nullptr; + AccountFetcherService* account_fetcher_service_ = nullptr; FakeProfileOAuth2TokenService* token_service_ = nullptr; SigninManagerBase* signin_manager_ = nullptr; GaiaCookieManagerService* gaia_cookie_manager_service_ = nullptr;
diff --git a/services/metrics/ukm_api.md b/services/metrics/ukm_api.md index 61f058d..a50adbe 100644 --- a/services/metrics/ukm_api.md +++ b/services/metrics/ukm_api.md
@@ -64,10 +64,8 @@ for the values which are 1, 5, 10, 25, 50, 75, 90, 95, and 99%ile. * `<enumeration/>`: Calculates the proportions of all values individually. The proportions indicate the relative frequency of each bucket and are - calculated independently for each metric over each aggregation. The - proportions will sum to 1.0 for an enumeration that emits only one result - per page-load if it emits anything at all. An enumeration emitted more than - once on a page will result in proportions that total greater than 1.0. + calculated independently for each metric over each aggregation. (Details + below.) There can also be one or more `index` tags which define additional aggregation keys. These are a comma-separated list of keys that is appended to the standard @@ -83,6 +81,42 @@ * `profile.country` * `profile.form_factor` +## Enumeration Proportions + +Porportions are calculated against the number of "page loads" (meaning per +"source" which is usually but not always the same as a browser page load) that +emitted one or more values for the enumeration. The proportions will sum to 1.0 +for an enumeration that emits only one result per page-load if it emits anything +at all. An enumeration emitted more than once per source will result in +proportions that total greater than 1.0 but are still relative to the total +number of loads. + +For example, `Security.SiteEngagement` emits one value (either 4 or 2) per source: + +* https://www.google.com/ : 4 +* https://www.facebook.com/ : 2 +* https://www.wikipedia.com/ : 4 + +A proportion calculated over all sources would sum to 1.0: + +* 2 (0.3333) +* 4 (0.6667) + +In contrast, `Blink.UseCounter.Feature` emits multiple values per source: + +* https://www.google.com/ : 1, 2, 4, 6 +* https://www.facebook.com/ : 2, 4, 5 +* https://www.wikipedia.com/ : 1, 2, 4 + +A proportion calculated over all sources would be: + +* 1 (0.6667) +* 2 (1.0000) +* 3 (absent) +* 4 (1.0000) +* 5 (0.3333) +* 6 (0.3333) + ## Get UkmRecorder instance In order to record UKM events, your code needs a UkmRecorder object, defined by [//services/metrics/public/cpp/ukm_recorder.h](https://cs.chromium.org/chromium/src/services/metrics/public/cpp/ukm_recorder.h)
diff --git a/services/resource_coordinator/memory_instrumentation/queued_request_dispatcher.cc b/services/resource_coordinator/memory_instrumentation/queued_request_dispatcher.cc index 991bef52..f0e74f69 100644 --- a/services/resource_coordinator/memory_instrumentation/queued_request_dispatcher.cc +++ b/services/resource_coordinator/memory_instrumentation/queued_request_dispatcher.cc
@@ -9,6 +9,7 @@ #include "base/android/library_loader/anchor_functions_buildflags.h" #include "base/bind.h" #include "base/command_line.h" +#include "base/format_macros.h" #include "base/logging.h" #include "base/metrics/histogram_macros.h" #include "base/process/process_metrics.h" @@ -71,6 +72,30 @@ } #if BUILDFLAG(SUPPORTS_CODE_ORDERING) +void LogNativeCodeResidentPages(const std::set<size_t>& accessed_pages_set) { + // |SUPPORTS_CODE_ORDERING| can only be enabled on Android. + const auto kResidentPagesPath = base::FilePath( + "/data/local/tmp/chrome/native-library-resident-pages.txt"); + + auto file = base::File(kResidentPagesPath, base::File::FLAG_CREATE_ALWAYS | + base::File::FLAG_WRITE); + + if (!file.IsValid()) { + DLOG(ERROR) << "Could not open " << kResidentPagesPath; + return; + } + + for (size_t page : accessed_pages_set) { + std::string page_str = base::StringPrintf("%" PRIuS "\n", page); + + if (file.WriteAtCurrentPos(page_str.c_str(), + static_cast<int>(page_str.size())) < 0) { + DLOG(WARNING) << "Error while dumping Resident pages"; + return; + } + } +} + size_t ReportGlobalNativeCodeResidentMemoryKb( const std::map<base::ProcessId, mojom::RawOSMemDump*>& pid_to_pmd) { std::vector<uint8_t> common_map; @@ -99,6 +124,11 @@ } } + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + "log-native-library-residency")) { + LogNativeCodeResidentPages(accessed_pages_set); + } + const size_t kPageSize = base::GetPageSize(); return accessed_pages_set.size() * kPageSize / 1024; }
diff --git a/testing/buildbot/client.v8.fyi.json b/testing/buildbot/client.v8.fyi.json index bab8378..261eaa4 100644 --- a/testing/buildbot/client.v8.fyi.json +++ b/testing/buildbot/client.v8.fyi.json
@@ -1260,6 +1260,52 @@ "chrome_public_apk" ] }, + "V8 Blink Linux Layout NG": { + "gtest_tests": [ + { + "args": [ + "--enable-blink-features=LayoutNG" + ], + "name": "webkit_unit_tests_ng", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-14.04" + } + ], + "hard_timeout": 900 + }, + "test": "blink_unittests" + } + ], + "isolated_scripts": [ + { + "args": [ + "--num-retries=3" + ], + "isolate_name": "blink_web_tests_exparchive", + "merge": { + "args": [ + "--verbose" + ], + "script": "//third_party/blink/tools/merge_web_test_results.py" + }, + "name": "webkit_layout_tests", + "results_handler": "layout tests", + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Ubuntu-14.04" + } + ], + "hard_timeout": 900, + "shards": 12 + } + } + ] + }, "V8 Linux GN": { "additional_compile_targets": [ "accessibility_unittests",
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index ec7b579..ef96db4 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -3760,6 +3760,20 @@ 'chrome_public_apk' ], }, + 'V8 Blink Linux Layout NG': { + 'swarming': { + 'dimension_sets': [ + { + 'os': 'Ubuntu-14.04', + }, + ], + 'hard_timeout': 900, + }, + 'test_suites': { + 'gtest_tests': 'layout_ng_gtests', + 'isolated_scripts': 'chromium_webkit_isolated_scripts', + }, + }, 'V8 Linux GN': { 'additional_compile_targets': [ 'accessibility_unittests',
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 1f2bde62..889e9113 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -4364,25 +4364,6 @@ ] } ], - "ScheduledScriptStreaming": [ - { - "platforms": [ - "android", - "chromeos", - "linux", - "mac", - "windows" - ], - "experiments": [ - { - "name": "ScheduledScriptStreaming", - "enable_features": [ - "ScheduledScriptStreaming" - ] - } - ] - } - ], "SearchEnginePromo": [ { "platforms": [ @@ -5750,24 +5731,6 @@ ] } ], - "WebRtcUseEchoCanceller3": [ - { - "platforms": [ - "chromeos", - "linux", - "mac", - "windows" - ], - "experiments": [ - { - "name": "WebRtcUseEchoCanceller3", - "enable_features": [ - "WebRtcUseEchoCanceller3" - ] - } - ] - } - ], "WinOOPSelectFileDialog": [ { "platforms": [
diff --git a/third_party/blink/public/mojom/web_feature/web_feature.mojom b/third_party/blink/public/mojom/web_feature/web_feature.mojom index f7d014b..d217061 100644 --- a/third_party/blink/public/mojom/web_feature/web_feature.mojom +++ b/third_party/blink/public/mojom/web_feature/web_feature.mojom
@@ -2255,6 +2255,8 @@ kCSSValueAppearanceTextarea = 2821, kCSSValueAppearanceTextFieldForOthersRendered = 2822, kCSSValueAppearanceTextFieldForTemporalRendered = 2823, + kBuiltInModuleKvStorage = 2824, + kBuiltInModuleVirtualScroller = 2825, // Add new features immediately above this line. Don't change assigned // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/blink/public/platform/web_blob_info.h b/third_party/blink/public/platform/web_blob_info.h index 91fef04..0b67683 100644 --- a/third_party/blink/public/platform/web_blob_info.h +++ b/third_party/blink/public/platform/web_blob_info.h
@@ -16,17 +16,20 @@ class WebBlobInfo { public: - WebBlobInfo() : is_file_(false), size_(-1), last_modified_(0) {} + WebBlobInfo() + : is_file_(false), + size_(std::numeric_limits<uint64_t>::max()), + last_modified_(0) {} BLINK_EXPORT WebBlobInfo(const WebString& uuid, const WebString& type, - long long size, + uint64_t size, mojo::ScopedMessagePipeHandle); BLINK_EXPORT WebBlobInfo(const WebString& uuid, const WebString& file_path, const WebString& file_name, const WebString& type, double last_modified, - long long size, + uint64_t size, mojo::ScopedMessagePipeHandle); // For testing purposes, these two methods create a WebBlobInfo connected to a @@ -35,7 +38,7 @@ // be able to safely pass around these blobs. BLINK_EXPORT static WebBlobInfo BlobForTesting(const WebString& uuid, const WebString& type, - long long size); + uint64_t size); BLINK_EXPORT static WebBlobInfo FileForTesting(const WebString& uuid, const WebString& file_path, const WebString& file_name, @@ -49,7 +52,7 @@ bool IsFile() const { return is_file_; } const WebString& Uuid() const { return uuid_; } const WebString& GetType() const { return type_; } - long long size() const { return size_; } + uint64_t size() const { return size_; } const WebString& FilePath() const { return file_path_; } const WebString& FileName() const { return file_name_; } double LastModified() const { return last_modified_; } @@ -65,13 +68,13 @@ // BlobDataHandle always has the correct type and size. BLINK_EXPORT WebBlobInfo(scoped_refptr<BlobDataHandle>, const WebString& type, - long long size); + uint64_t size); BLINK_EXPORT WebBlobInfo(scoped_refptr<BlobDataHandle>, const WebString& file_path, const WebString& file_name, const WebString& type, double last_modified, - long long size); + uint64_t size); BLINK_EXPORT scoped_refptr<BlobDataHandle> GetBlobHandle() const; #endif @@ -79,7 +82,7 @@ bool is_file_; WebString uuid_; WebString type_; // MIME type - long long size_; + uint64_t size_; WebPrivatePtr<BlobDataHandle> blob_handle_; WebString file_path_; // Only for File WebString file_name_; // Only for File
diff --git a/third_party/blink/public/platform/web_runtime_features.h b/third_party/blink/public/platform/web_runtime_features.h index 43b85f53..a6be471 100644 --- a/third_party/blink/public/platform/web_runtime_features.h +++ b/third_party/blink/public/platform/web_runtime_features.h
@@ -148,6 +148,8 @@ BLINK_PLATFORM_EXPORT static void EnablePaymentRequest(bool); BLINK_PLATFORM_EXPORT static void EnablePaymentRequestHasEnrolledInstrument( bool); + BLINK_PLATFORM_EXPORT static void EnablePerformanceManagerInstrumentation( + bool); BLINK_PLATFORM_EXPORT static void EnablePermissionsAPI(bool); BLINK_PLATFORM_EXPORT static void EnablePictureInPicture(bool); BLINK_PLATFORM_EXPORT static void EnablePictureInPictureAPI(bool); @@ -219,7 +221,6 @@ BLINK_PLATFORM_EXPORT static void EnableMediaEngagementBypassAutoplayPolicies( bool); BLINK_PLATFORM_EXPORT static void EnableAutomationControlled(bool); - BLINK_PLATFORM_EXPORT static void EnableScheduledScriptStreaming(bool); BLINK_PLATFORM_EXPORT static void EnableScriptStreamingOnPreload(bool); BLINK_PLATFORM_EXPORT static void EnableExperimentalProductivityFeatures( bool);
diff --git a/third_party/blink/public/platform/web_thread_type.h b/third_party/blink/public/platform/web_thread_type.h index 7f0cf64..38ace6b 100644 --- a/third_party/blink/public/platform/web_thread_type.h +++ b/third_party/blink/public/platform/web_thread_type.h
@@ -21,7 +21,7 @@ kFileThread = 8, kDatabaseThread = 9, kWebAudioThread = 10, - kScriptStreamerThread = 11, + // 11 was kScriptStreamerThread, which was deleted kOfflineAudioRenderThread = 12, kReverbConvolutionBackgroundThread = 13, kHRTFDatabaseLoaderThread = 14,
diff --git a/third_party/blink/public/web/web_blob.h b/third_party/blink/public/web/web_blob.h index 886c6ad..195d38b4bd 100644 --- a/third_party/blink/public/web/web_blob.h +++ b/third_party/blink/public/web/web_blob.h
@@ -61,9 +61,9 @@ BLINK_EXPORT static WebBlob CreateFromUUID(const WebString& uuid, const WebString& type, - long long size); + uint64_t size); BLINK_EXPORT static WebBlob CreateFromFile(const WebString& path, - long long size); + uint64_t size); BLINK_EXPORT static WebBlob FromV8Value(v8::Local<v8::Value>); BLINK_EXPORT void Reset();
diff --git a/third_party/blink/renderer/bindings/bindings.gni b/third_party/blink/renderer/bindings/bindings.gni index 7dff426..ee2e9a5 100644 --- a/third_party/blink/renderer/bindings/bindings.gni +++ b/third_party/blink/renderer/bindings/bindings.gni
@@ -100,8 +100,6 @@ "core/v8/script_source_location_type.h", "core/v8/script_streamer.cc", "core/v8/script_streamer.h", - "core/v8/script_streamer_thread.cc", - "core/v8/script_streamer_thread.h", "core/v8/script_value.cc", "core/v8/script_value.h", "core/v8/serialization/post_message_helper.cc",
diff --git a/third_party/blink/renderer/bindings/core/v8/script_streamer.cc b/third_party/blink/renderer/bindings/core/v8/script_streamer.cc index e58b16d..6836cf1 100644 --- a/third_party/blink/renderer/bindings/core/v8/script_streamer.cc +++ b/third_party/blink/renderer/bindings/core/v8/script_streamer.cc
@@ -8,7 +8,6 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" -#include "third_party/blink/renderer/bindings/core/v8/script_streamer_thread.h" #include "third_party/blink/renderer/bindings/core/v8/v8_code_cache.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/element.h" @@ -352,21 +351,6 @@ streamer->StreamingCompleteOnBackgroundThread(); } -void RunBlockingScriptStreamingTask( - std::unique_ptr<v8::ScriptCompiler::ScriptStreamingTask> task, - ScriptStreamer* streamer, - std::atomic_flag* blocking_task_started_or_cancelled) { - if (blocking_task_started_or_cancelled->test_and_set()) - return; - RunScriptStreamingTask(std::move(task), streamer); -} - -void RunNonBlockingScriptStreamingTask( - std::unique_ptr<v8::ScriptCompiler::ScriptStreamingTask> task, - ScriptStreamer* streamer) { - RunScriptStreamingTask(std::move(task), streamer); -} - } // namespace bool ScriptStreamer::HasEnoughDataForStreaming(size_t resource_buffer_size) { @@ -415,16 +399,6 @@ } } - if (!RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled() && - ScriptStreamerThread::Shared()->IsRunningTask()) { - // If scheduled script streaming is disabled, we only have one thread for - // running the tasks. A new task shouldn't be queued before the running - // task completes, because the running task can block and wait for data - // from the network. - SuppressStreaming(kThreadBusy); - return; - } - DCHECK(!stream_); DCHECK(!source_); stream_ = new SourceStream; @@ -451,31 +425,16 @@ inspector_parse_script_event::Data(this->ScriptResourceIdentifier(), this->ScriptURLString())); - if (RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled()) { - // Script streaming tasks are high priority, as they can block the parser, - // and they can (and probably will) block during their own execution as - // they wait for more input. - // - // Pass through the atomic cancellation token which is set to true by the - // task when it is started, or set to true by the streamer if it wants to - // cancel the task. - // - // TODO(leszeks): Decrease the priority of these tasks where possible. - worker_pool::PostTaskWithTraits( - FROM_HERE, {base::TaskPriority::USER_BLOCKING, base::MayBlock()}, - CrossThreadBind(RunBlockingScriptStreamingTask, - WTF::Passed(std::move(script_streaming_task)), - WrapCrossThreadPersistent(this), - WTF::CrossThreadUnretained( - &blocking_task_started_or_cancelled_))); - } else { - blocking_task_started_or_cancelled_.test_and_set(); - ScriptStreamerThread::Shared()->PostTask( - CrossThreadBind(&ScriptStreamerThread::RunScriptStreamingTask, - WTF::Passed(std::move(script_streaming_task)), - WrapCrossThreadPersistent(this))); - } - + // Script streaming tasks are high priority, as they can block the parser, + // and they can (and probably will) block during their own execution as + // they wait for more input. + // + // TODO(leszeks): Decrease the priority of these tasks where possible. + worker_pool::PostTaskWithTraits( + FROM_HERE, {base::TaskPriority::USER_BLOCKING, base::MayBlock()}, + CrossThreadBind(RunScriptStreamingTask, + WTF::Passed(std::move(script_streaming_task)), + WrapCrossThreadPersistent(this))); } if (stream_) stream_->DidReceiveData(script_resource_, this); @@ -492,34 +451,7 @@ } if (stream_) { - // Mark the stream as finished loading before potentially re-posting the - // task to avoid a race between this finish and the task's first read. stream_->DidFinishLoading(); - - // If the corresponding blocking task hasn't started yet, cancel it and post - // a non-blocking task, since we know now that all the data is received and - // we will no longer block. - // - // TODO(874080): Remove this once blocking and non-blocking pools are - // merged. - if (RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled() && - !RuntimeEnabledFeatures::MergeBlockingNonBlockingPoolsEnabled() && - !blocking_task_started_or_cancelled_.test_and_set()) { - std::unique_ptr<v8::ScriptCompiler::ScriptStreamingTask> - script_streaming_task( - base::WrapUnique(v8::ScriptCompiler::StartStreamingScript( - V8PerIsolateData::MainThreadIsolate(), source_.get(), - compile_options_))); - - // The task creation shouldn't fail, since it didn't fail before during - // NotifyAppendData. - CHECK(script_streaming_task); - worker_pool::PostTaskWithTraits( - FROM_HERE, {base::TaskPriority::USER_BLOCKING}, - CrossThreadBind(RunNonBlockingScriptStreamingTask, - WTF::Passed(std::move(script_streaming_task)), - WrapCrossThreadPersistent(this))); - } } loading_finished_ = true;
diff --git a/third_party/blink/renderer/bindings/core/v8/script_streamer.h b/third_party/blink/renderer/bindings/core/v8/script_streamer.h index 32f97c0..a162366 100644 --- a/third_party/blink/renderer/bindings/core/v8/script_streamer.h +++ b/third_party/blink/renderer/bindings/core/v8/script_streamer.h
@@ -5,7 +5,6 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SCRIPT_STREAMER_H_ #define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SCRIPT_STREAMER_H_ -#include <atomic> #include <memory> #include "base/macros.h" @@ -41,8 +40,7 @@ kRevalidate, kContextNotValid, // DEPRECATED kEncodingNotSupported, - // TODO(leszeks): Deprecate once scheduled streaming is on by default - kThreadBusy, + kThreadBusy, // DEPRECATED kV8CannotStream, kScriptTooSmall, kNoResourceBuffer, @@ -155,11 +153,6 @@ // Whether we have received enough data to start the streaming. bool have_enough_data_for_streaming_; - // Flag used to allow atomic cancelling and reposting of the streaming task - // when the load completes without the task yet starting. - // TODO(874080): Remove this once blocking and non-blocking pools are merged. - std::atomic_flag blocking_task_started_or_cancelled_ = ATOMIC_FLAG_INIT; - // Whether the script source code should be retrieved from the Resource // instead of the ScriptStreamer. bool streaming_suppressed_;
diff --git a/third_party/blink/renderer/bindings/core/v8/script_streamer_test.cc b/third_party/blink/renderer/bindings/core/v8/script_streamer_test.cc index 8fd2036..dfd8165 100644 --- a/third_party/blink/renderer/bindings/core/v8/script_streamer_test.cc +++ b/third_party/blink/renderer/bindings/core/v8/script_streamer_test.cc
@@ -13,7 +13,6 @@ #include "third_party/blink/public/platform/web_url_loader_mock_factory.h" #include "third_party/blink/renderer/bindings/core/v8/referrer_script_info.h" #include "third_party/blink/renderer/bindings/core/v8/script_source_code.h" -#include "third_party/blink/renderer/bindings/core/v8/script_streamer_thread.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h" #include "third_party/blink/renderer/bindings/core/v8/v8_code_cache.h" @@ -29,6 +28,7 @@ #include "third_party/blink/renderer/platform/loader/fetch/resource_loader.h" #include "third_party/blink/renderer/platform/loader/fetch/script_fetch_options.h" #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" +#include "third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" #include "third_party/blink/renderer/platform/wtf/text/text_encoding.h" #include "v8/include/v8.h" @@ -40,7 +40,7 @@ class ScriptStreamingTest : public testing::Test { public: ScriptStreamingTest() - : loading_task_runner_(scheduler::GetSingleThreadTaskRunnerForTesting()), + : loading_task_runner_(platform_->test_task_runner()), dummy_page_holder_(DummyPageHolder::Create(IntSize(800, 600))) { dummy_page_holder_->GetPage().GetSettings().SetScriptEnabled(true); MockScriptElementBase* element = MockScriptElementBase::Create(); @@ -122,16 +122,10 @@ GetResource()->SetStatus(ResourceStatus::kCached); } - void ProcessTasksUntilStreamingComplete() { - if (!RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled()) { - while (ScriptStreamerThread::Shared()->IsRunningTask()) { - test::RunPendingTasks(); - } - } - // Once more, because the "streaming complete" notification might only - // now be in the task queue. - test::RunPendingTasks(); - } + void ProcessTasksUntilStreamingComplete() { platform_->RunUntilIdle(); } + + ScopedTestingPlatformSupport<TestingPlatformSupportWithMockScheduler> + platform_; scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner_; // The PendingScript where we stream from. These don't really
diff --git a/third_party/blink/renderer/bindings/core/v8/script_streamer_thread.cc b/third_party/blink/renderer/bindings/core/v8/script_streamer_thread.cc deleted file mode 100644 index e1b3c34c..0000000 --- a/third_party/blink/renderer/bindings/core/v8/script_streamer_thread.cc +++ /dev/null
@@ -1,90 +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 "third_party/blink/renderer/bindings/core/v8/script_streamer_thread.h" - -#include <memory> -#include "base/location.h" -#include "third_party/blink/public/platform/platform.h" -#include "third_party/blink/renderer/bindings/core/v8/script_streamer.h" -#include "third_party/blink/renderer/core/inspector/inspector_trace_events.h" -#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" -#include "third_party/blink/renderer/platform/runtime_enabled_features.h" -#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h" -#include "third_party/blink/renderer/platform/scheduler/public/thread.h" - -namespace blink { - -static ScriptStreamerThread* g_shared_thread = nullptr; -// Guards s_sharedThread. s_sharedThread is initialized and deleted in the main -// thread, but also used by the streamer thread. Races can occur during -// shutdown. -static Mutex* g_mutex = nullptr; - -void ScriptStreamerThread::Init() { - // Only enabled when ScheduledScriptStreaming is disabled. - if (!RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled()) { - DCHECK(!g_shared_thread); - DCHECK(IsMainThread()); - // This is called in the main thread before any tasks are created, so no - // locking is needed. - g_mutex = new Mutex(); - g_shared_thread = new ScriptStreamerThread(); - } -} - -ScriptStreamerThread* ScriptStreamerThread::Shared() { - DCHECK(!RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled()); - return g_shared_thread; -} - -void ScriptStreamerThread::PostTask(CrossThreadClosure task) { - DCHECK(!RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled()); - DCHECK(IsMainThread()); - MutexLocker locker(mutex_); - DCHECK(!running_task_); - running_task_ = true; - PostCrossThreadTask(*PlatformThread().GetTaskRunner(), FROM_HERE, - std::move(task)); -} - -void ScriptStreamerThread::TaskDone() { - MutexLocker locker(mutex_); - DCHECK(running_task_); - running_task_ = false; -} - -Thread& ScriptStreamerThread::PlatformThread() { - if (!IsRunning()) { - thread_ = Platform::Current()->CreateThread( - ThreadCreationParams(WebThreadType::kScriptStreamerThread)); - } - return *thread_; -} - -void ScriptStreamerThread::RunScriptStreamingTask( - std::unique_ptr<v8::ScriptCompiler::ScriptStreamingTask> task, - ScriptStreamer* streamer) { - DCHECK(!RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled()); - TRACE_EVENT1( - "v8,devtools.timeline", "v8.parseOnBackground", "data", - inspector_parse_script_event::Data(streamer->ScriptResourceIdentifier(), - streamer->ScriptURLString())); - TRACE_EVENT_WITH_FLOW1( - TRACE_DISABLED_BY_DEFAULT("v8.compile"), "v8.streamingCompile.run", - streamer, TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "data", - inspector_parse_script_event::Data(streamer->ScriptResourceIdentifier(), - streamer->ScriptURLString())); - // Running the task can and will block: SourceStream::GetSomeData will get - // called and it will block and wait for data from the network. - task->Run(); - streamer->StreamingCompleteOnBackgroundThread(); - MutexLocker locker(*g_mutex); - ScriptStreamerThread* thread = Shared(); - if (thread) - thread->TaskDone(); - // If thread is 0, we're shutting down. -} - -} // namespace blink
diff --git a/third_party/blink/renderer/bindings/core/v8/script_streamer_thread.h b/third_party/blink/renderer/bindings/core/v8/script_streamer_thread.h deleted file mode 100644 index 664df34e..0000000 --- a/third_party/blink/renderer/bindings/core/v8/script_streamer_thread.h +++ /dev/null
@@ -1,60 +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 THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SCRIPT_STREAMER_THREAD_H_ -#define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SCRIPT_STREAMER_THREAD_H_ - -#include <memory> - -#include "base/macros.h" -#include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/platform/scheduler/public/thread.h" -#include "third_party/blink/renderer/platform/wtf/functional.h" -#include "third_party/blink/renderer/platform/wtf/threading_primitives.h" -#include "v8/include/v8.h" - -namespace blink { - -class ScriptStreamer; - -// A singleton thread for running background tasks for script streaming. -class CORE_EXPORT ScriptStreamerThread { - USING_FAST_MALLOC(ScriptStreamerThread); - - public: - static void Init(); - static ScriptStreamerThread* Shared(); - - void PostTask(CrossThreadClosure); - - bool IsRunningTask() const { - MutexLocker locker(mutex_); - return running_task_; - } - - void TaskDone(); - - static void RunScriptStreamingTask( - std::unique_ptr<v8::ScriptCompiler::ScriptStreamingTask>, - ScriptStreamer*); - - private: - ScriptStreamerThread() : running_task_(false) {} - - bool IsRunning() const { return !!thread_; } - - Thread& PlatformThread(); - - // At the moment, we only use one thread, so we can only stream one script - // at a time. FIXME: Use a thread pool and stream multiple scripts. - std::unique_ptr<Thread> thread_; - bool running_task_ GUARDED_BY(mutex_); - mutable Mutex mutex_; - - DISALLOW_COPY_AND_ASSIGN(ScriptStreamerThread); -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SCRIPT_STREAMER_THREAD_H_
diff --git a/third_party/blink/renderer/build/scripts/core/css/properties/templates/style_builder_functions.tmpl b/third_party/blink/renderer/build/scripts/core/css/properties/templates/style_builder_functions.tmpl index 680cfe6d..e3f6ccb 100644 --- a/third_party/blink/renderer/build/scripts/core/css/properties/templates/style_builder_functions.tmpl +++ b/third_party/blink/renderer/build/scripts/core/css/properties/templates/style_builder_functions.tmpl
@@ -17,8 +17,7 @@ {% if property.style_builder_declare %} {% if property.style_builder_inline == header and property.style_builder_generate_initial %} {{declare_initial(property.name.to_upper_camel_case() if not header)|indent(spaces, true)}} { -{{caller(property)|indent(spaces, true)-}} -{{'}'|indent(spaces, true)}} +{{(caller(property) ~ '}')|indent(spaces, true)}} {% else %} {{declare_initial()|indent(spaces, true)-}}; {% endif %} @@ -30,8 +29,7 @@ {% if property.style_builder_declare %} {% if property.style_builder_inline == header and property.style_builder_generate_inherit %} {{declare_inherit(property.name.to_upper_camel_case() if not header)|indent(spaces, true)}} { -{{caller(property)|indent(spaces, true)-}} -{{'}'|indent(spaces, true)}} +{{(caller(property) ~ '}')|indent(spaces, true)}} {% else %} {{declare_inherit()|indent(spaces, true)-}}; {% endif %} @@ -43,8 +41,7 @@ {% if property.style_builder_declare %} {% if property.style_builder_inline == header and property.style_builder_generate_value %} {{declare_value(property.name.to_upper_camel_case() if not header)|indent(spaces, true)}} { -{{caller(property)|indent(spaces, true)-}} -{{'}'|indent(spaces, true)}} +{{(caller(property) ~ '}')|indent(spaces, true)}} {% else %} {{declare_value()|indent(spaces, true)-}}; {% endif %}
diff --git a/third_party/blink/renderer/controller/bloated_renderer_detector.cc b/third_party/blink/renderer/controller/bloated_renderer_detector.cc index 33792cd..58399c7 100644 --- a/third_party/blink/renderer/controller/bloated_renderer_detector.cc +++ b/third_party/blink/renderer/controller/bloated_renderer_detector.cc
@@ -32,7 +32,8 @@ } } last_detection_time_ = now; - RendererResourceCoordinator::Get().OnRendererIsBloated(); + if (auto* renderer_resource_coordinator = RendererResourceCoordinator::Get()) + renderer_resource_coordinator->OnRendererIsBloated(); return NearV8HeapLimitHandling::kForwardedToBrowser; }
diff --git a/third_party/blink/renderer/core/core_initializer.cc b/third_party/blink/renderer/core/core_initializer.cc index 4b2cc24..45a820c 100644 --- a/third_party/blink/renderer/core/core_initializer.cc +++ b/third_party/blink/renderer/core/core_initializer.cc
@@ -32,7 +32,6 @@ #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/renderer/bindings/core/v8/binding_security.h" -#include "third_party/blink/renderer/bindings/core/v8/script_streamer_thread.h" #include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h" #include "third_party/blink/renderer/core/css/media_feature_names.h" #include "third_party/blink/renderer/core/css/media_query_evaluator.h" @@ -147,7 +146,6 @@ V8ThrowDOMException::Init(); BindingSecurity::Init(); - ScriptStreamerThread::Init(); } } // namespace blink
diff --git a/third_party/blink/renderer/core/css/cssom/paint_worklet_input.cc b/third_party/blink/renderer/core/css/cssom/paint_worklet_input.cc index 8b029b0..3ae78f4 100644 --- a/third_party/blink/renderer/core/css/cssom/paint_worklet_input.cc +++ b/third_party/blink/renderer/core/css/cssom/paint_worklet_input.cc
@@ -10,19 +10,10 @@ const std::string& name, const FloatSize& container_size, float effective_zoom, - const Document& document, - const ComputedStyle& style, - Node* styled_node, - const Vector<CSSPropertyID>& native_properties, - const Vector<AtomicString>& custom_properties) + CrossThreadPersistent<PaintWorkletStylePropertyMap> style_map) : name_(name), container_size_(container_size), effective_zoom_(effective_zoom), - style_map_(MakeGarbageCollected<PaintWorkletStylePropertyMap>( - document, - style, - styled_node, - native_properties, - custom_properties)) {} + style_map_(style_map) {} } // namespace blink
diff --git a/third_party/blink/renderer/core/css/cssom/paint_worklet_input.h b/third_party/blink/renderer/core/css/cssom/paint_worklet_input.h index f3e53f2..ec820a8 100644 --- a/third_party/blink/renderer/core/css/cssom/paint_worklet_input.h +++ b/third_party/blink/renderer/core/css/cssom/paint_worklet_input.h
@@ -19,11 +19,7 @@ PaintWorkletInput(const std::string& name, const FloatSize& container_size, float effective_zoom, - const Document&, - const ComputedStyle&, - Node* styled_node, - const Vector<CSSPropertyID>& native_properties, - const Vector<AtomicString>& custom_properties); + CrossThreadPersistent<PaintWorkletStylePropertyMap>); ~PaintWorkletInput() override = default;
diff --git a/third_party/blink/renderer/core/css/cssom/paint_worklet_style_property_map_test.cc b/third_party/blink/renderer/core/css/cssom/paint_worklet_style_property_map_test.cc index 49b755f..dbb4a8f2 100644 --- a/third_party/blink/renderer/core/css/cssom/paint_worklet_style_property_map_test.cc +++ b/third_party/blink/renderer/core/css/cssom/paint_worklet_style_property_map_test.cc
@@ -236,10 +236,13 @@ UpdateAllLifecyclePhasesForTest(); Node* node = PageNode(); + CrossThreadPersistent<PaintWorkletStylePropertyMap> style_map = + MakeGarbageCollected<PaintWorkletStylePropertyMap>( + GetDocument(), node->ComputedStyleRef(), node, native_properties, + custom_properties); scoped_refptr<PaintWorkletInput> input = - base::MakeRefCounted<PaintWorkletInput>( - "test", FloatSize(100, 100), 1.0f, GetDocument(), - node->ComputedStyleRef(), node, native_properties, custom_properties); + base::MakeRefCounted<PaintWorkletInput>("test", FloatSize(100, 100), 1.0f, + style_map); DCHECK(input); thread_ = WebThreadSupportingGC::Create(
diff --git a/third_party/blink/renderer/core/css/resolver/style_adjuster.cc b/third_party/blink/renderer/core/css/resolver/style_adjuster.cc index 38baa0ac..a87e347c 100644 --- a/third_party/blink/renderer/core/css/resolver/style_adjuster.cc +++ b/third_party/blink/renderer/core/css/resolver/style_adjuster.cc
@@ -37,6 +37,7 @@ #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/element.h" #include "third_party/blink/renderer/core/dom/node_computed_style.h" +#include "third_party/blink/renderer/core/dom/shadow_root.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" #include "third_party/blink/renderer/core/frame/settings.h" @@ -179,16 +180,24 @@ ToSVGElement(*element).IsOutermostSVGSVGElement(); } +static bool IsAtUAShadowBoundary(const Element* element) { + if (!element) + return false; + if (ContainerNode* parent = element->parentNode()) + return parent->IsShadowRoot() && To<ShadowRoot>(parent)->IsUserAgent(); + return false; +} + // CSS requires text-decoration to be reset at each DOM element for -// inline blocks, inline tables, shadow DOM crossings, floating elements, +// inline blocks, inline tables, UA shadow DOM crossings, floating elements, // and absolute or relatively positioned elements. Outermost <svg> roots are // considered to be atomic inline-level. -static bool DoesNotInheritTextDecoration(const ComputedStyle& style, +static bool StopPropagateTextDecorations(const ComputedStyle& style, const Element* element) { return style.Display() == EDisplay::kInlineTable || style.Display() == EDisplay::kInlineBlock || style.Display() == EDisplay::kWebkitInlineBox || - IsAtShadowBoundary(element) || style.IsFloating() || + IsAtUAShadowBoundary(element) || style.IsFloating() || style.HasOutOfFlowPosition() || IsOutermostSVGElement(element) || IsHTMLRTElement(element); } @@ -618,7 +627,7 @@ style.OverflowY() != EOverflow::kVisible) AdjustOverflow(style); - if (DoesNotInheritTextDecoration(style, element)) + if (StopPropagateTextDecorations(style, element)) style.ClearAppliedTextDecorations(); else style.RestoreParentTextDecorations(parent_style);
diff --git a/third_party/blink/renderer/core/editing/iterators/text_iterator_test.cc b/third_party/blink/renderer/core/editing/iterators/text_iterator_test.cc index f204ca6..4b0148a6 100644 --- a/third_party/blink/renderer/core/editing/iterators/text_iterator_test.cc +++ b/third_party/blink/renderer/core/editing/iterators/text_iterator_test.cc
@@ -75,6 +75,10 @@ .Build(); } +TextIteratorBehavior EmitsSpaceForNbspBehavior() { + return TextIteratorBehavior::Builder().SetEmitsSpaceForNbsp(true).Build(); +} + struct DOMTree : NodeTraversal { using PositionType = Position; using TextIteratorType = TextIterator; @@ -1151,5 +1155,10 @@ Iterate<FlatTree>(EmitsCharactersBetweenAllVisiblePositionsBehavior())); } +TEST_P(TextIteratorTest, EmitsSpaceForNbsp) { + SetBodyContent("foo bar"); + EXPECT_EQ("[foo bar]", Iterate<DOMTree>(EmitsSpaceForNbspBehavior())); +} + } // namespace text_iterator_test } // namespace blink
diff --git a/third_party/blink/renderer/core/editing/iterators/text_iterator_text_node_handler.cc b/third_party/blink/renderer/core/editing/iterators/text_iterator_text_node_handler.cc index a1c06bc8..8c699506 100644 --- a/third_party/blink/renderer/core/editing/iterators/text_iterator_text_node_handler.cc +++ b/third_party/blink/renderer/core/editing/iterators/text_iterator_text_node_handler.cc
@@ -60,8 +60,8 @@ String string = mapping.GetText().Substring( unit.TextContentStart(), unit.TextContentEnd() - unit.TextContentStart()); - // TODO(xiaochengh): This seems wrong... Add real handling. - return {string, 0, 0}; + string.Replace(kNoBreakSpaceCharacter, kSpaceCharacter); + return {string, 0, string.length()}; } return {mapping.GetText(), unit.TextContentStart(), unit.TextContentEnd()}; }
diff --git a/third_party/blink/renderer/core/exported/web_blob.cc b/third_party/blink/renderer/core/exported/web_blob.cc index 20aa17e..4f2f06f 100644 --- a/third_party/blink/renderer/core/exported/web_blob.cc +++ b/third_party/blink/renderer/core/exported/web_blob.cc
@@ -42,11 +42,11 @@ WebBlob WebBlob::CreateFromUUID(const WebString& uuid, const WebString& type, - long long size) { + uint64_t size) { return Blob::Create(BlobDataHandle::Create(uuid, type, size)); } -WebBlob WebBlob::CreateFromFile(const WebString& path, long long size) { +WebBlob WebBlob::CreateFromFile(const WebString& path, uint64_t size) { std::unique_ptr<BlobData> blob_data = BlobData::Create(); blob_data->AppendFile(path, 0, size, InvalidFileTime()); return Blob::Create(BlobDataHandle::Create(std::move(blob_data), size));
diff --git a/third_party/blink/renderer/core/fetch/blob_bytes_consumer_test.cc b/third_party/blink/renderer/core/fetch/blob_bytes_consumer_test.cc index 5a79724..e7df5ba 100644 --- a/third_party/blink/renderer/core/fetch/blob_bytes_consumer_test.cc +++ b/third_party/blink/renderer/core/fetch/blob_bytes_consumer_test.cc
@@ -147,7 +147,8 @@ TEST_F(BlobBytesConsumerTest, DrainAsBlobDataHandle_2) { scoped_refptr<BlobDataHandle> blob_data_handle = BlobDataHandle::Create( - "uuid", "", -1, CreateBlob("foo bar")->CloneBlobPtr().PassInterface()); + "uuid", "", std::numeric_limits<uint64_t>::max(), + CreateBlob("foo bar")->CloneBlobPtr().PassInterface()); ; BlobBytesConsumer* consumer = MakeGarbageCollected<BlobBytesConsumer>(&GetDocument(), blob_data_handle); @@ -167,7 +168,8 @@ TEST_F(BlobBytesConsumerTest, DrainAsBlobDataHandle_3) { scoped_refptr<BlobDataHandle> blob_data_handle = BlobDataHandle::Create( - "uuid", "", -1, CreateBlob("foo bar")->CloneBlobPtr().PassInterface()); + "uuid", "", std::numeric_limits<uint64_t>::max(), + CreateBlob("foo bar")->CloneBlobPtr().PassInterface()); ; BlobBytesConsumer* consumer = MakeGarbageCollected<BlobBytesConsumer>(&GetDocument(), blob_data_handle);
diff --git a/third_party/blink/renderer/core/fetch/bytes_consumer_tee_test.cc b/third_party/blink/renderer/core/fetch/bytes_consumer_tee_test.cc index 83e5dda..df34021c 100644 --- a/third_party/blink/renderer/core/fetch/bytes_consumer_tee_test.cc +++ b/third_party/blink/renderer/core/fetch/bytes_consumer_tee_test.cc
@@ -372,8 +372,8 @@ } TEST_F(BytesConsumerTeeTest, BlobHandleWithInvalidSize) { - scoped_refptr<BlobDataHandle> blob_data_handle = - BlobDataHandle::Create(BlobData::Create(), -1); + scoped_refptr<BlobDataHandle> blob_data_handle = BlobDataHandle::Create( + BlobData::Create(), std::numeric_limits<uint64_t>::max()); BytesConsumer* src = MakeGarbageCollected<FakeBlobBytesConsumer>(blob_data_handle);
diff --git a/third_party/blink/renderer/core/fetch/response.cc b/third_party/blink/renderer/core/fetch/response.cc index 379b3807..f7d17d5 100644 --- a/third_party/blink/renderer/core/fetch/response.cc +++ b/third_party/blink/renderer/core/fetch/response.cc
@@ -97,6 +97,14 @@ for (const auto& header : fetch_api_response.headers) response->HeaderList()->Append(header.key, header.value); + // TODO(wanderview): This sets the mime type of the Response based on the + // current headers. This should be correct for most cases, but technically + // the mime type should really be frozen at the initial Response + // construction. We should plumb the value through the cache_storage + // persistence layer and include the explicit mime type in FetchAPIResponse + // to set here. See: crbug.com/938939 + response->SetMIMEType(response->HeaderList()->ExtractMIMEType()); + if (fetch_api_response.blob) { response->ReplaceBodyStreamBuffer(MakeGarbageCollected<BodyStreamBuffer>( script_state,
diff --git a/third_party/blink/renderer/core/fileapi/blob.cc b/third_party/blink/renderer/core/fileapi/blob.cc index 377b540..364ea486 100644 --- a/third_party/blink/renderer/core/fileapi/blob.cc +++ b/third_party/blink/renderer/core/fileapi/blob.cc
@@ -99,7 +99,7 @@ PopulateBlobData(blob_data.get(), blob_parts, normalize_line_endings_to_native); - long long blob_size = blob_data->length(); + uint64_t blob_size = blob_data->length(); return MakeGarbageCollected<Blob>( BlobDataHandle::Create(std::move(blob_data), blob_size)); } @@ -112,7 +112,7 @@ std::unique_ptr<BlobData> blob_data = BlobData::Create(); blob_data->SetContentType(content_type); blob_data->AppendBytes(data, size); - long long blob_size = blob_data->length(); + uint64_t blob_size = blob_data->length(); return MakeGarbageCollected<Blob>( BlobDataHandle::Create(std::move(blob_data), blob_size)); @@ -172,10 +172,10 @@ long long end, const String& content_type, ExceptionState& exception_state) const { - long long size = this->size(); + uint64_t size = this->size(); ClampSliceOffsets(size, start, end); - long long length = end - start; + uint64_t length = end - start; std::unique_ptr<BlobData> blob_data = BlobData::Create(); blob_data->SetContentType(NormalizeType(content_type)); blob_data->AppendBlob(blob_data_handle_, start, length);
diff --git a/third_party/blink/renderer/core/fileapi/blob.h b/third_party/blink/renderer/core/fileapi/blob.h index 2bf8b1ad..d5078f17 100644 --- a/third_party/blink/renderer/core/fileapi/blob.h +++ b/third_party/blink/renderer/core/fileapi/blob.h
@@ -76,7 +76,7 @@ explicit Blob(scoped_refptr<BlobDataHandle>); ~Blob() override; - virtual unsigned long long size() const { return blob_data_handle_->size(); } + virtual uint64_t size() const { return blob_data_handle_->size(); } virtual Blob* slice(long long start, long long end, const String& content_type,
diff --git a/third_party/blink/renderer/core/fileapi/file.cc b/third_party/blink/renderer/core/fileapi/file.cc index 122df83..aeb5e2f8 100644 --- a/third_party/blink/renderer/core/fileapi/file.cc +++ b/third_party/blink/renderer/core/fileapi/file.cc
@@ -146,7 +146,7 @@ PopulateBlobData(blob_data.get(), file_bits, normalize_line_endings_to_native); - long long file_size = blob_data->length(); + uint64_t file_size = blob_data->length(); return File::Create(file_name, last_modified, BlobDataHandle::Create(std::move(blob_data), file_size)); } @@ -187,7 +187,8 @@ File::File(const String& path, ContentTypeLookupPolicy policy, UserVisibility user_visibility) - : Blob(BlobDataHandle::Create(CreateBlobDataForFile(path, policy), -1)), + : Blob(BlobDataHandle::Create(CreateBlobDataForFile(path, policy), + std::numeric_limits<uint64_t>::max())), has_backing_file_(true), user_visibility_(user_visibility), path_(path), @@ -322,17 +323,16 @@ return modified_date; } -unsigned long long File::size() const { +uint64_t File::size() const { if (HasValidSnapshotMetadata()) return snapshot_size_; - // FIXME: JavaScript cannot represent sizes as large as unsigned long long, we - // need to come up with an exception to throw if file size is not - // representable. + // FIXME: JavaScript cannot represent sizes as large as uint64_t, we need + // to come up with an exception to throw if file size is not representable. long long size; if (!HasBackingFile() || !GetFileSize(path_, size)) return 0; - return static_cast<unsigned long long>(size); + return static_cast<uint64_t>(size); } Blob* File::slice(long long start, @@ -349,7 +349,7 @@ CaptureSnapshot(size, modification_time_ms); ClampSliceOffsets(size, start, end); - long long length = end - start; + uint64_t length = end - start; std::unique_ptr<BlobData> blob_data = BlobData::Create(); blob_data->SetContentType(NormalizeType(content_type)); DCHECK(!path_.IsEmpty());
diff --git a/third_party/blink/renderer/core/fileapi/file.h b/third_party/blink/renderer/core/fileapi/file.h index 474c226..6ae1e8e 100644 --- a/third_party/blink/renderer/core/fileapi/file.h +++ b/third_party/blink/renderer/core/fileapi/file.h
@@ -183,7 +183,7 @@ File* Clone(const String& name = String()) const; - unsigned long long size() const override; + uint64_t size() const override; Blob* slice(long long start, long long end, const String& content_type,
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc index 04c8ce4..c0aecdf 100644 --- a/third_party/blink/renderer/core/frame/local_frame.cc +++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -1350,7 +1350,7 @@ auto* local_frame_client = Client(); if (!local_frame_client) return nullptr; - frame_resource_coordinator_ = FrameResourceCoordinator::Create( + frame_resource_coordinator_ = FrameResourceCoordinator::MaybeCreate( local_frame_client->GetInterfaceProvider()); } return frame_resource_coordinator_.get();
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_filter_primitive.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_filter_primitive.cc index b76d248..de5aacbe 100644 --- a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_filter_primitive.cc +++ b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_filter_primitive.cc
@@ -35,6 +35,22 @@ return diff.TextDecorationOrColorChanged() && color.IsCurrentColor(); } +static void CheckForColorChange(SVGFilterPrimitiveStandardAttributes& element, + const QualifiedName& attr_name, + StyleDifference diff, + const StyleColor& old_color, + const StyleColor& new_color) { + // If the <color> change from/to 'currentcolor' then invalidate the filter + // chain so that it is rebuilt. (Makes sure the 'tainted' flag is + // propagated.) + if (new_color.IsCurrentColor() != old_color.IsCurrentColor()) { + element.Invalidate(); + return; + } + if (new_color != old_color || CurrentColorChanged(diff, new_color)) + element.PrimitiveAttributeChanged(attr_name); +} + void LayoutSVGResourceFilterPrimitive::StyleDidChange( StyleDifference diff, const ComputedStyle* old_style) { @@ -47,16 +63,16 @@ ToSVGFilterPrimitiveStandardAttributes(*GetElement()); const SVGComputedStyle& new_style = StyleRef().SvgStyle(); if (IsSVGFEFloodElement(element) || IsSVGFEDropShadowElement(element)) { - if (new_style.FloodColor() != old_style->SvgStyle().FloodColor() || - CurrentColorChanged(diff, new_style.FloodColor())) - element.PrimitiveAttributeChanged(svg_names::kFloodColorAttr); + CheckForColorChange(element, svg_names::kFloodColorAttr, diff, + old_style->SvgStyle().FloodColor(), + new_style.FloodColor()); if (new_style.FloodOpacity() != old_style->SvgStyle().FloodOpacity()) element.PrimitiveAttributeChanged(svg_names::kFloodOpacityAttr); } else if (IsSVGFEDiffuseLightingElement(element) || IsSVGFESpecularLightingElement(element)) { - if (new_style.LightingColor() != old_style->SvgStyle().LightingColor() || - CurrentColorChanged(diff, new_style.LightingColor())) - element.PrimitiveAttributeChanged(svg_names::kLightingColorAttr); + CheckForColorChange(element, svg_names::kLightingColorAttr, diff, + old_style->SvgStyle().LightingColor(), + new_style.LightingColor()); } if (new_style.ColorInterpolationFilters() != old_style->SvgStyle().ColorInterpolationFilters()) {
diff --git a/third_party/blink/renderer/core/loader/ping_loader.cc b/third_party/blink/renderer/core/loader/ping_loader.cc index bd6b119..c3fa424b0 100644 --- a/third_party/blink/renderer/core/loader/ping_loader.cc +++ b/third_party/blink/renderer/core/loader/ping_loader.cc
@@ -63,7 +63,7 @@ public: virtual void Serialize(ResourceRequest&) const = 0; - virtual unsigned long long size() const = 0; + virtual uint64_t size() const = 0; virtual const AtomicString GetContentType() const = 0; }; @@ -71,9 +71,7 @@ public: explicit BeaconString(const String& data) : data_(data) {} - unsigned long long size() const override { - return data_.CharactersSizeInBytes(); - } + uint64_t size() const override { return data_.CharactersSizeInBytes(); } void Serialize(ResourceRequest& request) const override { scoped_refptr<EncodedFormData> entity_body = @@ -98,7 +96,7 @@ content_type_ = AtomicString(blob_type); } - unsigned long long size() const override { return data_->size(); } + uint64_t size() const override { return data_->size(); } void Serialize(ResourceRequest& request) const override { DCHECK(data_); @@ -126,7 +124,7 @@ public: explicit BeaconDOMArrayBufferView(DOMArrayBufferView* data) : data_(data) {} - unsigned long long size() const override { return data_->byteLength(); } + uint64_t size() const override { return data_->byteLength(); } void Serialize(ResourceRequest& request) const override { DCHECK(data_); @@ -154,9 +152,7 @@ entity_body_->Boundary().data(); } - unsigned long long size() const override { - return entity_body_->SizeInBytes(); - } + uint64_t size() const override { return entity_body_->SizeInBytes(); } void Serialize(ResourceRequest& request) const override { request.SetHTTPBody(entity_body_.get());
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc index 43e69e30..23cfc96 100644 --- a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc +++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
@@ -712,9 +712,9 @@ state.compositor_element_id = CompositorElementIdFromUniqueObjectId( object_.UniqueId(), CompositorElementIdNamespace::kPrimaryTransform); + state.is_running_animation_on_compositor = + style.IsRunningTransformAnimationOnCompositor(); } - state.is_running_animation_on_compositor = - style.IsRunningTransformAnimationOnCompositor(); OnUpdate(properties_->UpdateTransform(*context_.current.transform, std::move(state))); @@ -963,11 +963,11 @@ state.compositor_element_id = CompositorElementIdFromUniqueObjectId( object_.UniqueId(), CompositorElementIdNamespace::kPrimary); } + state.is_running_opacity_animation_on_compositor = + style.IsRunningOpacityAnimationOnCompositor(); + state.is_running_backdrop_filter_animation_on_compositor = + style.IsRunningBackdropFilterAnimationOnCompositor(); } - state.is_running_opacity_animation_on_compositor = - style.IsRunningOpacityAnimationOnCompositor(); - state.is_running_backdrop_filter_animation_on_compositor = - style.IsRunningBackdropFilterAnimationOnCompositor(); OnUpdate(properties_->UpdateEffect(*context_.current_effect, std::move(state))); @@ -1113,9 +1113,9 @@ state.compositor_element_id = CompositorElementIdFromUniqueObjectId( object_.UniqueId(), CompositorElementIdNamespace::kEffectFilter); + state.is_running_filter_animation_on_compositor = + style.IsRunningFilterAnimationOnCompositor(); } - state.is_running_filter_animation_on_compositor = - style.IsRunningFilterAnimationOnCompositor(); OnUpdate(properties_->UpdateFilter(*context_.current_effect, std::move(state)));
diff --git a/third_party/blink/renderer/core/paint/theme_painter.cc b/third_party/blink/renderer/core/paint/theme_painter.cc index 2aed9cf..7d172e7b 100644 --- a/third_party/blink/renderer/core/paint/theme_painter.cc +++ b/third_party/blink/renderer/core/paint/theme_painter.cc
@@ -70,7 +70,7 @@ } bool IsMenulistInput(const Node* node) { - if (auto* input = ToHTMLInputElement(node)) { + if (auto* input = ToHTMLInputElementOrNull(node)) { #if defined(OS_ANDROID) if (IsTemporalInput(input->type())) return true;
diff --git a/third_party/blink/renderer/core/script/import_map.cc b/third_party/blink/renderer/core/script/import_map.cc index f95d4cd..40ae1b9 100644 --- a/third_party/blink/renderer/core/script/import_map.cc +++ b/third_party/blink/renderer/core/script/import_map.cc
@@ -205,6 +205,57 @@ modules_map); } +base::Optional<ImportMap::MatchResult> ImportMap::MatchExact( + const ParsedSpecifier& parsed_specifier) const { + const String key = parsed_specifier.GetImportMapKeyString(); + MatchResult exact = imports_.find(key); + if (exact != imports_.end()) + return exact; + return base::nullopt; +} + +base::Optional<ImportMap::MatchResult> ImportMap::MatchPrefix( + const ParsedSpecifier& parsed_specifier) const { + // Do not perform prefix match for non-bare specifiers. + if (parsed_specifier.GetType() != ParsedSpecifier::Type::kBare) + return base::nullopt; + + const String key = parsed_specifier.GetImportMapKeyString(); + + // Prefix match, i.e. "Packages" via trailing slashes. + // https://github.com/WICG/import-maps#packages-via-trailing-slashes + // + // TODO(hiroshige): optimize this if necessary. See + // https://github.com/WICG/import-maps/issues/73#issuecomment-439327758 + // for some candidate implementations. + + // "most-specific wins", i.e. when there are multiple matching keys, + // choose the longest. + // https://github.com/WICG/import-maps/issues/102 + base::Optional<MatchResult> best_match; + + for (auto it = imports_.begin(); it != imports_.end(); ++it) { + if (!it->key.EndsWith('/')) + continue; + + if (!key.StartsWith(it->key)) + continue; + + if (best_match && it->key.length() < (*best_match)->key.length()) + continue; + + best_match = it; + } + return best_match; +} + +base::Optional<ImportMap::MatchResult> ImportMap::Match( + const ParsedSpecifier& parsed_specifier) const { + if (auto exact = MatchExact(parsed_specifier)) + return exact; + return MatchPrefix(parsed_specifier); +} + ImportMap::ImportMap(const Modulator& modulator_for_built_in_modules, const HashMap<String, Vector<KURL>>& imports) : imports_(imports), @@ -214,25 +265,32 @@ String* debug_message) const { DCHECK(debug_message); const String key = parsed_specifier.GetImportMapKeyString(); - auto it = imports_.find(key); - if (it == imports_.end()) { + + base::Optional<MatchResult> maybe_matched = Match(parsed_specifier); + + if (!maybe_matched) { *debug_message = "Import Map: \"" + key + "\" matches with no entries and thus is not mapped."; return base::nullopt; } - for (const auto& candidate_url : it->value) { + MatchResult& matched = *maybe_matched; + const String postfix = key.Substring(matched->key.length()); + + for (const KURL& value : matched->value) { + const KURL complete_url = postfix.IsEmpty() ? value : KURL(value, postfix); if (blink::layered_api::ResolveFetchingURL(*modulator_for_built_in_modules_, - candidate_url) + complete_url) .IsValid()) { - *debug_message = "Import Map: \"" + key + "\" matches with \"" + it->key + - "\" and is mapped to " + candidate_url.ElidedString(); - return candidate_url; + *debug_message = "Import Map: \"" + key + "\" matches with \"" + + matched->key + "\" and is mapped to " + + complete_url.ElidedString(); + return complete_url; } } - *debug_message = "Import Map: \"" + key + "\" matches with \"" + it->key + - "\" but fails to be mapped (no viable URLs)"; + *debug_message = "Import Map: \"" + key + "\" matches with \"" + + matched->key + "\" but fails to be mapped (no viable URLs)"; return NullURL(); }
diff --git a/third_party/blink/renderer/core/script/import_map.h b/third_party/blink/renderer/core/script/import_map.h index b6a00cd..b4f1d4e2 100644 --- a/third_party/blink/renderer/core/script/import_map.h +++ b/third_party/blink/renderer/core/script/import_map.h
@@ -41,6 +41,11 @@ void Trace(Visitor*); private: + using MatchResult = HashMap<String, Vector<KURL>>::const_iterator; + base::Optional<MatchResult> Match(const ParsedSpecifier&) const; + base::Optional<MatchResult> MatchExact(const ParsedSpecifier&) const; + base::Optional<MatchResult> MatchPrefix(const ParsedSpecifier&) const; + HashMap<String, Vector<KURL>> imports_; Member<const Modulator> modulator_for_built_in_modules_; };
diff --git a/third_party/blink/renderer/core/script/layered_api.cc b/third_party/blink/renderer/core/script/layered_api.cc index 6af1e48..e4001b6 100644 --- a/third_party/blink/renderer/core/script/layered_api.cc +++ b/third_party/blink/renderer/core/script/layered_api.cc
@@ -23,18 +23,21 @@ constexpr char kBuiltinSpecifierPrefix[] = "@std/"; -int GetResourceIDFromPath(const Modulator& modulator, const String& path) { +constexpr char kTopLevelScriptPostfix[] = "/index.js"; + +const LayeredAPIResource* GetResourceFromPath(const Modulator& modulator, + const String& path) { for (size_t i = 0; i < base::size(kLayeredAPIResources); ++i) { if (modulator.BuiltInModuleEnabled(kLayeredAPIResources[i].module) && path == kLayeredAPIResources[i].path) { - return kLayeredAPIResources[i].resource_id; + return &kLayeredAPIResources[i]; } } - return -1; + return nullptr; } bool IsImplemented(const Modulator& modulator, const String& name) { - return GetResourceIDFromPath(modulator, name + "/index.js") >= 0; + return GetResourceFromPath(modulator, name + kTopLevelScriptPostfix); } } // namespace @@ -104,11 +107,15 @@ path = path.Substring(2); } - int resource_id = GetResourceIDFromPath(modulator, path); - if (resource_id < 0) + const LayeredAPIResource* resource = GetResourceFromPath(modulator, path); + if (!resource) return String(); - return UncompressResourceAsString(resource_id); + // Only count the use of top-level scripts of each built-in module. + if (path.EndsWith(kTopLevelScriptPostfix)) + modulator.BuiltInModuleUseCount(resource->module); + + return UncompressResourceAsString(resource->resource_id); } } // namespace layered_api
diff --git a/third_party/blink/renderer/core/script/modulator.h b/third_party/blink/renderer/core/script/modulator.h index 7d76deae7..05d01b3 100644 --- a/third_party/blink/renderer/core/script/modulator.h +++ b/third_party/blink/renderer/core/script/modulator.h
@@ -123,6 +123,7 @@ virtual bool BuiltInModuleInfraEnabled() const = 0; virtual bool BuiltInModuleEnabled(blink::layered_api::Module) const = 0; + virtual void BuiltInModuleUseCount(blink::layered_api::Module) const = 0; // https://html.spec.whatwg.org/C/#fetch-a-module-script-tree // https://html.spec.whatwg.org/C/#fetch-a-module-worker-script-tree
diff --git a/third_party/blink/renderer/core/script/modulator_impl_base.cc b/third_party/blink/renderer/core/script/modulator_impl_base.cc index 32c311c..8b20ac1 100644 --- a/third_party/blink/renderer/core/script/modulator_impl_base.cc +++ b/third_party/blink/renderer/core/script/modulator_impl_base.cc
@@ -65,6 +65,24 @@ } } +void ModulatorImplBase::BuiltInModuleUseCount( + blink::layered_api::Module module) const { + DCHECK(BuiltInModuleInfraEnabled()); + DCHECK(BuiltInModuleEnabled(module)); + switch (module) { + case blink::layered_api::Module::kBlank: + break; + case blink::layered_api::Module::kVirtualScroller: + UseCounter::Count(GetExecutionContext(), + WebFeature::kBuiltInModuleVirtualScroller); + break; + case blink::layered_api::Module::kKvStorage: + UseCounter::Count(GetExecutionContext(), + WebFeature::kBuiltInModuleKvStorage); + break; + } +} + // <specdef label="fetch-a-module-script-tree" // href="https://html.spec.whatwg.org/C/#fetch-a-module-script-tree"> // <specdef label="fetch-a-module-worker-script-tree"
diff --git a/third_party/blink/renderer/core/script/modulator_impl_base.h b/third_party/blink/renderer/core/script/modulator_impl_base.h index 58ec179..cf9455e0 100644 --- a/third_party/blink/renderer/core/script/modulator_impl_base.h +++ b/third_party/blink/renderer/core/script/modulator_impl_base.h
@@ -44,6 +44,7 @@ bool BuiltInModuleInfraEnabled() const override; bool BuiltInModuleEnabled(blink::layered_api::Module) const override; + void BuiltInModuleUseCount(blink::layered_api::Module) const override; ScriptModuleResolver* GetScriptModuleResolver() override { return script_module_resolver_.Get();
diff --git a/third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.cc b/third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.cc index 42c6cda5c..01c0195 100644 --- a/third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.cc +++ b/third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.cc
@@ -192,7 +192,7 @@ effect_element, filter_color_interpolation); effect->SetOperatingInterpolationSpace( ResolveInterpolationSpace(color_interpolation)); - if (effect_element.TaintsOrigin(effect->InputsTaintOrigin())) + if (effect->InputsTaintOrigin() || effect_element.TaintsOrigin()) effect->SetOriginTainted(); Add(AtomicString(effect_element.result()->CurrentValue()->Value()), effect);
diff --git a/third_party/blink/renderer/core/svg/svg_fe_blend_element.h b/third_party/blink/renderer/core/svg/svg_fe_blend_element.h index 66927de..002967b 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_blend_element.h +++ b/third_party/blink/renderer/core/svg/svg_fe_blend_element.h
@@ -65,6 +65,7 @@ const QualifiedName& attr_name) override; void SvgAttributeChanged(const QualifiedName&) override; FilterEffect* Build(SVGFilterBuilder*, Filter*) override; + bool TaintsOrigin() const override { return false; } Member<SVGAnimatedString> in1_; Member<SVGAnimatedString> in2_;
diff --git a/third_party/blink/renderer/core/svg/svg_fe_color_matrix_element.cc b/third_party/blink/renderer/core/svg/svg_fe_color_matrix_element.cc index 46cb2d95..07d47ab0 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_color_matrix_element.cc +++ b/third_party/blink/renderer/core/svg/svg_fe_color_matrix_element.cc
@@ -106,8 +106,4 @@ return effect; } -bool SVGFEColorMatrixElement::TaintsOrigin(bool inputs_taint_origin) const { - return inputs_taint_origin; -} - } // namespace blink
diff --git a/third_party/blink/renderer/core/svg/svg_fe_color_matrix_element.h b/third_party/blink/renderer/core/svg/svg_fe_color_matrix_element.h index f886203..d569e80 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_color_matrix_element.h +++ b/third_party/blink/renderer/core/svg/svg_fe_color_matrix_element.h
@@ -50,7 +50,7 @@ bool SetFilterEffectAttribute(FilterEffect*, const QualifiedName&) override; void SvgAttributeChanged(const QualifiedName&) override; FilterEffect* Build(SVGFilterBuilder*, Filter*) override; - bool TaintsOrigin(bool inputs_taint_origin) const override; + bool TaintsOrigin() const override { return false; } Member<SVGAnimatedNumberList> values_; Member<SVGAnimatedString> in1_;
diff --git a/third_party/blink/renderer/core/svg/svg_fe_component_transfer_element.h b/third_party/blink/renderer/core/svg/svg_fe_component_transfer_element.h index bc617e6a..be88645 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_component_transfer_element.h +++ b/third_party/blink/renderer/core/svg/svg_fe_component_transfer_element.h
@@ -42,6 +42,7 @@ private: void SvgAttributeChanged(const QualifiedName&) override; FilterEffect* Build(SVGFilterBuilder*, Filter*) override; + bool TaintsOrigin() const override { return false; } Member<SVGAnimatedString> in1_; };
diff --git a/third_party/blink/renderer/core/svg/svg_fe_composite_element.h b/third_party/blink/renderer/core/svg/svg_fe_composite_element.h index 7f4b6d1..da1f5ff 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_composite_element.h +++ b/third_party/blink/renderer/core/svg/svg_fe_composite_element.h
@@ -56,6 +56,7 @@ bool SetFilterEffectAttribute(FilterEffect*, const QualifiedName&) override; void SvgAttributeChanged(const QualifiedName&) override; FilterEffect* Build(SVGFilterBuilder*, Filter*) override; + bool TaintsOrigin() const override { return false; } Member<SVGAnimatedNumber> k1_; Member<SVGAnimatedNumber> k2_;
diff --git a/third_party/blink/renderer/core/svg/svg_fe_convolve_matrix_element.h b/third_party/blink/renderer/core/svg/svg_fe_convolve_matrix_element.h index 20d5dd83..c4f9502 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_convolve_matrix_element.h +++ b/third_party/blink/renderer/core/svg/svg_fe_convolve_matrix_element.h
@@ -71,6 +71,7 @@ bool SetFilterEffectAttribute(FilterEffect*, const QualifiedName&) override; void SvgAttributeChanged(const QualifiedName&) override; FilterEffect* Build(SVGFilterBuilder*, Filter*) override; + bool TaintsOrigin() const override { return false; } Member<SVGAnimatedNumber> bias_; Member<SVGAnimatedNumber> divisor_;
diff --git a/third_party/blink/renderer/core/svg/svg_fe_diffuse_lighting_element.cc b/third_party/blink/renderer/core/svg/svg_fe_diffuse_lighting_element.cc index ab43b2a0..85e8226 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_diffuse_lighting_element.cc +++ b/third_party/blink/renderer/core/svg/svg_fe_diffuse_lighting_element.cc
@@ -161,4 +161,12 @@ return effect; } +bool SVGFEDiffuseLightingElement::TaintsOrigin() const { + const ComputedStyle* style = GetComputedStyle(); + // TaintsOrigin() is only called after a successful call to Build() + // (see above), so we should have a ComputedStyle here. + DCHECK(style); + return style->SvgStyle().LightingColor().IsCurrentColor(); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/svg/svg_fe_diffuse_lighting_element.h b/third_party/blink/renderer/core/svg/svg_fe_diffuse_lighting_element.h index a7f9b42..f95e3738 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_diffuse_lighting_element.h +++ b/third_party/blink/renderer/core/svg/svg_fe_diffuse_lighting_element.h
@@ -57,6 +57,7 @@ bool SetFilterEffectAttribute(FilterEffect*, const QualifiedName&) override; void SvgAttributeChanged(const QualifiedName&) override; FilterEffect* Build(SVGFilterBuilder*, Filter*) override; + bool TaintsOrigin() const override; Member<SVGAnimatedNumber> diffuse_constant_; Member<SVGAnimatedNumber> surface_scale_;
diff --git a/third_party/blink/renderer/core/svg/svg_fe_displacement_map_element.h b/third_party/blink/renderer/core/svg/svg_fe_displacement_map_element.h index 7cc51da..958cef73 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_displacement_map_element.h +++ b/third_party/blink/renderer/core/svg/svg_fe_displacement_map_element.h
@@ -58,6 +58,7 @@ const QualifiedName& attr_name) override; void SvgAttributeChanged(const QualifiedName&) override; FilterEffect* Build(SVGFilterBuilder*, Filter*) override; + bool TaintsOrigin() const override { return false; } Member<SVGAnimatedNumber> scale_; Member<SVGAnimatedString> in1_;
diff --git a/third_party/blink/renderer/core/svg/svg_fe_drop_shadow_element.cc b/third_party/blink/renderer/core/svg/svg_fe_drop_shadow_element.cc index 561173cc..bc187c9 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_drop_shadow_element.cc +++ b/third_party/blink/renderer/core/svg/svg_fe_drop_shadow_element.cc
@@ -115,4 +115,12 @@ return effect; } +bool SVGFEDropShadowElement::TaintsOrigin() const { + const ComputedStyle* style = GetComputedStyle(); + // TaintsOrigin() is only called after a successful call to Build() + // (see above), so we should have a ComputedStyle here. + DCHECK(style); + return style->SvgStyle().FloodColor().IsCurrentColor(); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/svg/svg_fe_drop_shadow_element.h b/third_party/blink/renderer/core/svg/svg_fe_drop_shadow_element.h index 624ab18..c9e3344 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_drop_shadow_element.h +++ b/third_party/blink/renderer/core/svg/svg_fe_drop_shadow_element.h
@@ -50,6 +50,7 @@ void SvgAttributeChanged(const QualifiedName&) override; bool SetFilterEffectAttribute(FilterEffect*, const QualifiedName&) override; FilterEffect* Build(SVGFilterBuilder*, Filter*) override; + bool TaintsOrigin() const override; Member<SVGAnimatedNumber> dx_; Member<SVGAnimatedNumber> dy_;
diff --git a/third_party/blink/renderer/core/svg/svg_fe_flood_element.cc b/third_party/blink/renderer/core/svg/svg_fe_flood_element.cc index 3b43613..3ea9634 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_flood_element.cc +++ b/third_party/blink/renderer/core/svg/svg_fe_flood_element.cc
@@ -61,4 +61,12 @@ return FEFlood::Create(filter, color, opacity); } +bool SVGFEFloodElement::TaintsOrigin() const { + const ComputedStyle* style = GetComputedStyle(); + // TaintsOrigin() is only called after a successful call to Build() + // (see above), so we should have a ComputedStyle here. + DCHECK(style); + return style->SvgStyle().FloodColor().IsCurrentColor(); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/svg/svg_fe_flood_element.h b/third_party/blink/renderer/core/svg/svg_fe_flood_element.h index 45af42f..1a3fc21 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_flood_element.h +++ b/third_party/blink/renderer/core/svg/svg_fe_flood_element.h
@@ -37,6 +37,7 @@ bool SetFilterEffectAttribute(FilterEffect*, const QualifiedName& attr_name) override; FilterEffect* Build(SVGFilterBuilder*, Filter*) override; + bool TaintsOrigin() const override; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/svg/svg_fe_gaussian_blur_element.h b/third_party/blink/renderer/core/svg/svg_fe_gaussian_blur_element.h index 73a68d1..4fda9b8 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_gaussian_blur_element.h +++ b/third_party/blink/renderer/core/svg/svg_fe_gaussian_blur_element.h
@@ -47,6 +47,7 @@ private: void SvgAttributeChanged(const QualifiedName&) override; FilterEffect* Build(SVGFilterBuilder*, Filter*) override; + bool TaintsOrigin() const override { return false; } Member<SVGAnimatedNumberOptionalNumber> std_deviation_; Member<SVGAnimatedString> in1_;
diff --git a/third_party/blink/renderer/core/svg/svg_fe_image_element.cc b/third_party/blink/renderer/core/svg/svg_fe_image_element.cc index 6ee1a319..8fb2e27 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_image_element.cc +++ b/third_party/blink/renderer/core/svg/svg_fe_image_element.cc
@@ -162,10 +162,9 @@ preserve_aspect_ratio_->CurrentValue()); } -bool SVGFEImageElement::TaintsOrigin(bool inputs_taint_origin) const { - if (cached_image_ && cached_image_->IsAccessAllowed()) - return inputs_taint_origin; - return true; +bool SVGFEImageElement::TaintsOrigin() const { + // We always consider a 'href' that references a local element as tainting. + return !cached_image_ || !cached_image_->IsAccessAllowed(); } } // namespace blink
diff --git a/third_party/blink/renderer/core/svg/svg_fe_image_element.h b/third_party/blink/renderer/core/svg/svg_fe_image_element.h index 8288902..c59802c1 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_image_element.h +++ b/third_party/blink/renderer/core/svg/svg_fe_image_element.h
@@ -66,7 +66,7 @@ void BuildPendingResource() override; InsertionNotificationRequest InsertedInto(ContainerNode&) override; void RemovedFrom(ContainerNode&) override; - bool TaintsOrigin(bool inputs_taint_origin) const override; + bool TaintsOrigin() const override; Member<SVGAnimatedPreserveAspectRatio> preserve_aspect_ratio_;
diff --git a/third_party/blink/renderer/core/svg/svg_fe_merge_element.cc b/third_party/blink/renderer/core/svg/svg_fe_merge_element.cc index aa7b48e4..8c1565d 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_merge_element.cc +++ b/third_party/blink/renderer/core/svg/svg_fe_merge_element.cc
@@ -47,8 +47,4 @@ return effect; } -bool SVGFEMergeElement::TaintsOrigin(bool inputs_taint_origin) const { - return inputs_taint_origin; -} - } // namespace blink
diff --git a/third_party/blink/renderer/core/svg/svg_fe_merge_element.h b/third_party/blink/renderer/core/svg/svg_fe_merge_element.h index 69a9a2f..d39a831 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_merge_element.h +++ b/third_party/blink/renderer/core/svg/svg_fe_merge_element.h
@@ -35,7 +35,7 @@ private: FilterEffect* Build(SVGFilterBuilder*, Filter*) override; - bool TaintsOrigin(bool inputs_taint_origin) const override; + bool TaintsOrigin() const override { return false; } }; } // namespace blink
diff --git a/third_party/blink/renderer/core/svg/svg_fe_morphology_element.h b/third_party/blink/renderer/core/svg/svg_fe_morphology_element.h index 17c8316..7e7c722 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_morphology_element.h +++ b/third_party/blink/renderer/core/svg/svg_fe_morphology_element.h
@@ -52,6 +52,7 @@ bool SetFilterEffectAttribute(FilterEffect*, const QualifiedName&) override; void SvgAttributeChanged(const QualifiedName&) override; FilterEffect* Build(SVGFilterBuilder*, Filter*) override; + bool TaintsOrigin() const override { return false; } Member<SVGAnimatedNumberOptionalNumber> radius_; Member<SVGAnimatedString> in1_;
diff --git a/third_party/blink/renderer/core/svg/svg_fe_offset_element.h b/third_party/blink/renderer/core/svg/svg_fe_offset_element.h index 0263ec9a..7dec229c 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_offset_element.h +++ b/third_party/blink/renderer/core/svg/svg_fe_offset_element.h
@@ -44,6 +44,7 @@ private: void SvgAttributeChanged(const QualifiedName&) override; FilterEffect* Build(SVGFilterBuilder*, Filter*) override; + bool TaintsOrigin() const override { return false; } Member<SVGAnimatedNumber> dx_; Member<SVGAnimatedNumber> dy_;
diff --git a/third_party/blink/renderer/core/svg/svg_fe_specular_lighting_element.cc b/third_party/blink/renderer/core/svg/svg_fe_specular_lighting_element.cc index f2bda029e..e077742 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_specular_lighting_element.cc +++ b/third_party/blink/renderer/core/svg/svg_fe_specular_lighting_element.cc
@@ -172,4 +172,12 @@ return effect; } +bool SVGFESpecularLightingElement::TaintsOrigin() const { + const ComputedStyle* style = GetComputedStyle(); + // TaintsOrigin() is only called after a successful call to Build() + // (see above), so we should have a ComputedStyle here. + DCHECK(style); + return style->SvgStyle().LightingColor().IsCurrentColor(); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/svg/svg_fe_specular_lighting_element.h b/third_party/blink/renderer/core/svg/svg_fe_specular_lighting_element.h index 8ac45e6..e0aad86 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_specular_lighting_element.h +++ b/third_party/blink/renderer/core/svg/svg_fe_specular_lighting_element.h
@@ -59,6 +59,7 @@ bool SetFilterEffectAttribute(FilterEffect*, const QualifiedName&) override; void SvgAttributeChanged(const QualifiedName&) override; FilterEffect* Build(SVGFilterBuilder*, Filter*) override; + bool TaintsOrigin() const override; Member<SVGAnimatedNumber> specular_constant_; Member<SVGAnimatedNumber> specular_exponent_;
diff --git a/third_party/blink/renderer/core/svg/svg_fe_tile_element.h b/third_party/blink/renderer/core/svg/svg_fe_tile_element.h index b2c4845..3659be87 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_tile_element.h +++ b/third_party/blink/renderer/core/svg/svg_fe_tile_element.h
@@ -41,6 +41,7 @@ private: void SvgAttributeChanged(const QualifiedName&) override; FilterEffect* Build(SVGFilterBuilder*, Filter*) override; + bool TaintsOrigin() const override { return false; } Member<SVGAnimatedString> in1_; };
diff --git a/third_party/blink/renderer/core/svg/svg_fe_turbulence_element.h b/third_party/blink/renderer/core/svg/svg_fe_turbulence_element.h index b4b9800..821a963 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_turbulence_element.h +++ b/third_party/blink/renderer/core/svg/svg_fe_turbulence_element.h
@@ -64,7 +64,7 @@ // Turbulence takes no inputs and doesn't taint origin, so we can always // return false. - bool TaintsOrigin(bool inputs_taint_origin) const override { return false; } + bool TaintsOrigin() const override { return false; } private: bool SetFilterEffectAttribute(FilterEffect*,
diff --git a/third_party/blink/renderer/core/svg/svg_filter_primitive_standard_attributes.h b/third_party/blink/renderer/core/svg/svg_filter_primitive_standard_attributes.h index 2306066..90f533a 100644 --- a/third_party/blink/renderer/core/svg/svg_filter_primitive_standard_attributes.h +++ b/third_party/blink/renderer/core/svg/svg_filter_primitive_standard_attributes.h
@@ -46,7 +46,7 @@ // Returns true, if the new value is different from the old one. virtual bool SetFilterEffectAttribute(FilterEffect*, const QualifiedName&); - virtual bool TaintsOrigin(bool inputs_taint_origin) const { return true; } + virtual bool TaintsOrigin() const { return true; } // JS API SVGAnimatedLength* x() const { return x_.Get(); }
diff --git a/third_party/blink/renderer/core/testing/dummy_modulator.cc b/third_party/blink/renderer/core/testing/dummy_modulator.cc index a08f609..ef3144f 100644 --- a/third_party/blink/renderer/core/testing/dummy_modulator.cc +++ b/third_party/blink/renderer/core/testing/dummy_modulator.cc
@@ -66,6 +66,8 @@ return false; } +void DummyModulator::BuiltInModuleUseCount(blink::layered_api::Module) const {} + ScriptModuleResolver* DummyModulator::GetScriptModuleResolver() { return resolver_.Get(); }
diff --git a/third_party/blink/renderer/core/testing/dummy_modulator.h b/third_party/blink/renderer/core/testing/dummy_modulator.h index bb255a8..01c1e51 100644 --- a/third_party/blink/renderer/core/testing/dummy_modulator.h +++ b/third_party/blink/renderer/core/testing/dummy_modulator.h
@@ -37,6 +37,7 @@ bool BuiltInModuleInfraEnabled() const override; bool BuiltInModuleEnabled(blink::layered_api::Module) const override; + void BuiltInModuleUseCount(blink::layered_api::Module) const override; void FetchTree(const KURL&, ResourceFetcher*,
diff --git a/third_party/blink/renderer/modules/filesystem/metadata.h b/third_party/blink/renderer/modules/filesystem/metadata.h index 8bff4ae..4223190f 100644 --- a/third_party/blink/renderer/modules/filesystem/metadata.h +++ b/third_party/blink/renderer/modules/filesystem/metadata.h
@@ -56,8 +56,8 @@ double modificationTime() const { return platform_metadata_.modification_time; } - unsigned long long size() const { - return static_cast<unsigned long long>(platform_metadata_.length); + uint64_t size() const { + return static_cast<uint64_t>(platform_metadata_.length); } private:
diff --git a/third_party/blink/renderer/modules/mediarecorder/media_recorder.cc b/third_party/blink/renderer/modules/mediarecorder/media_recorder.cc index 67c16eb2..0fa418d 100644 --- a/third_party/blink/renderer/modules/mediarecorder/media_recorder.cc +++ b/third_party/blink/renderer/modules/mediarecorder/media_recorder.cc
@@ -344,7 +344,7 @@ return; // Cache |m_blobData->length()| before release()ng it. - const long long blob_data_length = blob_data_->length(); + const uint64_t blob_data_length = blob_data_->length(); CreateBlobEvent(Blob::Create(BlobDataHandle::Create(std::move(blob_data_), blob_data_length)), timecode);
diff --git a/third_party/blink/renderer/modules/push_messaging/push_message_data.cc b/third_party/blink/renderer/modules/push_messaging/push_message_data.cc index 69220f1c..b7609dc 100644 --- a/third_party/blink/renderer/modules/push_messaging/push_message_data.cc +++ b/third_party/blink/renderer/modules/push_messaging/push_message_data.cc
@@ -69,7 +69,7 @@ // Note that the content type of the Blob object is deliberately not being // provided, following the specification. - const long long byte_length = blob_data->length(); + const uint64_t byte_length = blob_data->length(); return Blob::Create( BlobDataHandle::Create(std::move(blob_data), byte_length)); }
diff --git a/third_party/blink/renderer/modules/time_zone_monitor/time_zone_monitor_client.cc b/third_party/blink/renderer/modules/time_zone_monitor/time_zone_monitor_client.cc index 73e7a46..a67cf487 100644 --- a/third_party/blink/renderer/modules/time_zone_monitor/time_zone_monitor_client.cc +++ b/third_party/blink/renderer/modules/time_zone_monitor/time_zone_monitor_client.cc
@@ -25,7 +25,7 @@ // Notify V8 that the date/time configuration of the system might have changed. void NotifyTimezoneChangeToV8(v8::Isolate* isolate) { DCHECK(isolate); - v8::Date::DateTimeConfigurationChangeNotification(isolate); + isolate->DateTimeConfigurationChangeNotification(); } void NotifyTimezoneChangeOnWorkerThread(WorkerThread* worker_thread) {
diff --git a/third_party/blink/renderer/modules/websockets/dom_websocket.cc b/third_party/blink/renderer/modules/websockets/dom_websocket.cc index 89e5629d..2baadc0a 100644 --- a/third_party/blink/renderer/modules/websockets/dom_websocket.cc +++ b/third_party/blink/renderer/modules/websockets/dom_websocket.cc
@@ -538,7 +538,7 @@ UpdateBufferedAmountAfterClose(binary_data->size()); return; } - unsigned long long size = binary_data->size(); + uint64_t size = binary_data->size(); RecordSendTypeHistogram(kWebSocketSendTypeBlob); RecordSendMessageSizeHistogram( kWebSocketSendTypeBlob,
diff --git a/third_party/blink/renderer/platform/bindings/v8_per_isolate_data.cc b/third_party/blink/renderer/platform/bindings/v8_per_isolate_data.cc index 3dfc6d43..ea8cbfa4 100644 --- a/third_party/blink/renderer/platform/bindings/v8_per_isolate_data.cc +++ b/third_party/blink/renderer/platform/bindings/v8_per_isolate_data.cc
@@ -67,7 +67,7 @@ CHECK(!ScriptForbiddenScope::IsScriptForbidden()); } -static void MicrotasksCompletedCallback(v8::Isolate* isolate, void*) { +static void MicrotasksCompletedCallback(v8::Isolate* isolate) { V8PerIsolateData::From(isolate)->RunEndOfScopeTasks(); }
diff --git a/third_party/blink/renderer/platform/blob/blob_data.h b/third_party/blink/renderer/platform/blob/blob_data.h index 1afc9f231..7788cc5 100644 --- a/third_party/blink/renderer/platform/blob/blob_data.h +++ b/third_party/blink/renderer/platform/blob/blob_data.h
@@ -184,7 +184,7 @@ String Uuid() const { return uuid_.IsolatedCopy(); } String GetType() const { return type_.IsolatedCopy(); } - unsigned long long size() const { return size_; } + uint64_t size() const { return size_; } bool IsSingleUnknownSizeFile() const { return is_single_unknown_size_file_; }
diff --git a/third_party/blink/renderer/platform/exported/platform.cc b/third_party/blink/renderer/platform/exported/platform.cc index 7b1643a7..aafd9121 100644 --- a/third_party/blink/renderer/platform/exported/platform.cc +++ b/third_party/blink/renderer/platform/exported/platform.cc
@@ -220,7 +220,7 @@ ParkableStringManagerDumpProvider::Instance(), "ParkableStrings", base::ThreadTaskRunnerHandle::Get()); - RendererResourceCoordinator::Initialize(); + RendererResourceCoordinator::MaybeInitialize(); } void Platform::SetCurrentPlatformForTesting(Platform* platform) {
diff --git a/third_party/blink/renderer/platform/exported/web_blob_info.cc b/third_party/blink/renderer/platform/exported/web_blob_info.cc index 5ba8952..b4808d0 100644 --- a/third_party/blink/renderer/platform/exported/web_blob_info.cc +++ b/third_party/blink/renderer/platform/exported/web_blob_info.cc
@@ -10,7 +10,7 @@ WebBlobInfo::WebBlobInfo(const WebString& uuid, const WebString& type, - long long size, + uint64_t size, mojo::ScopedMessagePipeHandle handle) : WebBlobInfo(BlobDataHandle::Create( uuid, @@ -24,7 +24,7 @@ const WebString& file_name, const WebString& type, double last_modified, - long long size, + uint64_t size, mojo::ScopedMessagePipeHandle handle) : WebBlobInfo(BlobDataHandle::Create( uuid, @@ -39,7 +39,7 @@ // static WebBlobInfo WebBlobInfo::BlobForTesting(const WebString& uuid, const WebString& type, - long long size) { + uint64_t size) { return WebBlobInfo(uuid, type, size, mojo::MessagePipe().handle0); } @@ -48,7 +48,8 @@ const WebString& file_path, const WebString& file_name, const WebString& type) { - return WebBlobInfo(uuid, file_path, file_name, type, 0, -1, + return WebBlobInfo(uuid, file_path, file_name, type, 0, + std::numeric_limits<uint64_t>::max(), mojo::MessagePipe().handle0); } @@ -84,7 +85,7 @@ WebBlobInfo::WebBlobInfo(scoped_refptr<BlobDataHandle> handle, const WebString& type, - long long size) + uint64_t size) : is_file_(false), uuid_(handle->Uuid()), type_(type), @@ -97,7 +98,7 @@ const WebString& file_name, const WebString& type, double last_modified, - long long size) + uint64_t size) : is_file_(true), uuid_(handle->Uuid()), type_(type),
diff --git a/third_party/blink/renderer/platform/exported/web_runtime_features.cc b/third_party/blink/renderer/platform/exported/web_runtime_features.cc index ef919b5..f580fb8 100644 --- a/third_party/blink/renderer/platform/exported/web_runtime_features.cc +++ b/third_party/blink/renderer/platform/exported/web_runtime_features.cc
@@ -354,6 +354,10 @@ RuntimeEnabledFeatures::SetPaymentRequestHasEnrolledInstrumentEnabled(enable); } +void WebRuntimeFeatures::EnablePerformanceManagerInstrumentation(bool enable) { + RuntimeEnabledFeatures::SetPerformanceManagerInstrumentationEnabled(enable); +} + void WebRuntimeFeatures::EnablePermissionsAPI(bool enable) { RuntimeEnabledFeatures::SetPermissionsEnabled(enable); } @@ -594,10 +598,6 @@ RuntimeEnabledFeatures::SetAutomationControlledEnabled(enable); } -void WebRuntimeFeatures::EnableScheduledScriptStreaming(bool enable) { - RuntimeEnabledFeatures::SetScheduledScriptStreamingEnabled(enable); -} - void WebRuntimeFeatures::EnableScriptStreamingOnPreload(bool enable) { RuntimeEnabledFeatures::SetScriptStreamingOnPreloadEnabled(enable); }
diff --git a/third_party/blink/renderer/platform/instrumentation/resource_coordinator/DEPS b/third_party/blink/renderer/platform/instrumentation/resource_coordinator/DEPS index 0d498429..07468f5c 100644 --- a/third_party/blink/renderer/platform/instrumentation/resource_coordinator/DEPS +++ b/third_party/blink/renderer/platform/instrumentation/resource_coordinator/DEPS
@@ -1,3 +1,4 @@ include_rules = [ "+services/resource_coordinator/public", -] \ No newline at end of file + "+third_party/blink/renderer/platform/runtime_enabled_features.h", +]
diff --git a/third_party/blink/renderer/platform/instrumentation/resource_coordinator/frame_resource_coordinator.cc b/third_party/blink/renderer/platform/instrumentation/resource_coordinator/frame_resource_coordinator.cc index 1b5b1d3..7a7fe502 100644 --- a/third_party/blink/renderer/platform/instrumentation/resource_coordinator/frame_resource_coordinator.cc +++ b/third_party/blink/renderer/platform/instrumentation/resource_coordinator/frame_resource_coordinator.cc
@@ -4,8 +4,11 @@ #include "third_party/blink/renderer/platform/instrumentation/resource_coordinator/frame_resource_coordinator.h" +#include <memory> + #include "base/memory/ptr_util.h" #include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/renderer/platform/runtime_enabled_features.h" namespace blink { @@ -17,8 +20,11 @@ } // namespace // static -std::unique_ptr<FrameResourceCoordinator> FrameResourceCoordinator::Create( +std::unique_ptr<FrameResourceCoordinator> FrameResourceCoordinator::MaybeCreate( service_manager::InterfaceProvider* interface_provider) { + if (!RuntimeEnabledFeatures::PerformanceManagerInstrumentationEnabled()) + return nullptr; + return base::WrapUnique(new FrameResourceCoordinator(interface_provider)); }
diff --git a/third_party/blink/renderer/platform/instrumentation/resource_coordinator/frame_resource_coordinator.h b/third_party/blink/renderer/platform/instrumentation/resource_coordinator/frame_resource_coordinator.h index 88cb69b..f70aa48 100644 --- a/third_party/blink/renderer/platform/instrumentation/resource_coordinator/frame_resource_coordinator.h +++ b/third_party/blink/renderer/platform/instrumentation/resource_coordinator/frame_resource_coordinator.h
@@ -5,6 +5,8 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_INSTRUMENTATION_RESOURCE_COORDINATOR_FRAME_RESOURCE_COORDINATOR_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_INSTRUMENTATION_RESOURCE_COORDINATOR_FRAME_RESOURCE_COORDINATOR_H_ +#include <memory> + #include "base/macros.h" #include "services/resource_coordinator/public/mojom/coordination_unit.mojom-blink.h" #include "third_party/blink/renderer/platform/platform_export.h" @@ -20,7 +22,8 @@ USING_FAST_MALLOC(FrameResourceCoordinator); public: - static std::unique_ptr<FrameResourceCoordinator> Create( + // Returns nullptr if instrumentation is not enabled. + static std::unique_ptr<FrameResourceCoordinator> MaybeCreate( service_manager::InterfaceProvider*); ~FrameResourceCoordinator();
diff --git a/third_party/blink/renderer/platform/instrumentation/resource_coordinator/renderer_resource_coordinator.cc b/third_party/blink/renderer/platform/instrumentation/resource_coordinator/renderer_resource_coordinator.cc index 9a7de51a8..46294765 100644 --- a/third_party/blink/renderer/platform/instrumentation/resource_coordinator/renderer_resource_coordinator.cc +++ b/third_party/blink/renderer/platform/instrumentation/resource_coordinator/renderer_resource_coordinator.cc
@@ -7,6 +7,7 @@ #include "services/service_manager/public/cpp/connector.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/renderer/platform/heap/thread_state.h" +#include "third_party/blink/renderer/platform/runtime_enabled_features.h" namespace blink { @@ -17,7 +18,10 @@ } // namespace // static -void RendererResourceCoordinator::Initialize() { +void RendererResourceCoordinator::MaybeInitialize() { + if (!RuntimeEnabledFeatures::PerformanceManagerInstrumentationEnabled()) + return; + blink::Platform* platform = Platform::Current(); DCHECK(IsMainThread()); DCHECK(platform); @@ -33,9 +37,8 @@ } // static -RendererResourceCoordinator& RendererResourceCoordinator::Get() { - DCHECK(g_renderer_resource_coordinator); - return *g_renderer_resource_coordinator; +RendererResourceCoordinator* RendererResourceCoordinator::Get() { + return g_renderer_resource_coordinator; } RendererResourceCoordinator::RendererResourceCoordinator(
diff --git a/third_party/blink/renderer/platform/instrumentation/resource_coordinator/renderer_resource_coordinator.h b/third_party/blink/renderer/platform/instrumentation/resource_coordinator/renderer_resource_coordinator.h index 464c2aa..c7a79e6 100644 --- a/third_party/blink/renderer/platform/instrumentation/resource_coordinator/renderer_resource_coordinator.h +++ b/third_party/blink/renderer/platform/instrumentation/resource_coordinator/renderer_resource_coordinator.h
@@ -20,8 +20,9 @@ USING_FAST_MALLOC(RendererResourceCoordinator); public: - static void Initialize(); - static RendererResourceCoordinator& Get(); + // Only initializes if the instrumentation runtime feature is enabled. + static void MaybeInitialize(); + static RendererResourceCoordinator* Get(); // Used to switch the current renderer resource coordinator only for testing. static void SetCurrentRendererResourceCoordinatorForTesting(
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc index c4e42d31..c92e2ed 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
@@ -493,9 +493,10 @@ auto_load_images_(true), images_enabled_(true), allow_stale_resources_(false), - image_fetched_(false), - stale_while_revalidate_enabled_(false) { + image_fetched_(false) { DCHECK(console_logger_); + stale_while_revalidate_enabled_ = + RuntimeEnabledFeatures::StaleWhileRevalidateEnabledByRuntimeFlag(); InstanceCounters::IncrementCounter(InstanceCounters::kResourceFetcherCounter); if (IsMainThread()) MainThreadFetchersSet().insert(this); @@ -2078,6 +2079,7 @@ // requests. FetchParameters params(stale_resource->GetResourceRequest()); params.SetStaleRevalidation(true); + params.MutableResourceRequest().SetSkipServiceWorker(true); RawResource::Fetch( params, this, MakeGarbageCollected<StaleRevalidationResourceClient>(stale_resource));
diff --git a/third_party/blink/renderer/platform/network/encoded_form_data.cc b/third_party/blink/renderer/platform/network/encoded_form_data.cc index a01dfe7f..80413c5 100644 --- a/third_party/blink/renderer/platform/network/encoded_form_data.cc +++ b/third_party/blink/renderer/platform/network/encoded_form_data.cc
@@ -157,7 +157,7 @@ bytes.size()); } -unsigned long long EncodedFormData::SizeInBytes() const { +uint64_t EncodedFormData::SizeInBytes() const { unsigned size = 0; for (const FormDataElement& e : elements_) { switch (e.type_) {
diff --git a/third_party/blink/renderer/platform/network/encoded_form_data.h b/third_party/blink/renderer/platform/network/encoded_form_data.h index 4b0c6fc..a1771ca 100644 --- a/third_party/blink/renderer/platform/network/encoded_form_data.h +++ b/third_party/blink/renderer/platform/network/encoded_form_data.h
@@ -173,7 +173,7 @@ } // Size of the elements making up the EncodedFormData. - unsigned long long SizeInBytes() const; + uint64_t SizeInBytes() const; bool IsSafeToSendToAnotherThread() const;
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 9301be6..2bcf056 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1067,6 +1067,9 @@ status: "experimental", }, { + name: "PerformanceManagerInstrumentation", + }, + { // Flag enabling the performance observers buffered flag. The buffered // flag indicates whether or not the buffered entries should be loaded // into the observer's buffer upon registration. See crbug.com/725567. @@ -1221,9 +1224,6 @@ { name: "RTCUnifiedPlanByDefault", }, - { - name: "ScheduledScriptStreaming", - }, // WebSpeech API with both speech recognition and synthesis functionality // is not fully enabled on all platforms. {
diff --git a/third_party/blink/renderer/platform/scheduler/common/metrics_helper.cc b/third_party/blink/renderer/platform/scheduler/common/metrics_helper.cc index 2d57044..1576919 100644 --- a/third_party/blink/renderer/platform/scheduler/common/metrics_helper.cc +++ b/third_party/blink/renderer/platform/scheduler/common/metrics_helper.cc
@@ -35,7 +35,6 @@ case WebThreadType::kHRTFDatabaseLoaderThread: case WebThreadType::kOfflineAudioRenderThread: case WebThreadType::kReverbConvolutionBackgroundThread: - case WebThreadType::kScriptStreamerThread: case WebThreadType::kSharedWorkerThread: case WebThreadType::kUnspecifiedWorkerThread: case WebThreadType::kWebAudioThread:
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.cc index d1b33c3..8708ad5 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.cc
@@ -576,15 +576,18 @@ static const int main_thread_task_load_low_threshold = ::resource_coordinator::GetMainThreadTaskLoadLowThreshold(); - // Avoid sending duplicate IPCs when the state doesn't change. - if (load_percentage <= main_thread_task_load_low_threshold && - main_thread_task_load_state_ != MainThreadTaskLoadState::kLow) { - RendererResourceCoordinator::Get().SetMainThreadTaskLoadIsLow(true); - main_thread_task_load_state_ = MainThreadTaskLoadState::kLow; - } else if (load_percentage > main_thread_task_load_low_threshold && - main_thread_task_load_state_ != MainThreadTaskLoadState::kHigh) { - RendererResourceCoordinator::Get().SetMainThreadTaskLoadIsLow(false); - main_thread_task_load_state_ = MainThreadTaskLoadState::kHigh; + if (auto* renderer_resource_coordinator = + RendererResourceCoordinator::Get()) { + // Avoid sending duplicate IPCs when the state doesn't change. + if (load_percentage <= main_thread_task_load_low_threshold && + main_thread_task_load_state_ != MainThreadTaskLoadState::kLow) { + renderer_resource_coordinator->SetMainThreadTaskLoadIsLow(true); + main_thread_task_load_state_ = MainThreadTaskLoadState::kLow; + } else if (load_percentage > main_thread_task_load_low_threshold && + main_thread_task_load_state_ != MainThreadTaskLoadState::kHigh) { + renderer_resource_coordinator->SetMainThreadTaskLoadIsLow(false); + main_thread_task_load_state_ = MainThreadTaskLoadState::kHigh; + } } }
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc index 559bba3d..f1fa25d 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc
@@ -2537,8 +2537,11 @@ "estimated_queueing_time_for_window", queueing_time.InMillisecondsF()); - RendererResourceCoordinator::Get().SetExpectedTaskQueueingDuration( - queueing_time); + if (auto* renderer_resource_coordinator = + RendererResourceCoordinator::Get()) { + renderer_resource_coordinator->SetExpectedTaskQueueingDuration( + queueing_time); + } } void MainThreadSchedulerImpl::OnReportFineGrainedExpectedQueueingTime(
diff --git a/third_party/blink/renderer/platform/web_thread_type.cc b/third_party/blink/renderer/platform/web_thread_type.cc index fd20b80..2c17a78 100644 --- a/third_party/blink/renderer/platform/web_thread_type.cc +++ b/third_party/blink/renderer/platform/web_thread_type.cc
@@ -33,8 +33,6 @@ return "Database thread"; case WebThreadType::kWebAudioThread: return "WebAudio thread"; - case WebThreadType::kScriptStreamerThread: - return "ScriptStreamer thread"; case WebThreadType::kOfflineAudioRenderThread: return "OfflineAudioRender thread"; case WebThreadType::kReverbConvolutionBackgroundThread:
diff --git a/third_party/blink/web_tests/SlowTests b/third_party/blink/web_tests/SlowTests index 1bf999c4..5878b9bf 100644 --- a/third_party/blink/web_tests/SlowTests +++ b/third_party/blink/web_tests/SlowTests
@@ -1295,6 +1295,7 @@ crbug.com/874695 http/tests/devtools/sxg/sxg-cert-not-found.js [ Slow ] crbug.com/874695 http/tests/devtools/sxg/sxg-disable-cache.js [ Slow ] crbug.com/874695 virtual/threaded/animations/svg/animated-filter-svg-element.html [ Slow ] +crbug.com/874695 virtual/disable-blink-gen-property-trees/animations/svg/animated-filter-svg-element.html [ Slow ] crbug.com/874695 virtual/threaded/external/wpt/css/css-scroll-snap/snap-at-user-scroll-end-manual.html [ Slow ] crbug.com/874695 virtual/threaded/external/wpt/feature-policy/experimental-features/vertical-scroll-touch-block-manual.tentative.html [ Slow ] crbug.com/874695 virtual/threaded/external/wpt/feature-policy/experimental-features/vertical-scroll-wheel-block-manual.tentative.html [ Slow ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 8c04e3a7..9222235 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -23,7 +23,9 @@ ## Next 18 can be viewed in this run, by clicking on "Did not pass 11183": ## https://test-results.appspot.com/data/layout_results/linux-blink-rel/1237/webkit_layout_tests%20%28with%20patch%29/layout-test-results/results.html crbug.com/891427 virtual/threaded/animations/responsive/viewport-unit-transform-responsive.html [ Timeout ] +crbug.com/891427 virtual/disable-blink-gen-property-trees/animations/responsive/viewport-unit-transform-responsive.html [ Skip ] crbug.com/891427 virtual/threaded/animations/responsive/viewport-unit-translate-responsive.html [ Timeout ] +crbug.com/891427 virtual/disable-blink-gen-property-trees/animations/responsive/viewport-unit-translate-responsive.html [ Skip ] crbug.com/891427 virtual/fractional_scrolling/fast/scrolling/editor-command-scroll-page-scale.html [ Pass Failure ] crbug.com/891427 fast/replaced/replaced-breaking.html [ Failure ] crbug.com/891427 virtual/android/fullscreen/rendering/backdrop-video.html [ Failure ] @@ -32,6 +34,7 @@ crbug.com/891427 virtual/android/url-bar/bottom-and-top-fixed-sticks-to-top.html [ Failure ] ## Next 4 here: https://ci.chromium.org/p/chromium/builders/luci.chromium.try/linux_chromium_rel_ng/216317 crbug.com/891427 virtual/threaded/animations/timing/animation-duration-infinite.html [ Failure ] +crbug.com/891427 virtual/disable-blink-gen-property-trees/animations/timing/animation-duration-infinite.html [ Skip ] crbug.com/891427 editing/selection/drag-in-iframe.html [ Failure ] crbug.com/891427 fast/overflow/transformed-frame-scrollIntoView.html [ Crash ] @@ -382,12 +385,14 @@ crbug.com/882975 virtual/threaded/fast/events/pinch/gesture-pinch-zoom-prevent-in-handler.html [ Failure Pass ] crbug.com/882975 virtual/threaded/fast/events/pinch/scroll-visual-viewport-send-boundary-events.html [ Failure Pass ] crbug.com/884239 virtual/threaded/animations/animationworklet/worklet-animation-local-time-undefined.html [ Failure Pass ] +crbug.com/884239 virtual/disable-blink-gen-property-trees/animations/animationworklet/worklet-animation-local-time-undefined.html [ Skip ] # Subpixel rounding differences that are incorrect. crbug.com/836886 virtual/prefer_compositing_to_lcd_text/compositing/overflow/scaled-overflow.html [ Failure ] crbug.com/836886 compositing/overflow/scaled-overflow.html [ Failure ] crbug.com/836886 compositing/scrollbars/nested-overlay-scrollbars.html [ Failure ] # Flaky subpixel AA difference (not necessarily incorrect, but flaky) crbug.com/921105 virtual/threaded/animations/skew-notsequential-compositor.html [ Failure Pass ] +crbug.com/921105 virtual/disable-blink-gen-property-trees/animations/skew-notsequential-compositor.html [ Skip ] # Occasionally timeout, but the test coverage is still good crbug.com/919789 paint/invalidation/window-resize/ [ Timeout Pass ] @@ -2009,6 +2014,7 @@ crbug.com/432129 html/marquee/marquee-scroll.html [ Failure Pass ] crbug.com/326139 crbug.com/390125 media/video-frame-accurate-seek.html [ Failure Pass ] crbug.com/936462 virtual/threaded/animations/stability/animation-iteration-event-destroy-renderer.html [ Pass Timeout ] +crbug.com/936462 virtual/disable-blink-gen-property-trees/animations/stability/animation-iteration-event-destroy-renderer.html [ Skip ] crbug.com/421283 html/marquee/marquee-scrollamount.html [ Pass Failure ] # TODO(oshima): Mac Android are currently not supported. @@ -3026,6 +3032,8 @@ crbug.com/939181 virtual/not-site-per-process/external/wpt/html/browsers/origin/cross-origin-objects/cross-origin-objects.html [ Failure Timeout ] # ====== New tests from wpt-importer added here ====== +crbug.com/626703 [ Mac10.10 ] virtual/threaded/external/wpt/animation-worklet/worklet-animation-with-scroll-timeline-root-scroller.https.html [ Failure ] +crbug.com/626703 [ Mac10.11 ] virtual/threaded/external/wpt/animation-worklet/worklet-animation-with-scroll-timeline-root-scroller.https.html [ Failure ] crbug.com/626703 external/wpt/screen-orientation/onchange-event.html [ Timeout ] crbug.com/626703 external/wpt/html/semantics/forms/the-fieldset-element/accessibility/fieldset-div-display-contents-manual.html [ Skip ] crbug.com/626703 external/wpt/html/semantics/forms/the-fieldset-element/accessibility/role-manual.html [ Skip ] @@ -4472,6 +4480,12 @@ crbug.com/831509 virtual/navigation-mojo-response/external/wpt/service-workers/service-worker/skip-waiting-installed.https.html [ Failure Pass ] crbug.com/831509 virtual/outofblink-cors/external/wpt/service-workers/service-worker/skip-waiting-installed.https.html [ Failure Pass ] +# Stale While Revalidate +crbug.com/348877 external/wpt/fetch/stale-while-revalidate/fetch-sw.https.tentative.html [ Failure ] +crbug.com/348877 virtual/outofblink-cors/external/wpt/fetch/stale-while-revalidate/fetch-sw.https.tentative.html [ Failure ] +crbug.com/348877 external/wpt/fetch/stale-while-revalidate/fetch.tentative.html [ Failure ] +crbug.com/348877 virtual/outofblink-cors/external/wpt/fetch/stale-while-revalidate/fetch.tentative.html [ Failure ] + # Sheriff failures 2017-02-21 crbug.com/73609 http/tests/media/video-play-stall.html [ Pass Timeout ] @@ -5816,8 +5830,11 @@ crbug.com/922951 virtual/prefer_compositing_to_lcd_text/scrollbars/resize-scales-with-dpi-150.html [ Skip ] crbug.com/922951 virtual/scalefactor150/fast/events/synthetic-events/tap-on-scaled-screen.html [ Skip ] crbug.com/922951 virtual/threaded/animations/direction-and-fill/fill-mode-iteration-count-non-integer.html [ Skip ] +crbug.com/922951 virtual/disable-blink-gen-property-trees/animations/direction-and-fill/fill-mode-iteration-count-non-integer.html [ Skip ] crbug.com/922951 virtual/threaded/animations/direction-and-fill/fill-mode-missing-from-to-keyframes.html [ Skip ] +crbug.com/922951 virtual/disable-blink-gen-property-trees/animations/direction-and-fill/fill-mode-missing-from-to-keyframes.html [ Skip ] crbug.com/922951 virtual/threaded/animations/direction-and-fill/fill-mode.html [ Skip ] +crbug.com/922951 virtual/disable-blink-gen-property-trees/animations/direction-and-fill/fill-mode.html [ Skip ] crbug.com/922951 virtual/threaded/http/tests/devtools/tracing/console-timeline.js [ Skip ] crbug.com/922951 virtual/threaded/http/tests/devtools/tracing/frame-model-instrumentation.js [ Skip ] crbug.com/922951 virtual/threaded/http/tests/devtools/tracing/timeline-layout/timeline-layout-reason.js [ Skip ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index 01beab7a..09b2651a 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -120,6 +120,13 @@ }, { "prefix": "disable-blink-gen-property-trees", + "base": "animations", + "args": ["--disable-blink-features=BlinkGenPropertyTrees", + "--enable-threaded-compositing", + "--disable-composited-antialiasing"] + }, + { + "prefix": "disable-blink-gen-property-trees", "base": "compositing", "args": ["--disable-blink-features=BlinkGenPropertyTrees"] },
diff --git a/third_party/blink/web_tests/css3/filters/effect-reference-displacement-negative-scale-expected.html b/third_party/blink/web_tests/css3/filters/effect-reference-displacement-negative-scale-expected.html index f85fe44..f718ea6 100644 --- a/third_party/blink/web_tests/css3/filters/effect-reference-displacement-negative-scale-expected.html +++ b/third_party/blink/web_tests/css3/filters/effect-reference-displacement-negative-scale-expected.html
@@ -1,2 +1,2 @@ <!DOCTYPE html> -<div style="position: relative; top: 20px; left: 20px; width: 100px; height: 100px; background-color: green"></div> +<div style="width: 100px; height: 100px; background-color: green"></div>
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json index ef9a991..379450c 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json
@@ -6577,6 +6577,12 @@ {} ] ], + "web-nfc/NFCReader-manual.https.html": [ + [ + "/web-nfc/NFCReader-manual.https.html", + {} + ] + ], "web-nfc/nfc_hw_disabled-manual.https.html": [ [ "/web-nfc/nfc_hw_disabled-manual.https.html", @@ -6902,7 +6908,7 @@ "/acid/acid2/reftest.html", [ [ - "/acid/acid2/reference.html", + "/acid/acid2/px-reference.html", "==" ] ], @@ -107013,6 +107019,18 @@ {} ] ], + "html/semantics/embedded-content/the-img-element/img-with-containment-and-size.html": [ + [ + "/html/semantics/embedded-content/the-img-element/img-with-containment-and-size.html", + [ + [ + "/html/semantics/embedded-content/the-img-element/img-with-containment-and-size-ref.html", + "==" + ] + ], + {} + ] + ], "html/semantics/embedded-content/the-img-element/sizes/sizes-dynamic-001.html": [ [ "/html/semantics/embedded-content/the-img-element/sizes/sizes-dynamic-001.html", @@ -115585,6 +115603,11 @@ {} ] ], + "IndexedDB/resources/idbfactory-origin-isolation-iframe.html": [ + [ + {} + ] + ], "IndexedDB/support-promises.js": [ [ {} @@ -116960,6 +116983,11 @@ {} ] ], + "acid/acid2/px-reference.html": [ + [ + {} + ] + ], "acid/acid2/reference.html": [ [ {} @@ -164375,11 +164403,6 @@ {} ] ], - "html/browsers/origin/cross-origin-objects/cross-origin-objects-expected.txt": [ - [ - {} - ] - ], "html/browsers/origin/cross-origin-objects/frame-with-then.html": [ [ {} @@ -165405,11 +165428,6 @@ {} ] ], - "html/dom/elements/the-innertext-idl-attribute/setter-expected.txt": [ - [ - {} - ] - ], "html/dom/elements/the-innertext-idl-attribute/setter-tests.js": [ [ {} @@ -165465,11 +165483,6 @@ {} ] ], - "html/dom/reflection-forms-expected.txt": [ - [ - {} - ] - ], "html/dom/reflection-metadata-expected.txt": [ [ {} @@ -171880,6 +171893,11 @@ {} ] ], + "html/semantics/embedded-content/the-img-element/img-with-containment-and-size-ref.html": [ + [ + {} + ] + ], "html/semantics/embedded-content/the-img-element/img.complete-expected.txt": [ [ {} @@ -196010,11 +196028,26 @@ {} ] ], + "web-nfc/NFCReader-expected.txt": [ + [ + {} + ] + ], + "web-nfc/NFCReader-manual.https-expected.txt": [ + [ + {} + ] + ], "web-nfc/NFCReadingEvent_constructor.https-expected.txt": [ [ {} ] ], + "web-nfc/NFCWriter_push.https-expected.txt": [ + [ + {} + ] + ], "web-nfc/OWNERS": [ [ {} @@ -200140,6 +200173,16 @@ {} ] ], + "webxr/resources/webxr_test_asserts.js": [ + [ + {} + ] + ], + "webxr/resources/webxr_test_constants.js": [ + [ + {} + ] + ], "webxr/resources/webxr_util.js": [ [ {} @@ -207960,6 +208003,12 @@ {} ] ], + "IndexedDB/idbfactory-origin-isolation.html": [ + [ + "/IndexedDB/idbfactory-origin-isolation.html", + {} + ] + ], "IndexedDB/idbfactory_cmp.htm": [ [ "/IndexedDB/idbfactory_cmp.htm", @@ -220544,6 +220593,30 @@ {} ] ], + "css/css-masking/hit-test/clip-path-element-objectboundingbox-001.html": [ + [ + "/css/css-masking/hit-test/clip-path-element-objectboundingbox-001.html", + {} + ] + ], + "css/css-masking/hit-test/clip-path-element-objectboundingbox-002.html": [ + [ + "/css/css-masking/hit-test/clip-path-element-objectboundingbox-002.html", + {} + ] + ], + "css/css-masking/hit-test/clip-path-element-userspaceonuse-001.html": [ + [ + "/css/css-masking/hit-test/clip-path-element-userspaceonuse-001.html", + {} + ] + ], + "css/css-masking/hit-test/clip-path-shape-polygon-and-box-shadow.html": [ + [ + "/css/css-masking/hit-test/clip-path-shape-polygon-and-box-shadow.html", + {} + ] + ], "css/css-masking/idlharness.html": [ [ "/css/css-masking/idlharness.html", @@ -233712,6 +233785,12 @@ {} ] ], + "element-timing/images-repeated-resource.html": [ + [ + "/element-timing/images-repeated-resource.html", + {} + ] + ], "element-timing/observe-child-element.html": [ [ "/element-timing/observe-child-element.html", @@ -285035,7 +285114,9 @@ "screen-orientation/onchange-event.html": [ [ "/screen-orientation/onchange-event.html", - {} + { + "testdriver": true + } ] ], "screen-orientation/orientation-reading.html": [ @@ -286689,7 +286770,9 @@ "service-workers/service-worker/registration-mime-types.https.html": [ [ "/service-workers/service-worker/registration-mime-types.https.html", - {} + { + "timeout": "long" + } ] ], "service-workers/service-worker/registration-scope.https.html": [ @@ -293380,12 +293463,24 @@ {} ] ], + "web-nfc/NFCReader.html": [ + [ + "/web-nfc/NFCReader.html", + {} + ] + ], "web-nfc/NFCReadingEvent_constructor.https.html": [ [ "/web-nfc/NFCReadingEvent_constructor.https.html", {} ] ], + "web-nfc/NFCWriter_push.https.html": [ + [ + "/web-nfc/NFCWriter_push.https.html", + {} + ] + ], "web-nfc/idlharness.https.window.js": [ [ "/web-nfc/idlharness.https.window.html", @@ -293398,18 +293493,6 @@ {} ] ], - "web-nfc/nfc_push.https.html": [ - [ - "/web-nfc/nfc_push.https.html", - {} - ] - ], - "web-nfc/nfc_watch.https.html": [ - [ - "/web-nfc/nfc_watch.https.html", - {} - ] - ], "web-share/canShare-files.https.html": [ [ "/web-share/canShare-files.https.html", @@ -299084,6 +299167,24 @@ {} ] ], + "webxr/xrRay_constructor.https.html": [ + [ + "/webxr/xrRay_constructor.https.html", + {} + ] + ], + "webxr/xrRay_matrix.https.html": [ + [ + "/webxr/xrRay_matrix.https.html", + {} + ] + ], + "webxr/xrRigidTransform_constructor.https.html": [ + [ + "/webxr/xrRigidTransform_constructor.https.html", + {} + ] + ], "webxr/xrSession_cancelAnimationFrame.https.html": [ [ "/webxr/xrSession_cancelAnimationFrame.https.html", @@ -313884,7 +313985,7 @@ "support" ], "2dcontext/tools/tests.yaml": [ - "a11d7c0f35b1a6c908a26e7f584e900d80cfc13e", + "b6b52e7abac5a49e81a87228b991b00736859926", "support" ], "2dcontext/tools/tests2d.yaml": [ @@ -314568,7 +314669,7 @@ "testharness" ], "IndexedDB/bindings-inject-key.html": [ - "72edc91469f01709fe2da628aa73679a8b03a707", + "2fbe95ec8fc41878babd2ce1705787c8c4f4aa5f", "testharness" ], "IndexedDB/clone-before-keypath-eval.html": [ @@ -315107,6 +315208,10 @@ "0c2ab948531a194fdc76423b54a327e500cc0dad", "testharness" ], + "IndexedDB/idbfactory-origin-isolation.html": [ + "3f200877ba7c75a2bcb1bf670d0f0f6b25b2c69e", + "testharness" + ], "IndexedDB/idbfactory_cmp.htm": [ "7b301ece46d6b7f1753b8a61ae96674882fe81cb", "testharness" @@ -315927,6 +316032,10 @@ "21d72d75a6fa9389c05e968f3e9eebc386063e51", "testharness" ], + "IndexedDB/resources/idbfactory-origin-isolation-iframe.html": [ + "d405ea48e15e298241a2c400a6d04adbd054e1e5", + "support" + ], "IndexedDB/string-list-ordering.htm": [ "cc905e56ecf83ea4cd4f1fe2ccfac425cdc5f9d0", "testharness" @@ -317447,6 +317556,10 @@ "a17f4ecb85ab33ffce52d20e9cc8b1c7c109b0af", "support" ], + "acid/acid2/px-reference.html": [ + "5a350033e3c974c08f58db8c444ff9e2953de480", + "support" + ], "acid/acid2/reference.html": [ "66eed5ae3553c879af28cf8d4b479dac7adfd0f3", "support" @@ -317456,7 +317569,7 @@ "support" ], "acid/acid2/reftest.html": [ - "0f9b9ac023535183a534608e8df4a709ed269b11", + "80220cee7699343206378306a9e4c3fc0d048093", "reftest" ], "acid/acid2/test.html": [ @@ -317744,11 +317857,11 @@ "testharness" ], "animation-worklet/worklet-animation-with-scroll-timeline-and-display-none.https.html": [ - "6f981854d38877d42b1c7b63afdb9ec989a32d42", + "9841c575d1d76f9601f8c229c9c527618083fd21", "reftest" ], "animation-worklet/worklet-animation-with-scroll-timeline-and-overflow-hidden-ref.html": [ - "c6d7314e396e85225f245905f5afa17fb848b469", + "2004e6df905177a6165c66647e271938f6255685", "support" ], "animation-worklet/worklet-animation-with-scroll-timeline-and-overflow-hidden.https.html": [ @@ -317756,11 +317869,11 @@ "reftest" ], "animation-worklet/worklet-animation-with-scroll-timeline-ref.html": [ - "fe92232d9afa24f78e9cc7cc3bae341ba2a471bc", + "f30c861fb9a49b5c2691be0aa2f82297be17de41", "support" ], "animation-worklet/worklet-animation-with-scroll-timeline-root-scroller-ref.html": [ - "5810e1738c1d5927223037e97a7a14a52c405a5e", + "3b527dced72ee63fba3d5538d679b517ed583a26", "support" ], "animation-worklet/worklet-animation-with-scroll-timeline-root-scroller.https.html": [ @@ -339620,11 +339733,11 @@ "testharness" ], "css/css-animations/KeyframeEffect-getKeyframes.tentative-expected.txt": [ - "0972ff282d055f91e5879243c290e41772d7b17c", + "6418a80d7d603aaea01e24422a93c4d137fc1635", "support" ], "css/css-animations/KeyframeEffect-getKeyframes.tentative.html": [ - "81b0d18946440a34ed80e064ba9c9dd322d10f69", + "efb26e9502471983ef246eaafaaf7a49fd438c67", "testharness" ], "css/css-animations/KeyframeEffect-target.tentative.html": [ @@ -362307,6 +362420,22 @@ "96ccc2c19c428ddf3717c641db07bce710bb6690", "support" ], + "css/css-masking/hit-test/clip-path-element-objectboundingbox-001.html": [ + "22d4bc0b0d3feea9ea9355c90ddd3c714e995b0a", + "testharness" + ], + "css/css-masking/hit-test/clip-path-element-objectboundingbox-002.html": [ + "1932848a13563f1d825eac02091d4a43b11ff725", + "testharness" + ], + "css/css-masking/hit-test/clip-path-element-userspaceonuse-001.html": [ + "2b8beab9100a3402b1e43551713b245cbcefe235", + "testharness" + ], + "css/css-masking/hit-test/clip-path-shape-polygon-and-box-shadow.html": [ + "23009f76e502ed11f2c247035167234857d9ce2c", + "testharness" + ], "css/css-masking/idlharness-expected.txt": [ "f188afc0043b727bb09f4342f294a737793f51e3", "support" @@ -365484,11 +365613,11 @@ "testharness" ], "css/css-properties-values-api/register-property-syntax-parsing-expected.txt": [ - "9137fe140b2a142e6872aeac9a4690eb3f3c6ddb", + "9e133e5b38f5cbd7756e407f271f15943b727748", "support" ], "css/css-properties-values-api/register-property-syntax-parsing.html": [ - "4ce514f01c87917d2e5aac4d402176ba88daf5a0", + "43cff0dbe283e33d0d79763d01e5744774cf0b9f", "testharness" ], "css/css-properties-values-api/register-property.html": [ @@ -375852,7 +375981,7 @@ "testharness" ], "css/css-transforms/parsing/transform-valid.html": [ - "fbde8eaf2d23306b34125eeeafc66a692eaad301", + "e6f10154cb6a1d8b5c9eddbb8f1e7c3b2756554e", "testharness" ], "css/css-transforms/parsing/translate-parsing-invalid.html": [ @@ -404712,7 +404841,7 @@ "testharness" ], "element-timing/buffer-before-onload.html": [ - "4d59d4afc9f8e501a0a764cbce980d0d276250fe", + "1fd02776927d193d68702fce5248835ed26f8dea", "testharness" ], "element-timing/cross-origin-element.sub.html": [ @@ -404724,11 +404853,15 @@ "testharness" ], "element-timing/image-TAO-wildcard.sub.html": [ - "6d5abe21c3c353e55b058655684197ba986d8e64", + "3ba12a7d01f1c8b9f0069f0382d6fcc4bda2e639", "testharness" ], "element-timing/image-not-fully-visible.html": [ - "8ab3f343635a0e2c7704b4548b9b9dfa76388200", + "d3e2c105bffdf9a78ba2b51ade49dbb0df91e2fe", + "testharness" + ], + "element-timing/images-repeated-resource.html": [ + "18c72cdad1b310972a35dab0878c92af1bba75bf", "testharness" ], "element-timing/observe-child-element.html": [ @@ -404736,23 +404869,23 @@ "testharness" ], "element-timing/observe-elementtiming.html": [ - "c148d33ab906da4588feea10370783b8c4b2404b", + "9170b36d7c7fbd14683a8d56afb9f174aac23686", "testharness" ], "element-timing/observe-large-image.html": [ - "ef3eab8107b2824a60c955b54f58ef2cb4e4c3df", + "fb2884381ab30e3c6b05150ad4fbb47fe2c81f32", "testharness" ], "element-timing/observe-multiple-images.html": [ - "e56092c65bf4ab422875b54e25a5315d9f6da8c9", + "aa91aa839896c166e46fe76b31eb169b0bf81857", "testharness" ], "element-timing/observe-svg-image.html": [ - "327ab69668b20addd31df5e9ae2ce655f021d81b", + "f127152cf8693481703e5a38306204232e4a9ce5", "testharness" ], "element-timing/progressively-loaded-image.html": [ - "6fdff39d53848546e113b72ca17e38fd9b0dabc7", + "cf54e1e5c7a281bc59ba4172cd8ee3d7efdab099", "testharness" ], "element-timing/resources/TAOImage.py": [ @@ -404764,7 +404897,7 @@ "support" ], "element-timing/resources/element-timing-helpers.js": [ - "0be97e403f27b4ab1e47fda1c114110c6e2a3edb", + "e952930ef5e49cf9da25b29c333e752e09c75e60", "support" ], "element-timing/resources/iframe-with-square.html": [ @@ -407460,11 +407593,11 @@ "support" ], "feature-policy/experimental-features/lazyload/lazyload-enabled-image-tentative.sub.html": [ - "7a564be5f891f869deb8d316d3750996097549cd", + "e277d9e8ad42307e9ab47038b534f8fc974c492b", "testharness" ], "feature-policy/experimental-features/lazyload/lazyload-enabled-tentative.sub.html": [ - "ca040b0fcbb030c0d50d1f1ed2537ab3ab1a40df", + "ebed07bab5abdd15dc95a84eddd03bc4907386be", "testharness" ], "feature-policy/experimental-features/lazyload/lazyload-enabled-tentative.sub.html.headers": [ @@ -413195,24 +413328,20 @@ "a5d8e59406e870c7be80dfe57ef404ddc7b288a4", "manual" ], - "html/browsers/origin/cross-origin-objects/cross-origin-objects-expected.txt": [ - "770e1bffa9257ac80615cd5b664c76cc2e2139f2", - "support" - ], "html/browsers/origin/cross-origin-objects/cross-origin-objects-on-new-window.html": [ "3ad0de6a3a3fd7fb2304154d602226e9d5299724", "testharness" ], "html/browsers/origin/cross-origin-objects/cross-origin-objects.html": [ - "888343b45bcd901b6b665453170c41ad4cc5a753", + "f664819d3404498dc1ef9ede50c7b1b28fad1933", "testharness" ], "html/browsers/origin/cross-origin-objects/frame-with-then.html": [ - "1127995ea84dcd94fe87642b95b34e597f30abba", + "3eedeca38af5a9c71fc831306b029da76dca47af", "support" ], "html/browsers/origin/cross-origin-objects/frame.html": [ - "0d81624597dfcf6fd7ded4ce8bb7a9895afd2085", + "3226c8719311f937bcee4ad3b42b840828d0f600", "support" ], "html/browsers/origin/cross-origin-objects/win-documentdomain.sub.html": [ @@ -413972,7 +414101,7 @@ "support" ], "html/browsers/windows/embedded-opener-remove-frame.html": [ - "9bce93f0888ea25d713944efc9c8a4fdcc371da0", + "a66f52e5f649a1c473822d58182ee042a862d974", "testharness" ], "html/browsers/windows/embedded-opener.html": [ @@ -415175,10 +415304,6 @@ "3d504b682e5c031b2187f48891eaedd4157b7674", "testharness" ], - "html/dom/elements/the-innertext-idl-attribute/setter-expected.txt": [ - "e2639306498d436d232262e13f24bcc5b4f76e59", - "support" - ], "html/dom/elements/the-innertext-idl-attribute/setter-tests.js": [ "99ae5ec18516ed7b25176da2da49478587ec084f", "support" @@ -415236,17 +415361,13 @@ "support" ], "html/dom/reflection-embedded-expected.txt": [ - "d109dc59b5f30805bf7761728f6e5de764045359", + "aea251d94c702f34494778b753461e89dde316cf", "support" ], "html/dom/reflection-embedded.html": [ "0a362f817a5e7fb630cc4c0317fc80fe59cf4ab3", "testharness" ], - "html/dom/reflection-forms-expected.txt": [ - "6be164ee0c87236aedd16300028d43092831fb2a", - "support" - ], "html/dom/reflection-forms.html": [ "2fe251a6f4c26cd5f679572350717b3b87698a64", "testharness" @@ -415256,7 +415377,7 @@ "testharness" ], "html/dom/reflection-metadata-expected.txt": [ - "408ab6f3d2a70f6d4bae4242d28a982354f002d8", + "7cc499c410c19aef87da788c617ffb86321f18db", "support" ], "html/dom/reflection-metadata.html": [ @@ -415300,7 +415421,7 @@ "testharness" ], "html/dom/reflection.js": [ - "9a98478b9dcda50635555ffd72295bf75412ec2f", + "3f8d7c1e7675d69bc53bda1e7f7c5efeb002f038", "support" ], "html/dom/resources/self-origin-subframe.html": [ @@ -422884,7 +423005,7 @@ "support" ], "html/semantics/embedded-content/the-canvas-element/size.attributes.parse.whitespace.html": [ - "f4662b45f9404693e016ba99302be96ccbc150a4", + "efb263eb8d53b137ae06ce6a26d7d918ed2842d9", "testharness" ], "html/semantics/embedded-content/the-canvas-element/size.attributes.parse.whitespace.png": [ @@ -423028,7 +423149,7 @@ "support" ], "html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.whitespace.html": [ - "9d85fe7320ac16c9bf90a3446a85e7c7221dbe18", + "8a01f57ea5de049f9a73c01af3453a34eaf05422", "testharness" ], "html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.whitespace.png": [ @@ -423915,6 +424036,14 @@ "d26878c9f22d53bb44be515fa9f0ffbb90a71cbd", "support" ], + "html/semantics/embedded-content/the-img-element/img-with-containment-and-size-ref.html": [ + "56176c4b71eb4960f3e11fd323cc09964ce3f3a9", + "support" + ], + "html/semantics/embedded-content/the-img-element/img-with-containment-and-size.html": [ + "a095adc7cf6775e9c9b63832c0c5c9df23756b6c", + "reftest" + ], "html/semantics/embedded-content/the-img-element/img.complete-expected.txt": [ "aba6affa8084a3556e8db7ecd8948093cef555f9", "support" @@ -432024,7 +432153,7 @@ "support" ], "interfaces/web-nfc.idl": [ - "11a36cde6eb7d2d287310635e867f2fe65f4a4fa", + "a5709161bdb45f7a02bdd9b78f73febd8d21e222", "support" ], "interfaces/web-share.idl": [ @@ -432076,7 +432205,7 @@ "support" ], "interfaces/webxr.idl": [ - "899bb0daa008ccb547d47b0a96c383c40e7e776e", + "e91a50c28ee7acbcc5e04ed9e7b929def64afee3", "support" ], "interfaces/worklets.idl": [ @@ -456192,7 +456321,7 @@ "testharness" ], "screen-orientation/onchange-event.html": [ - "401af096631a2cfdf44f3c920454eb1958925c3c", + "635ff8207a2f421a198f6738095ef2e811ea68c1", "testharness" ], "screen-orientation/orientation-reading-expected.txt": [ @@ -458496,7 +458625,7 @@ "testharness" ], "service-workers/service-worker/registration-mime-types.https.html": [ - "9ae5f0956fbaff5c2d94c27e3efd5d402acac36a", + "1d39ecfb086c4dd665f3350468e892381c44d15a", "testharness" ], "service-workers/service-worker/registration-scope.https.html": [ @@ -458536,7 +458665,7 @@ "testharness" ], "service-workers/service-worker/resource-timing.https.html": [ - "123bbc87c57e857a517ab792717f1cf65b9a3a16", + "7fc3fcd9e48b445aad5f34d658171d18c3caa42f", "testharness" ], "service-workers/service-worker/resources/404.py": [ @@ -463948,7 +464077,7 @@ "support" ], "tools/manifest/vcs.py": [ - "5e5b8df597bbcd360165158cabc82c30d382af53", + "ecd565cf9e7bd5719b8d1d7dd23cd89c61ad1bf6", "support" ], "tools/py27-flake8.ini": [ @@ -468424,7 +468553,7 @@ "support" ], "tools/wptrunner/wptrunner/metadata.py": [ - "8699ac4fc734c1a45a4b7723b3dceea27590f8fa", + "b951ea5b9b43b27d2cf37ccbe17686c780cbd326", "support" ], "tools/wptrunner/wptrunner/products.py": [ @@ -471199,6 +471328,22 @@ "8a08fe0a70edaebb542a4d2ec3f033476fc8b865", "testharness" ], + "web-nfc/NFCReader-expected.txt": [ + "7643110f7e4bfde7d18d5d1000b5f8957f8ac826", + "support" + ], + "web-nfc/NFCReader-manual.https-expected.txt": [ + "c1656d832d350763699e4ea1d0827c1c077d5dbe", + "support" + ], + "web-nfc/NFCReader-manual.https.html": [ + "a3171c3544e4640ca35d2a6de451d05cf8aa008c", + "manual" + ], + "web-nfc/NFCReader.html": [ + "5a0e88433f23d0ca8f71df8d9fcd0c7ebe036345", + "testharness" + ], "web-nfc/NFCReadingEvent_constructor.https-expected.txt": [ "c0163f7946ac4c87e9d0ebe96447e00ca7b92dae", "support" @@ -471207,6 +471352,14 @@ "6cfcc0d3bddae2430152504fce839d1b96b12ce0", "testharness" ], + "web-nfc/NFCWriter_push.https-expected.txt": [ + "78ff3bdf6d929835066b780c626f82ebef2df248", + "support" + ], + "web-nfc/NFCWriter_push.https.html": [ + "f5a0a84273681f7c2af402061fd3e6fb456cac76", + "testharness" + ], "web-nfc/OWNERS": [ "2a0e82019549591b88878ca70fc6baf616d34c29", "support" @@ -471235,10 +471388,6 @@ "ac9674bcc76b37db5e470a2a410de613610d2ec9", "support" ], - "web-nfc/nfc_push.https.html": [ - "c83217e12bdf8b9928f6d510bca4f9b4b77db59e", - "testharness" - ], "web-nfc/nfc_push_ArrayBuffer-manual.https-expected.txt": [ "5d17eaffffb98814dcd28399c8cc03fe608b2d7c", "support" @@ -471299,10 +471448,6 @@ "2a055256ce0b6cd95bd44328b635a66a6faf55aa", "support" ], - "web-nfc/nfc_watch.https.html": [ - "455b6437a8e1a16dc790adb0956fe72bf909af2c", - "testharness" - ], "web-nfc/resources/nfc_help.js": [ "52d2710fd8173be6f6541b93ae8fa6d9251620f7", "support" @@ -471676,7 +471821,7 @@ "testharness" ], "webaudio/the-audio-api/the-audiocontext-interface/audiocontextoptions.html": [ - "3a11074a41c0918343291505526eaf08a01117a3", + "bee1aa835bf64ef31e7bc61e4bc8e9e8d0c43ec3", "testharness" ], "webaudio/the-audio-api/the-audionode-interface/audionode-channel-rules.html": [ @@ -474080,7 +474225,7 @@ "testharness" ], "webrtc/RTCError.html": [ - "e83dba27453cc4677479d7d601e169997ec63610", + "4d0726093c19c2828e59e7f61d2f65954c8075fc", "testharness" ], "webrtc/RTCIceCandidate-constructor-expected.txt": [ @@ -479227,6 +479372,14 @@ "2d8e5b387dc88588921ccfa49dd14db58009900c", "support" ], + "webxr/resources/webxr_test_asserts.js": [ + "2253ffc2d39d268142711fca7f81dda3fc6a318c", + "support" + ], + "webxr/resources/webxr_test_constants.js": [ + "aab0417aed0b08e930347ff666cd672d271b8e00", + "support" + ], "webxr/resources/webxr_util.js": [ "e61e4227715f8184b9d7b6dbdd37be82c8680f78", "support" @@ -479283,6 +479436,18 @@ "971a6d78a1e1ee1c51141a475868185318680495", "testharness" ], + "webxr/xrRay_constructor.https.html": [ + "0e78cffea4697956951be7833c1a0b2ba6bcf24a", + "testharness" + ], + "webxr/xrRay_matrix.https.html": [ + "3c9cea0849f77063d3c86eff7f2d85e4830c851c", + "testharness" + ], + "webxr/xrRigidTransform_constructor.https.html": [ + "abaf8bf9ebe2fed3c99cef5bf52d697b9e8ed1c8", + "testharness" + ], "webxr/xrSession_cancelAnimationFrame.https.html": [ "cc7b8802cba01ac03adb53a06308acd5642dd0af", "testharness"
diff --git a/third_party/blink/web_tests/external/wpt/2dcontext/tools/tests.yaml b/third_party/blink/web_tests/external/wpt/2dcontext/tools/tests.yaml index a11d7c0..b6b52e7a 100644 --- a/third_party/blink/web_tests/external/wpt/2dcontext/tools/tests.yaml +++ b/third_party/blink/web_tests/external/wpt/2dcontext/tools/tests.yaml
@@ -198,7 +198,7 @@ ("empty", "", None), ("onlyspace", " ", None), ("space", " 100", 100), - ("whitespace", "\n\t\f100", 100), + ("whitespace", "\r\n\t\f100", 100), ("plus", "+100", 100), ("minus", "-100", None), ("octal", "0100", 100), @@ -235,11 +235,13 @@ for name, string, exp in cases: code = "" code, testing, expected = gen(name, string, exp, code) + # We need to replace \r with 
 because \r\n gets converted to \n in the HTML parser. + htmlString = string.replace('\r', '
') tests.append( { "name": "size.attributes.parse.%s" % name, "desc": "Parsing of non-negative integers", "testing": testing, - "canvas": 'width="%s" height="%s"' % (string, string), + "canvas": 'width="%s" height="%s"' % (htmlString, htmlString), "code": code, "expected": expected } )
diff --git a/third_party/blink/web_tests/external/wpt/acid/acid2/px-reference.html b/third_party/blink/web_tests/external/wpt/acid/acid2/px-reference.html new file mode 100644 index 0000000..5a35003 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/acid/acid2/px-reference.html
@@ -0,0 +1,272 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> +<html> + <head> + <title>The Second Acid Test (pixel-for-pixel reference version)</title> + <style type="text/css"> + * + { + margin: 0; + padding: 0; + } + + html + { + font: 12px sans-serif; + + overflow: hidden; + + color: red; + background: white; + } + + #top + { + font: 2em / 24px sans-serif; + + margin: 2em 3.5em 0; + + text-align: left; + white-space: pre; + + color: navy; + } + + .picture + { + margin: 3em 1em 1em 6em; + } + + .line + { + height: 1em; + + border: 0 solid black; + background: yellow; + } + + .one + { + width: 0; + margin-left: 5em; + + border-width: 0 2em; + } + + .two + { + width: 4em; + margin-left: 3em; + + border-width: 0 2em; + } + + .three + { + width: 8em; + margin-left: 2em; + + border-width: 0 1em; + } + + /* the eyes, in all their three-layer glory + + these need to appear with both background layers as on hidpi displays + the two background layers don't just create a solid yellow background */ + .eyes + { + position: relative; + + width: 12em; + height: 2em; + margin-left: 1em; + + background: red; + } + + .eyes .lower + { + position: absolute; + z-index: 1; /* redundant, but make stacking explicit */ + + width: 9em; + height: 2em; + margin-left: 1em; + + border-left: solid 1em yellow; + background: fixed url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91JpzAAAABnRSTlMAAAAAAABupgeRAAAABmJLR0QA%2FwD%2FAP%2BgvaeTAAAAEUlEQVR42mP4%2F58BCv7%2FZwAAHfAD%2FabwPj4AAAAASUVORK5CYII%3D'); + } + + .eyes .upper + { + position: absolute; + z-index: 2; /* redundant, but make stacking explicit */ + + width: 10em; + height: 2em; + margin-left: 0; + + border: solid 1em black; + border-width: 0 1em; + background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91JpzAAAABnRSTlMAAAAAAABupgeRAAAABmJLR0QA%2FwD%2FAP%2BgvaeTAAAAEUlEQVR42mP4%2F58BCv7%2FZwAAHfAD%2FabwPj4AAAAASUVORK5CYII%3D') fixed 1px 0; + } + + .eyes .img + { + position: absolute; + z-index: 3; /* redundant, but make stacking explicit */ + + width: 8em; + height: 2em; + margin-left: 2em; + + background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAAAYCAYAAAFy7sgCAAAGsUlEQVRo3u2ZbWwcZxHHf3s%2B7LNbO3ZjXBtowprGODRX0qpNQCjmJKuVKhMl1P2AkCwhFOIKkCBSm9IXavGFKAixIAECwkmWo5MrhRI3Ub40IEwQgp6aIDg3Cd6eEqyIHEteah%2B1E69vhw%2BZtTaX8704ZzkKjHS6271nZ56ZZ%2BY%2F%2F%2BdZKF%2FCwYshx3EkkggLsD1v4FQkEZZYLCbAKyG9%2Ba9EIsG6hnUAf8x74K3aUC3j4%2BM54HcsR2oAIomwZOezkv%2FnSHpYNh%2BNCmAE7xv94zvFdd1bHsjMZmQkPSxAJP%2B%2FfuBLwK54PC7JZFKAVJmzXLBt2w%2FMvcDLwIb8QS8CeJ4nkURYIomw7J%2FYJ8BvSiiXptGGxWds2%2Fa9%2Bnaxh%2BYAD%2Bgt04NDgABTpQY2cvvSFLzw86gWeBVwC8SzlOSv2YeBPfmDBoBHgKmR9LBEEmHZfDTqGykqfkUE0nA78BzQGfSgUeP3wNeTXwXg7MwZDhw4UHL6ra2ti79%2FOvljgG8AZ4H64Lhm4MvAocxsRppGG%2FxcXihlwLIs6R%2FfKV2HO%2F26uA94pdDYUKUZUU7W1RQYXA98Gnhaf5%2FXWX0HeAHYoQonqa4sZSOsSWMCWeC9Yko%2BCQwBe4E6oNc0Tc91XTl1%2BaTsn9gnI%2Blhyc5nZWxsrBIkKSbl2tiic3tW53YDEwOKaoFBrcOfqKee53lG9xsPMjV784r%2F4lO%2FpPvyJ9iyZcuvFSaXK5XYeAZ4CDgGvB3MS4B54LQuWYPeuy4iRFsevsXqpuYoqVQKIH2bK1CuDQNo11o4XUzh%2FcDWYIe1LEtyuZx4niee54njOGKapgfsqlL%2Bl2OjEXg8nxrc1dJ0h3hbtL%2BGCtz7KPBF4CuBe9uB15VafE8hr9qylI3HgG8C2%2FK7VyHZoJj7MrBRm30qFotJMpkU27YlHo%2F7Ha5a%2BV%2FKRkSJ4KuKRLVLKapTjB1SzAVIjY2NSXY%2BKyPpYdk%2FsU9OXT4pruv6BdZbBQfKsVGnvWlIe1VB6VQO8JxC1vZYLCbZ%2BaxsPhpdZDyRRFhG0sPiOE6ldKBg2lRg4xF1YCDIIIKN7DGgD3gH%2BBXwejKZfPrs2tPs%2FvPN2bKuYR1nd7xLKBSSJeqoXKnERjPwNWAG%2BLn2rZuM%2B4Tpml6vaWlp4eLcxVusZq5lCgVgOVKJjRqdX86ffL4D5wIoZACnTpw4wRMdT96i%2FImOJxERAs4uVyqxUacF%2FPdiCj%2BjdRBRGFtwXVdG0sPSdbhTmkYbpH98p2RmM2JZlig1vl0GWo4NQ%2Fn%2Bs5pKRXfwjweaxy7TND3HcRZbfC6X8xVPVQlGy7WxVWlO5XRXFXm6EZmrQuSXYyPE3SiVoEhE6Wyr0u2rumO6zv%2B21AFdQAswC1wCMuUCXCmyWQus103Qg8qlDO0lxwOb%2Fl4FiK3AB3VS%2FuKKLtK%2FgbeAnwG%2FvUODuRw%2FFrR0H1UC75fwu8oJ%2FhFsW5VIG%2FBUgEIN6Y65O4AHu4Ap0zQ9y7LEcZyb9lRBUHQcRyzL8unZVBW5bFWAvAp%2BhDQ2g4F47dUYtlU6obXA54DnVdFLekjUGGifh4AFy7LEdV3xj3X9I66m0QZpGm2QrsOd0j%2B%2BU0bSw5KZzYjrun6HWlAd961i4FfCj0aN1Usau%2Bc1lmuXPFwvAEumUut7tQQvAb%2FXb%2FT0bCAej9cODg7yt%2Bm%2F8q2%2F7OUHZ76PnZ1k2p0mJzlykmPancbOTnL0whHs7CQfb%2B5mx2d3sH79%2BtCRI0c6FeaOr9ICrIQfLvA%2B8BGNXxi4R6HrisJVUWrxAVW2oMFf0Aczim8o3kV6enowDIPjF9%2Fk%2BMU3S3rrjzMMg56eHr%2BxP7qKFbASfojG6kpeDGs1tiW53RxwWT%2Bin5q8w4xpQK5evQpAR30H7ZH2khNvj7TTUd8BgD4rqmu1ZKX8qNeY%2BfHz4zlXDgT5E8tpCTUq7XSBC4Euv8227TV9fX1E73%2BYtvo27BmbS9cvFVTY3bSRFza9yOcf6Gfmygy7d%2B%2Fm%2FPnzF4DvrsBLhnJlJfwIKXxv1PheAE4qK6p4H9AGbNKTuhngBPBPXYRe4IemaT5kWZbR19fHNbmGnZ1k4r3U4glDR30Hm5qjbGjsImJEOHbsGHv27JFz5869o0eFq01Jq%2BmHAXwI6FFKagMTgHM7GzFDS%2BoeLSMv7zjzC9x4Y7gxFovVDAwMEI1GaWlpWSzRVCrFwYMH%2FXfxZ4AfAa8B%2F7lDaGg1%2FQgp43lfK0yqtRMuJa3ceKe5DfgYsCYAZ2ngD8CfAkzqTpW7xY%2F%2FSznyX%2FVeUb2kVmX4AAAAAElFTkSuQmCC'); + } + + /* lines six to nine are the nose + + (note these are scarcely changed from the test as border anti-aliasing + quickly differs) */ + .nose + { + width: 12em; + height: 4em; + margin-left: 0; + + border-width: 0 1em; + } + + .nose > div + { + height: 0; + padding: 1em 1em 3em; + + background: yellow; + } + + .nose div div + { + width: 2em; + height: 2em; + margin-left: 4em; + + background: red; + } + + .nose div:hover div:before + { + border-bottom-color: blue; + } + + .nose div:hover div:after + { + border-top-color: blue; + } + + .nose div div:before + { + display: block; + + height: 0; + + content: ''; + + border-width: 1em; + border-style: none solid solid; + border-color: red yellow black yellow; + } + + .nose div div:after + { + display: block; + + height: 0; + + content: ''; + + border-width: 1em; + border-style: solid solid none; + border-color: black yellow red yellow; + } + + /* lines ten and eleven are the smile */ + .ten + { + width: 10em; + margin-left: 1em; + + border-width: 0 1em; + } + + .ten div + { + width: 6em; + height: 1em; + margin-left: 1em; + + border: solid black; + border-width: 0 1em; + background: transparent; + } + + .eleven + { + width: 10em; + margin-left: 1em; + + border-width: 0 1em; + } + + .eleven div + { + width: 6em; + height: 1em; + margin-left: 2em; + + background: black; + } + + /* bottom of the face */ + .twelve + { + width: 8em; + margin-left: 2em; + + border-width: 0 1em; + } + + .thirteen + { + width: 4em; + margin-left: 3em; + + border-width: 0 2em; + } + + .fourteen + { + width: 0; + margin-left: 5em; + + border-width: 0 2em; + } + </style> + </head> + <body> + <h2 id="top">Hello World!</h2> + <div class="picture"> + <div class="line one"></div> + <div class="line two"></div> + <div class="line three"></div> + + <div class="eyes"><div class=lower></div><div class=upper></div><div class=img></div></div> + + <div class="line nose"><div><div></div></div></div> + + <div class="line ten"><div></div></div> + <div class="line eleven"><div></div></div> + <div class="line twelve"></div> + <div class="line thirteen"></div> + <div class="line fourteen"></div> + </div> + </body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/acid/acid2/reftest.html b/third_party/blink/web_tests/external/wpt/acid/acid2/reftest.html index 0f9b9ac..80220ce 100644 --- a/third_party/blink/web_tests/external/wpt/acid/acid2/reftest.html +++ b/third_party/blink/web_tests/external/wpt/acid/acid2/reftest.html
@@ -1,6 +1,8 @@ <!doctype html> +<html class=reftest-wait> <title>Acid2 reftest</title> -<link rel="match" href="reference.html"> +<link rel="match" href="px-reference.html"> +<script src="/common/reftest-wait.js"></script> <style> * { margin: 0; @@ -12,4 +14,12 @@ height: 300px; } </style> -<iframe src="test.html#top"></iframe> +<script> +function frameLoaded(frame) { + let fwin = frame.contentWindow; + let fdoc = frame.contentDocument; + fdoc.querySelector("#top").scrollIntoView(); + takeScreenshot(); +} +</script> +<iframe src="test.html" onload="frameLoaded(this)"></iframe>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-animations/KeyframeEffect-getKeyframes.tentative-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-animations/KeyframeEffect-getKeyframes.tentative-expected.txt index 0972ff2..6418a80 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-animations/KeyframeEffect-getKeyframes.tentative-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/css-animations/KeyframeEffect-getKeyframes.tentative-expected.txt
@@ -22,6 +22,6 @@ FAIL KeyframeEffect.getKeyframes() returns expected values for animations with CSS variables as keyframe values assert_equals: properties on ComputedKeyframe #0 expected "composite,computedOffset,easing,offset,transform" but got "composite,computedOffset,easing,offset" FAIL KeyframeEffect.getKeyframes() returns expected values for animations with CSS variables as keyframe values in a shorthand property assert_equals: properties on ComputedKeyframe #0 expected "composite,computedOffset,easing,marginBottom,marginLeft,marginRight,marginTop,offset" but got "composite,computedOffset,easing,offset" FAIL KeyframeEffect.getKeyframes() returns expected values for animations with a CSS variable which is overriden by the value in keyframe assert_equals: properties on ComputedKeyframe #0 expected "color,composite,computedOffset,easing,offset" but got "composite,computedOffset,easing,offset" -FAIL KeyframeEffect.getKeyframes() returns expected values for animations with only custom property in a keyframe assert_equals: properties on ComputedKeyframe #1 expected "composite,computedOffset,easing,offset,transform" but got "--not-used,composite,computedOffset,easing,offset" +FAIL KeyframeEffect.getKeyframes() returns expected values for animations with only custom property in a keyframe assert_equals: value for 'transform' on ComputedKeyframe #0 expected "translate(100px)" but got "translate(100px, 0px)" Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-animations/KeyframeEffect-getKeyframes.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-animations/KeyframeEffect-getKeyframes.tentative.html index 81b0d18..efb26e9 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-animations/KeyframeEffect-getKeyframes.tentative.html +++ b/third_party/blink/web_tests/external/wpt/css/css-animations/KeyframeEffect-getKeyframes.tentative.html
@@ -679,7 +679,7 @@ { offset: 0, computedOffset: 0, easing: "ease", composite: "auto", transform: "none" }, { offset: 1, computedOffset: 1, easing: "ease", composite: "auto", - transform: "translate(100px, 0px)" }, + transform: "translate(100px)" }, ]; for (let i = 0; i < frames.length; i++) { assert_frames_equal(frames[i], expected[i], "ComputedKeyframe #" + i); @@ -743,7 +743,7 @@ const expected = [ { offset: 0, computedOffset: 0, easing: "ease", composite: "auto", - transform: "translate(100px, 0px)" }, + transform: "translate(100px)" }, { offset: 1, computedOffset: 1, easing: "ease", composite: "auto", transform: "none" }, ];
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text-decor/reference/text-decoration-underline-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text-decor/reference/text-decoration-underline-ref.html new file mode 100644 index 0000000..2370054a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text-decor/reference/text-decoration-underline-ref.html
@@ -0,0 +1,2 @@ +<!DOCTYPE html> +<p style="text-decoration:underline">This text should be underlined.</p>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text-decor/text-decoration-propagation-shadow.html b/third_party/blink/web_tests/external/wpt/css/css-text-decor/text-decoration-propagation-shadow.html new file mode 100644 index 0000000..ac365ee --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text-decor/text-decoration-propagation-shadow.html
@@ -0,0 +1,16 @@ +<!DOCTYPE html> +<title>CSS Test: text-decoration propagation into shadow DOM boxes</title> +<link rel="help" href="https://drafts.csswg.org/css-text-decor/#line-decoration"> +<link rel="match" href="reference/text-decoration-underline-ref.html"> +<style> + #host { text-decoration: underline } +</style> +<p> + <div id="host"> + <span>This text should be underlined.</span> + </div> +</p> +<script> + const root = host.attachShadow({mode:"open"}); + root.appendChild(document.createElement("slot")); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-transforms/parsing/transform-valid.html b/third_party/blink/web_tests/external/wpt/css/css-transforms/parsing/transform-valid.html index fbde8ea..e6f1015 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-transforms/parsing/transform-valid.html +++ b/third_party/blink/web_tests/external/wpt/css/css-transforms/parsing/transform-valid.html
@@ -39,7 +39,7 @@ test_valid_value("transform", "skew(0)", "skew(0deg)"); test_valid_value("transform", "skew(90deg)"); test_valid_value("transform", "skew(0, -90deg)", "skew(0deg, -90deg)"); -test_valid_value("transform", "skew(90deg, 0)", "skew(90deg, 0deg)"); +test_valid_value("transform", "skew(90deg, 0)", ["skew(90deg)", "skew(90deg, 0deg)"]); test_valid_value("transform", "skewX(0)", "skewX(0deg)"); test_valid_value("transform", "skewX(90deg)");
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/reference/green-blue-stripe-100x100.html b/third_party/blink/web_tests/external/wpt/css/filter-effects/reference/green-blue-stripe-100x100.html new file mode 100644 index 0000000..01546f1 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/reference/green-blue-stripe-100x100.html
@@ -0,0 +1,2 @@ +<!DOCTYPE html> +<div style="width: 50px; height: 100px; background-color: blue; border-left: 50px solid green"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-feblend-001.html b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-feblend-001.html new file mode 100644 index 0000000..416f578 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-feblend-001.html
@@ -0,0 +1,24 @@ +<!DOCTYPE html> +<title>feBlend: does not taint the filter chain</title> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#tainted-filter-primitives"> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#fedisplacemnentmap-restrictions"> +<link rel="match" href="reference/green-blue-stripe-100x100.html"> +<svg> + <linearGradient id="g"> + <stop stop-color="red"/> + <stop stop-color="red" offset=".5"/> + <stop stop-color="green" offset=".5"/> + <stop stop-color="green" offset="1"/> + </linearGradient> + <filter id="blend_notaint" color-interpolation-filters="sRGB" + filterUnits="userSpaceOnUse"> + <feFlood flood-color="rgb(0%, 100%, 50%)"/> + <feBlend/> + <feDisplacementMap in="SourceGraphic" + xChannelSelector="G" yChannelSelector="B" + scale="100"/> + </filter> + <rect width="100" height="100" fill="blue"/> + <rect width="100" height="100" fill="url(#g)" + filter="url(#blend_notaint)"/> +</svg>
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-feblend-002.html b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-feblend-002.html new file mode 100644 index 0000000..3d75341 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-feblend-002.html
@@ -0,0 +1,18 @@ +<!DOCTYPE html> +<title>feBlend: propagates tainting from tainted input primitive</title> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#tainted-filter-primitives"> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#fedisplacemnentmap-restrictions"> +<link rel="match" href="reference/green-100x100.html"> +<svg> + <filter id="blend_taintedinput" color-interpolation-filters="sRGB" + filterUnits="userSpaceOnUse"> + <feFlood flood-color="currentcolor" style="color: rgb(0%, 100%, 50%)"/> + <feBlend/> + <feDisplacementMap in="SourceGraphic" + xChannelSelector="G" yChannelSelector="B" + scale="100"/> + </filter> + <rect width="100" height="100" fill="red"/> + <rect width="100" height="100" fill="green" + filter="url(#blend_taintedinput)"/> +</svg>
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fecomponenttransfer-001.html b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fecomponenttransfer-001.html new file mode 100644 index 0000000..89c60ba9 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fecomponenttransfer-001.html
@@ -0,0 +1,24 @@ +<!DOCTYPE html> +<title>feComponentTransfer: does not taint the filter chain</title> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#tainted-filter-primitives"> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#fedisplacemnentmap-restrictions"> +<link rel="match" href="reference/green-blue-stripe-100x100.html"> +<svg> + <linearGradient id="g"> + <stop stop-color="red"/> + <stop stop-color="red" offset=".5"/> + <stop stop-color="green" offset=".5"/> + <stop stop-color="green" offset="1"/> + </linearGradient> + <filter id="compxfer_notaint" color-interpolation-filters="sRGB" + filterUnits="userSpaceOnUse"> + <feFlood flood-color="rgb(0%, 100%, 50%)"/> + <feComponentTransfer/> + <feDisplacementMap in="SourceGraphic" + xChannelSelector="G" yChannelSelector="B" + scale="100"/> + </filter> + <rect width="100" height="100" fill="blue"/> + <rect width="100" height="100" fill="url(#g)" + filter="url(#compxfer_notaint)"/> +</svg>
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fecomponenttransfer-002.html b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fecomponenttransfer-002.html new file mode 100644 index 0000000..6f29b35b --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fecomponenttransfer-002.html
@@ -0,0 +1,18 @@ +<!DOCTYPE html> +<title>feComponentTransfer: propagates tainting from tainted input primitive</title> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#tainted-filter-primitives"> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#fedisplacemnentmap-restrictions"> +<link rel="match" href="reference/green-100x100.html"> +<svg> + <filter id="compxfer_taintedinput" color-interpolation-filters="sRGB" + filterUnits="userSpaceOnUse"> + <feFlood flood-color="currentcolor" style="color: rgb(0%, 100%, 50%)"/> + <feComponentTransfer/> + <feDisplacementMap in="SourceGraphic" + xChannelSelector="G" yChannelSelector="B" + scale="100"/> + </filter> + <rect width="100" height="100" fill="red"/> + <rect width="100" height="100" fill="green" + filter="url(#compxfer_taintedinput)"/> +</svg>
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fecomposite-001.html b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fecomposite-001.html new file mode 100644 index 0000000..ddaa53e1 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fecomposite-001.html
@@ -0,0 +1,24 @@ +<!DOCTYPE html> +<title>feComposite: does not taint the filter chain</title> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#tainted-filter-primitives"> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#fedisplacemnentmap-restrictions"> +<link rel="match" href="reference/green-blue-stripe-100x100.html"> +<svg> + <linearGradient id="g"> + <stop stop-color="red"/> + <stop stop-color="red" offset=".5"/> + <stop stop-color="green" offset=".5"/> + <stop stop-color="green" offset="1"/> + </linearGradient> + <filter id="composite_notaint" color-interpolation-filters="sRGB" + filterUnits="userSpaceOnUse"> + <feFlood flood-color="rgb(0%, 100%, 50%)"/> + <feComposite/> + <feDisplacementMap in="SourceGraphic" + xChannelSelector="G" yChannelSelector="B" + scale="100"/> + </filter> + <rect width="100" height="100" fill="blue"/> + <rect width="100" height="100" fill="url(#g)" + filter="url(#composite_notaint)"/> +</svg>
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fecomposite-002.html b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fecomposite-002.html new file mode 100644 index 0000000..1e68378 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fecomposite-002.html
@@ -0,0 +1,18 @@ +<!DOCTYPE html> +<title>feComposite: propagates tainting from tainted input primitive</title> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#tainted-filter-primitives"> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#fedisplacemnentmap-restrictions"> +<link rel="match" href="reference/green-100x100.html"> +<svg> + <filter id="composite_taintedinput" color-interpolation-filters="sRGB" + filterUnits="userSpaceOnUse"> + <feFlood flood-color="currentcolor" style="color: rgb(0%, 100%, 50%)"/> + <feComposite/> + <feDisplacementMap in="SourceGraphic" + xChannelSelector="G" yChannelSelector="B" + scale="100"/> + </filter> + <rect width="100" height="100" fill="red"/> + <rect width="100" height="100" fill="green" + filter="url(#composite_taintedinput)"/> +</svg>
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-feconvolvematrix-001.html b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-feconvolvematrix-001.html new file mode 100644 index 0000000..eda1d7e2 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-feconvolvematrix-001.html
@@ -0,0 +1,24 @@ +<!DOCTYPE html> +<title>feConvolveMatrix: does not taint the filter chain</title> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#tainted-filter-primitives"> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#fedisplacemnentmap-restrictions"> +<link rel="match" href="reference/green-blue-stripe-100x100.html"> +<svg> + <linearGradient id="g"> + <stop stop-color="red"/> + <stop stop-color="red" offset=".5"/> + <stop stop-color="green" offset=".5"/> + <stop stop-color="green" offset="1"/> + </linearGradient> + <filter id="convolve_notaint" color-interpolation-filters="sRGB" + filterUnits="userSpaceOnUse"> + <feFlood flood-color="rgb(0%, 100%, 50%)"/> + <feConvolveMatrix order="1" kernelMatrix="1"/> + <feDisplacementMap in="SourceGraphic" + xChannelSelector="G" yChannelSelector="B" + scale="100"/> + </filter> + <rect width="100" height="100" fill="blue"/> + <rect width="100" height="100" fill="url(#g)" + filter="url(#convolve_notaint)"/> +</svg>
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-feconvolvematrix-002.html b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-feconvolvematrix-002.html new file mode 100644 index 0000000..e7ec038fbd --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-feconvolvematrix-002.html
@@ -0,0 +1,18 @@ +<!DOCTYPE html> +<title>feConvolveMatrix: propagates tainting from tainted input primitive</title> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#tainted-filter-primitives"> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#fedisplacemnentmap-restrictions"> +<link rel="match" href="reference/green-100x100.html"> +<svg> + <filter id="convolve_taintedinput" color-interpolation-filters="sRGB" + filterUnits="userSpaceOnUse"> + <feFlood flood-color="currentcolor" style="color: rgb(0%, 100%, 50%)"/> + <feConvolveMatrix order="1" kernelMatrix="1"/> + <feDisplacementMap in="SourceGraphic" + xChannelSelector="G" yChannelSelector="B" + scale="100"/> + </filter> + <rect width="100" height="100" fill="red"/> + <rect width="100" height="100" fill="green" + filter="url(#convolve_taintedinput)"/> +</svg>
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fediffuselighting-001.html b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fediffuselighting-001.html new file mode 100644 index 0000000..bce3a29 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fediffuselighting-001.html
@@ -0,0 +1,25 @@ +<!DOCTYPE html> +<title>feDiffuseLighting: no tainting with regular <color> lighting-color</title> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#tainted-filter-primitives"> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#fedisplacemnentmap-restrictions"> +<link rel="match" href="reference/green-blue-stripe-100x100.html"> +<svg> + <linearGradient id="g"> + <stop stop-color="red"/> + <stop stop-color="red" offset=".5"/> + <stop stop-color="green" offset=".5"/> + <stop stop-color="green" offset="1"/> + </linearGradient> + <filter id="diffuse_notaint" color-interpolation-filters="sRGB" + filterUnits="userSpaceOnUse"> + <feFlood/> + <feDiffuseLighting lighting-color="rgb(0%, 100%, 50%)"> + <feDistantLight elevation="90"/> + </feDiffuseLighting> + <feDisplacementMap in="SourceGraphic" + xChannelSelector="G" yChannelSelector="B" + scale="100" x="0" y="0" width="100" height="100"/> + </filter> + <rect width="100" height="100" fill="blue"/> + <rect width="100" height="100" fill="url(#g)" filter="url(#diffuse_notaint)"/> +</svg>
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fediffuselighting-002.html b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fediffuselighting-002.html new file mode 100644 index 0000000..773c25b --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fediffuselighting-002.html
@@ -0,0 +1,21 @@ +<!DOCTYPE html> +<title>feDiffuseLighting: 'currentcolor' lighting-color taints the primitive</title> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#tainted-filter-primitives"> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#fedisplacemnentmap-restrictions"> +<link rel="match" href="reference/green-100x100.html"> +<svg> + <filter id="diffuse_currentcolor" color-interpolation-filters="sRGB" + filterUnits="userSpaceOnUse"> + <feFlood/> + <feDiffuseLighting lighting-color="currentcolor" + style="color: rgb(0%, 100%, 50%)"> + <feDistantLight elevation="90"/> + </feDiffuseLighting> + <feDisplacementMap in="SourceGraphic" + xChannelSelector="G" yChannelSelector="B" + scale="100"/> + </filter> + <rect width="100" height="100" fill="red"/> + <rect width="100" height="100" fill="green" + filter="url(#diffuse_currentcolor)"/> +</svg>
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fediffuselighting-003.html b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fediffuselighting-003.html new file mode 100644 index 0000000..0b7bb4d --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fediffuselighting-003.html
@@ -0,0 +1,20 @@ +<!DOCTYPE html> +<title>feDiffuseLighting: propagates tainting from tainted input primitive</title> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#tainted-filter-primitives"> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#fedisplacemnentmap-restrictions"> +<link rel="match" href="reference/green-100x100.html"> +<svg> + <filter id="diffuse_taintedinput" color-interpolation-filters="sRGB" + filterUnits="userSpaceOnUse"> + <feFlood flood-color="currentcolor" style="color: black"/> + <feDiffuseLighting lighting-color="rgb(0%, 100%, 50%)"> + <feDistantLight elevation="90"/> + </feDiffuseLighting> + <feDisplacementMap in="SourceGraphic" + xChannelSelector="G" yChannelSelector="B" + scale="100"/> + </filter> + <rect width="100" height="100" fill="red"/> + <rect width="100" height="100" fill="green" + filter="url(#diffuse_taintedinput)"/> +</svg>
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fediffuselighting-dynamic.html b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fediffuselighting-dynamic.html new file mode 100644 index 0000000..8967409 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fediffuselighting-dynamic.html
@@ -0,0 +1,30 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>feDiffuseLighting: tainting state changes dynamically</title> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#tainted-filter-primitives"> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#fedisplacemnentmap-restrictions"> +<link rel="match" href="reference/green-100x100.html"> +<script src="/common/reftest-wait.js"></script> +<svg> + <filter id="diffuse" color-interpolation-filters="sRGB" + filterUnits="userSpaceOnUse"> + <feFlood/> + <feDiffuseLighting lighting-color="rgb(0%, 100%, 50%)" + style="color: rgb(0%, 100%, 50%)"> + <feDistantLight elevation="90"/> + </feDiffuseLighting> + <feDisplacementMap in="SourceGraphic" + xChannelSelector="G" yChannelSelector="B" + scale="100" x="0" y="0" width="100" height="100"/> + </filter> + <rect width="100" height="100" fill="red"/> + <rect width="100" height="100" fill="green" filter="url(#diffuse)"/> +</svg> +<script> + requestAnimationFrame(() => { + requestAnimationFrame(() => { + document.querySelector('feDiffuseLighting').style.lightingColor = 'currentcolor'; + takeScreenshot(); + }); + }); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fedisplacementmap-001.html b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fedisplacementmap-001.html new file mode 100644 index 0000000..2c99cc49 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fedisplacementmap-001.html
@@ -0,0 +1,25 @@ +<!DOCTYPE html> +<title>feDisplacementMap: does not taint the filter chain</title> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#tainted-filter-primitives"> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#fedisplacemnentmap-restrictions"> +<link rel="match" href="reference/green-blue-stripe-100x100.html"> +<svg> + <linearGradient id="g"> + <stop stop-color="red"/> + <stop stop-color="red" offset=".5"/> + <stop stop-color="green" offset=".5"/> + <stop stop-color="green" offset="1"/> + </linearGradient> + <filter id="dispmap_notaint" color-interpolation-filters="sRGB" + filterUnits="userSpaceOnUse"> + <feFlood flood-color="rgb(0%, 100%, 50%)"/> + <feDisplacementMap xChannelSelector="G" yChannelSelector="B" + scale="0"/> + <feDisplacementMap in="SourceGraphic" + xChannelSelector="G" yChannelSelector="B" + scale="100"/> + </filter> + <rect width="100" height="100" fill="blue"/> + <rect width="100" height="100" fill="url(#g)" + filter="url(#dispmap_notaint)"/> +</svg>
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fedisplacementmap-002.html b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fedisplacementmap-002.html new file mode 100644 index 0000000..9648b54b --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fedisplacementmap-002.html
@@ -0,0 +1,19 @@ +<!DOCTYPE html> +<title>feDisplacementMap: propagates tainting from tainted input primitive</title> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#tainted-filter-primitives"> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#fedisplacemnentmap-restrictions"> +<link rel="match" href="reference/green-100x100.html"> +<svg> + <filter id="dispmap_taintedinput" color-interpolation-filters="sRGB" + filterUnits="userSpaceOnUse"> + <feFlood flood-color="currentcolor" style="color: rgb(0%, 100%, 50%)"/> + <feDisplacementMap xChannelSelector="G" yChannelSelector="B" + scale="0"/> + <feDisplacementMap in="SourceGraphic" + xChannelSelector="G" yChannelSelector="B" + scale="100"/> + </filter> + <rect width="100" height="100" fill="red"/> + <rect width="100" height="100" fill="green" + filter="url(#dispmap_taintedinput)"/> +</svg>
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fedropshadow-001.html b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fedropshadow-001.html new file mode 100644 index 0000000..1b3dbb4 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fedropshadow-001.html
@@ -0,0 +1,25 @@ +<!DOCTYPE html> +<title>feDropShadow: no tainting with regular <color> flood-color</title> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#tainted-filter-primitives"> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#fedisplacemnentmap-restrictions"> +<link rel="match" href="reference/green-blue-stripe-100x100.html"> +<svg> + <linearGradient id="g"> + <stop stop-color="red"/> + <stop stop-color="red" offset=".5"/> + <stop stop-color="green" offset=".5"/> + <stop stop-color="green" offset="1"/> + </linearGradient> + <filter id="dropshdw_notaint" color-interpolation-filters="sRGB" + filterUnits="userSpaceOnUse"> + <feFlood x="0" y="0" width="100" height="100"/> + <feDropShadow width="100%" flood-color="rgb(0%, 100%, 50%)" stdDeviation="0" + dx="100" dy="0"/> + <feOffset dx="-100"/> + <feDisplacementMap in="SourceGraphic" + xChannelSelector="G" yChannelSelector="B" + scale="100" x="0" y="0" width="100" height="100"/> + </filter> + <rect width="100" height="100" fill="blue"/> + <rect width="100" height="100" fill="url(#g)" filter="url(#dropshdw_notaint)"/> +</svg>
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fedropshadow-002.html b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fedropshadow-002.html new file mode 100644 index 0000000..26fc687 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fedropshadow-002.html
@@ -0,0 +1,20 @@ +<!DOCTYPE html> +<title>feDropShadow: 'currentcolor' flood-color taints the primitive</title> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#tainted-filter-primitives"> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#fedisplacemnentmap-restrictions"> +<link rel="match" href="reference/green-100x100.html"> +<svg> + <filter id="dropshdw_currentcolor" color-interpolation-filters="sRGB" + filterUnits="userSpaceOnUse"> + <feFlood x="0" y="0" width="100" height="100"/> + <feDropShadow width="100%" flood-color="currentcolor" stdDeviation="0" + dx="100" dy="0" style="color: rgb(0%, 100%, 50%)"/> + <feOffset dx="-100"/> + <feDisplacementMap in="SourceGraphic" + xChannelSelector="G" yChannelSelector="B" + scale="100" x="0" y="0" width="100" height="100"/> + </filter> + <rect width="100" height="100" fill="red"/> + <rect width="100" height="100" fill="green" + filter="url(#dropshdw_currentcolor)"/> +</svg>
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fedropshadow-003.html b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fedropshadow-003.html new file mode 100644 index 0000000..d42102a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fedropshadow-003.html
@@ -0,0 +1,21 @@ +<!DOCTYPE html> +<title>feDropShadow: propagates tainting from tainted input primitive</title> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#tainted-filter-primitives"> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#fedisplacemnentmap-restrictions"> +<link rel="match" href="reference/green-100x100.html"> +<svg> + <filter id="dropshdw_taintedinput" color-interpolation-filters="sRGB" + filterUnits="userSpaceOnUse"> + <feFlood x="0" y="0" width="100" height="100" flood-color="currentcolor" + style="color: black"/> + <feDropShadow width="100%" flood-color="rgb(0%, 100%, 50%)" stdDeviation="0" + dx="100" dy="0"/> + <feOffset dx="-100"/> + <feDisplacementMap in="SourceGraphic" + xChannelSelector="G" yChannelSelector="B" + scale="100" x="0" y="0" width="100" height="100"/> + </filter> + <rect width="100" height="100" fill="red"/> + <rect width="100" height="100" fill="green" + filter="url(#dropshdw_taintedinput)"/> +</svg>
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-feflood-001.html b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-feflood-001.html new file mode 100644 index 0000000..714e6b99 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-feflood-001.html
@@ -0,0 +1,21 @@ +<!DOCTYPE html> +<title>feFlood: no tainting with regular <color> flood-color</title> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#tainted-filter-primitives"> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#fedisplacemnentmap-restrictions"> +<link rel="match" href="reference/green-blue-stripe-100x100.html"> +<svg> + <linearGradient id="g"> + <stop stop-color="red"/> + <stop stop-color="red" offset=".5"/> + <stop stop-color="green" offset=".5"/> + <stop stop-color="green" offset="1"/> + </linearGradient> + <filter id="flood_notaint" color-interpolation-filters="sRGB"> + <feFlood flood-color="rgb(0%, 100%, 50%)"/> + <feDisplacementMap in="SourceGraphic" + xChannelSelector="G" yChannelSelector="B" + scale="100"/> + </filter> + <rect width="100" height="100" fill="blue"/> + <rect width="100" height="100" fill="url(#g)" filter="url(#flood_notaint)"/> +</svg>
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-feflood-002.html b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-feflood-002.html new file mode 100644 index 0000000..79ea8dac --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-feflood-002.html
@@ -0,0 +1,16 @@ +<!DOCTYPE html> +<title>feFlood: 'currentcolor' flood-color taints the primitive</title> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#tainted-filter-primitives"> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#fedisplacemnentmap-restrictions"> +<link rel="match" href="reference/green-100x100.html"> +<svg> + <filter id="flood_currentcolor" color-interpolation-filters="sRGB"> + <feFlood flood-color="currentcolor" style="color: rgb(0%, 100%, 50%)"/> + <feDisplacementMap in="SourceGraphic" + xChannelSelector="G" yChannelSelector="B" + scale="100"/> + </filter> + <rect width="100" height="100" fill="red"/> + <rect width="100" height="100" fill="green" + filter="url(#flood_currentcolor)"/> +</svg>
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-feflood-dynamic.html b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-feflood-dynamic.html new file mode 100644 index 0000000..fc9b335 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-feflood-dynamic.html
@@ -0,0 +1,25 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>feFlood: tainting state changes dynamically</title> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#tainted-filter-primitives"> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#fedisplacemnentmap-restrictions"> +<link rel="match" href="reference/green-100x100.html"> +<script src="/common/reftest-wait.js"></script> +<svg> + <filter id="flood" color-interpolation-filters="sRGB"> + <feFlood flood-color="rgb(0%, 100%, 50%)" style="color: rgb(0%, 100%, 50%)"/> + <feDisplacementMap in="SourceGraphic" + xChannelSelector="G" yChannelSelector="B" + scale="100"/> + </filter> + <rect width="100" height="100" fill="red"/> + <rect width="100" height="100" fill="green" filter="url(#flood)"/> +</svg> +<script> + requestAnimationFrame(() => { + requestAnimationFrame(() => { + document.querySelector('feFlood').style.floodColor = 'currentcolor'; + takeScreenshot(); + }); + }); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fegaussianblur-001.html b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fegaussianblur-001.html new file mode 100644 index 0000000..a938c749 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fegaussianblur-001.html
@@ -0,0 +1,24 @@ +<!DOCTYPE html> +<title>feGaussianBlur: does not taint the filter chain</title> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#tainted-filter-primitives"> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#fedisplacemnentmap-restrictions"> +<link rel="match" href="reference/green-blue-stripe-100x100.html"> +<svg> + <linearGradient id="g"> + <stop stop-color="red"/> + <stop stop-color="red" offset=".5"/> + <stop stop-color="green" offset=".5"/> + <stop stop-color="green" offset="1"/> + </linearGradient> + <filter id="gaussian_notaint" color-interpolation-filters="sRGB" + filterUnits="userSpaceOnUse"> + <feFlood flood-color="rgb(0%, 100%, 50%)"/> + <feGaussianBlur stdDeviation="0"/> + <feDisplacementMap in="SourceGraphic" + xChannelSelector="G" yChannelSelector="B" + scale="100"/> + </filter> + <rect width="100" height="100" fill="blue"/> + <rect width="100" height="100" fill="url(#g)" + filter="url(#gaussian_notaint)"/> +</svg>
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fegaussianblur-002.html b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fegaussianblur-002.html new file mode 100644 index 0000000..55dabbbd --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fegaussianblur-002.html
@@ -0,0 +1,18 @@ +<!DOCTYPE html> +<title>feGaussianBlur: propagates tainting from tainted input primitive</title> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#tainted-filter-primitives"> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#fedisplacemnentmap-restrictions"> +<link rel="match" href="reference/green-100x100.html"> +<svg> + <filter id="gaussian_taintedinput" color-interpolation-filters="sRGB" + filterUnits="userSpaceOnUse"> + <feFlood flood-color="currentcolor" style="color: rgb(0%, 100%, 50%)"/> + <feGaussianBlur stdDeviation="0"/> + <feDisplacementMap in="SourceGraphic" + xChannelSelector="G" yChannelSelector="B" + scale="100"/> + </filter> + <rect width="100" height="100" fill="red"/> + <rect width="100" height="100" fill="green" + filter="url(#gaussian_taintedinput)"/> +</svg>
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-femorphology-001.html b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-femorphology-001.html new file mode 100644 index 0000000..9af5664 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-femorphology-001.html
@@ -0,0 +1,24 @@ +<!DOCTYPE html> +<title>feMorphology: does not taint the filter chain</title> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#tainted-filter-primitives"> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#fedisplacemnentmap-restrictions"> +<link rel="match" href="reference/green-blue-stripe-100x100.html"> +<svg> + <linearGradient id="g"> + <stop stop-color="red"/> + <stop stop-color="red" offset=".5"/> + <stop stop-color="green" offset=".5"/> + <stop stop-color="green" offset="1"/> + </linearGradient> + <filter id="morphology_notaint" color-interpolation-filters="sRGB" + filterUnits="userSpaceOnUse"> + <feFlood flood-color="rgb(0%, 100%, 50%)"/> + <feMorphology radius="0.5"/> + <feDisplacementMap in="SourceGraphic" + xChannelSelector="G" yChannelSelector="B" + scale="100"/> + </filter> + <rect width="100" height="100" fill="blue"/> + <rect width="100" height="100" fill="url(#g)" + filter="url(#morphology_notaint)"/> +</svg>
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-femorphology-002.html b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-femorphology-002.html new file mode 100644 index 0000000..2c097202 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-femorphology-002.html
@@ -0,0 +1,18 @@ +<!DOCTYPE html> +<title>feMorphology: propagates tainting from tainted input primitive</title> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#tainted-filter-primitives"> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#fedisplacemnentmap-restrictions"> +<link rel="match" href="reference/green-100x100.html"> +<svg> + <filter id="morphology_taintedinput" color-interpolation-filters="sRGB" + filterUnits="userSpaceOnUse"> + <feFlood flood-color="currentcolor" style="color: rgb(0%, 100%, 50%)"/> + <feMorphology radius="0.5"/> + <feDisplacementMap in="SourceGraphic" + xChannelSelector="G" yChannelSelector="B" + scale="100"/> + </filter> + <rect width="100" height="100" fill="red"/> + <rect width="100" height="100" fill="green" + filter="url(#morphology_taintedinput)"/> +</svg>
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-feoffset-001.html b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-feoffset-001.html new file mode 100644 index 0000000..8704b693 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-feoffset-001.html
@@ -0,0 +1,24 @@ +<!DOCTYPE html> +<title>feOffset: does not taint the filter chain</title> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#tainted-filter-primitives"> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#fedisplacemnentmap-restrictions"> +<link rel="match" href="reference/green-blue-stripe-100x100.html"> +<svg> + <linearGradient id="g"> + <stop stop-color="red"/> + <stop stop-color="red" offset=".5"/> + <stop stop-color="green" offset=".5"/> + <stop stop-color="green" offset="1"/> + </linearGradient> + <filter id="offset_notaint" color-interpolation-filters="sRGB" + filterUnits="userSpaceOnUse"> + <feFlood flood-color="rgb(0%, 100%, 50%)"/> + <feOffset/> + <feDisplacementMap in="SourceGraphic" + xChannelSelector="G" yChannelSelector="B" + scale="100"/> + </filter> + <rect width="100" height="100" fill="blue"/> + <rect width="100" height="100" fill="url(#g)" + filter="url(#offset_notaint)"/> +</svg>
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-feoffset-002.html b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-feoffset-002.html new file mode 100644 index 0000000..3c04268f5 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-feoffset-002.html
@@ -0,0 +1,18 @@ +<!DOCTYPE html> +<title>feOffset: propagates tainting from tainted input primitive</title> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#tainted-filter-primitives"> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#fedisplacemnentmap-restrictions"> +<link rel="match" href="reference/green-100x100.html"> +<svg> + <filter id="offset_taintedinput" color-interpolation-filters="sRGB" + filterUnits="userSpaceOnUse"> + <feFlood flood-color="currentcolor" style="color: rgb(0%, 100%, 50%)"/> + <feOffset/> + <feDisplacementMap in="SourceGraphic" + xChannelSelector="G" yChannelSelector="B" + scale="100"/> + </filter> + <rect width="100" height="100" fill="red"/> + <rect width="100" height="100" fill="green" + filter="url(#offset_taintedinput)"/> +</svg>
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fespecularlighting-001.html b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fespecularlighting-001.html new file mode 100644 index 0000000..c2825258 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fespecularlighting-001.html
@@ -0,0 +1,26 @@ +<!DOCTYPE html> +<title>feSpecularLighting: no tainting with regular <color> lighting-color</title> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#tainted-filter-primitives"> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#fedisplacemnentmap-restrictions"> +<link rel="match" href="reference/green-blue-stripe-100x100.html"> +<svg> + <linearGradient id="g"> + <stop stop-color="red"/> + <stop stop-color="red" offset=".5"/> + <stop stop-color="green" offset=".5"/> + <stop stop-color="green" offset="1"/> + </linearGradient> + <filter id="specular_notaint" color-interpolation-filters="sRGB" + filterUnits="userSpaceOnUse"> + <feFlood/> + <feSpecularLighting lighting-color="rgb(0%, 100%, 50%)"> + <feDistantLight elevation="90"/> + </feSpecularLighting> + <feDisplacementMap in="SourceGraphic" + xChannelSelector="G" yChannelSelector="B" + scale="100"/> + </filter> + <rect width="100" height="100" fill="blue"/> + <rect width="100" height="100" fill="url(#g)" + filter="url(#specular_notaint)"/> +</svg>
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fespecularlighting-002.html b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fespecularlighting-002.html new file mode 100644 index 0000000..773b0c7 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fespecularlighting-002.html
@@ -0,0 +1,21 @@ +<!DOCTYPE html> +<title>feSpecularLighting: 'currentcolor' lighting-color taints the primitive</title> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#tainted-filter-primitives"> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#fedisplacemnentmap-restrictions"> +<link rel="match" href="reference/green-100x100.html"> +<svg> + <filter id="specular_currentcolor" color-interpolation-filters="sRGB" + filterUnits="userSpaceOnUse"> + <feFlood/> + <feSpecularLighting lighting-color="currentcolor" + style="color: rgb(0%, 100%, 50%)"> + <feDistantLight elevation="90"/> + </feSpecularLighting> + <feDisplacementMap in="SourceGraphic" + xChannelSelector="G" yChannelSelector="B" + scale="100"/> + </filter> + <rect width="100" height="100" fill="red"/> + <rect width="100" height="100" fill="green" + filter="url(#specular_currentcolor)"/> +</svg>
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fespecularlighting-003.html b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fespecularlighting-003.html new file mode 100644 index 0000000..173ed2da --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fespecularlighting-003.html
@@ -0,0 +1,20 @@ +<!DOCTYPE html> +<title>feSpecularLighting: propagates tainting from tainted input primitive</title> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#tainted-filter-primitives"> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#fedisplacemnentmap-restrictions"> +<link rel="match" href="reference/green-100x100.html"> +<svg> + <filter id="specular_taintedinput" color-interpolation-filters="sRGB" + filterUnits="userSpaceOnUse"> + <feFlood flood-color="currentcolor" style="color: black"/> + <feSpecularLighting lighting-color="rgb(0%, 100%, 50%)"> + <feDistantLight elevation="90"/> + </feSpecularLighting> + <feDisplacementMap in="SourceGraphic" + xChannelSelector="G" yChannelSelector="B" + scale="100"/> + </filter> + <rect width="100" height="100" fill="red"/> + <rect width="100" height="100" fill="green" + filter="url(#specular_taintedinput)"/> +</svg>
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fetile-001.html b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fetile-001.html new file mode 100644 index 0000000..c5b955e --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fetile-001.html
@@ -0,0 +1,24 @@ +<!DOCTYPE html> +<title>feTile: does not taint the filter chain</title> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#tainted-filter-primitives"> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#fedisplacemnentmap-restrictions"> +<link rel="match" href="reference/green-blue-stripe-100x100.html"> +<svg> + <linearGradient id="g"> + <stop stop-color="red"/> + <stop stop-color="red" offset=".5"/> + <stop stop-color="green" offset=".5"/> + <stop stop-color="green" offset="1"/> + </linearGradient> + <filter id="tile_notaint" color-interpolation-filters="sRGB" + filterUnits="userSpaceOnUse"> + <feFlood flood-color="rgb(0%, 100%, 50%)"/> + <feTile/> + <feDisplacementMap in="SourceGraphic" + xChannelSelector="G" yChannelSelector="B" + scale="100"/> + </filter> + <rect width="100" height="100" fill="blue"/> + <rect width="100" height="100" fill="url(#g)" + filter="url(#tile_notaint)"/> +</svg>
diff --git a/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fetile-002.html b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fetile-002.html new file mode 100644 index 0000000..ed77301 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/filter-effects/tainting-fetile-002.html
@@ -0,0 +1,18 @@ +<!DOCTYPE html> +<title>feTile: propagates tainting from tainted input primitive</title> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#tainted-filter-primitives"> +<link rel="help" href="https://drafts.fxtf.org/filter-effects/#fedisplacemnentmap-restrictions"> +<link rel="match" href="reference/green-100x100.html"> +<svg> + <filter id="tile_taintedinput" color-interpolation-filters="sRGB" + filterUnits="userSpaceOnUse"> + <feFlood flood-color="currentcolor" style="color: rgb(0%, 100%, 50%)"/> + <feTile/> + <feDisplacementMap in="SourceGraphic" + xChannelSelector="G" yChannelSelector="B" + scale="100"/> + </filter> + <rect width="100" height="100" fill="red"/> + <rect width="100" height="100" fill="green" + filter="url(#tile_taintedinput)"/> +</svg>
diff --git a/third_party/blink/web_tests/external/wpt/fetch/stale-while-revalidate/fetch-sw.https.tentative.html b/third_party/blink/web_tests/external/wpt/fetch/stale-while-revalidate/fetch-sw.https.tentative.html new file mode 100644 index 0000000..2286739 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/fetch/stale-while-revalidate/fetch-sw.https.tentative.html
@@ -0,0 +1,63 @@ +<!DOCTYPE html> +<!--- +Tentative test against: +https://github.com/whatwg/fetch/pull/853 +--> +<html> +<head> + <meta charset="utf-8"> + <title>Stale Revalidation Requests don't get sent to service worker</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="../../service-workers/service-worker/resources/test-helpers.sub.js"></script> + <script src="/common/utils.js"></script> +</head> +<body> +<script> + + // Duplicating this resource to make service worker scoping simpler. + async function setupRegistration(t, scope) { + const reg = await navigator.serviceWorker.register('sw-intercept.js'); + await wait_for_state(t, reg.installing, 'activated'); + add_completion_callback(_ => reg.unregister()); + return reg; + } + + function wait25ms(test) { + return new Promise(resolve => { + test.step_timeout(() => { + resolve(); + }, 25); + }); + } + + promise_test(async (test) => { + var request_token = token(); + const uri = 'stale-script.py?token=' + request_token; + + await setupRegistration(test, 'stale-script.py'); + + var service_worker_count = 0; + navigator.serviceWorker.addEventListener('message', function once(event) { + if (event.data.endsWith(uri)) { + service_worker_count++; + } + }); + + const response = await fetch(uri); + const response2 = await fetch(uri); + assert_equals(response.headers.get('Unique-Id'), response2.headers.get('Unique-Id')); + while(true) { + const revalidation_check = await fetch(`stale-script.py?query&token=` + request_token); + if (revalidation_check.headers.get('Count') == '2') { + // The service worker should not see the revalidation request. + assert_equals(service_worker_count, 2); + break; + } + await wait25ms(test); + } + }, 'Second fetch returns same response'); + +</script> +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/fetch/stale-while-revalidate/fetch.tentative.html b/third_party/blink/web_tests/external/wpt/fetch/stale-while-revalidate/fetch.tentative.html index 5b9b2dc5..33d844fd 100644 --- a/third_party/blink/web_tests/external/wpt/fetch/stale-while-revalidate/fetch.tentative.html +++ b/third_party/blink/web_tests/external/wpt/fetch/stale-while-revalidate/fetch.tentative.html
@@ -9,12 +9,28 @@ <script src="/resources/testharnessreport.js"></script> <script src="/common/utils.js"></script> <script> +function wait25ms(test) { + return new Promise(resolve => { + test.step_timeout(() => { + resolve(); + }, 25); + }); +} + promise_test(async (test) => { var request_token = token(); const response = await fetch(`stale-script.py?token=` + request_token); const response2 = await fetch(`stale-script.py?token=` + request_token); - assert_not_equals(response.headers.get('Unique-Id'), response2.headers.get('Unique-Id')); -}, 'Second fetch does not return same response'); + assert_equals(response.headers.get('Unique-Id'), response2.headers.get('Unique-Id')); + + while(true) { + const revalidation_check = await fetch(`stale-script.py?query&token=` + request_token); + if (revalidation_check.headers.get('Count') == '2') { + break; + } + await wait25ms(test); + } +}, 'Second fetch returns same response'); </script>
diff --git a/third_party/blink/web_tests/external/wpt/fetch/stale-while-revalidate/stale-css.py b/third_party/blink/web_tests/external/wpt/fetch/stale-while-revalidate/stale-css.py index 425c889..9566833 100644 --- a/third_party/blink/web_tests/external/wpt/fetch/stale-while-revalidate/stale-css.py +++ b/third_party/blink/web_tests/external/wpt/fetch/stale-while-revalidate/stale-css.py
@@ -8,6 +8,8 @@ if request.GET.first("query", None) != None: headers = [("Count", count)] content = "" + if count < 2: + request.server.stash.put(token, count) return 200, headers, content else: count = count + 1
diff --git a/third_party/blink/web_tests/external/wpt/fetch/stale-while-revalidate/stale-image.py b/third_party/blink/web_tests/external/wpt/fetch/stale-while-revalidate/stale-image.py index ce7f0fc..e0cf94bc 100644 --- a/third_party/blink/web_tests/external/wpt/fetch/stale-while-revalidate/stale-image.py +++ b/third_party/blink/web_tests/external/wpt/fetch/stale-while-revalidate/stale-image.py
@@ -10,6 +10,8 @@ if request.GET.first("query", None) != None: headers = [("Count", count)] content = "" + if count < 2: + request.server.stash.put(token, count) return 200, headers, content else: count = count + 1
diff --git a/third_party/blink/web_tests/external/wpt/fetch/stale-while-revalidate/stale-script.py b/third_party/blink/web_tests/external/wpt/fetch/stale-while-revalidate/stale-script.py index 0f91a9b..5ea5987db 100644 --- a/third_party/blink/web_tests/external/wpt/fetch/stale-while-revalidate/stale-script.py +++ b/third_party/blink/web_tests/external/wpt/fetch/stale-while-revalidate/stale-script.py
@@ -13,6 +13,8 @@ if request.GET.first("query", None) != None: headers = [("Count", count)] content = "" + if count < 2: + request.server.stash.put(token, count) return 200, headers, content else: count = count + 1
diff --git a/third_party/blink/web_tests/external/wpt/fetch/stale-while-revalidate/sw-intercept.js b/third_party/blink/web_tests/external/wpt/fetch/stale-while-revalidate/sw-intercept.js new file mode 100644 index 0000000..dca7de5 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/fetch/stale-while-revalidate/sw-intercept.js
@@ -0,0 +1,14 @@ +async function broadcast(msg) { + for (const client of await clients.matchAll()) { + client.postMessage(msg); + } +} + +self.addEventListener('fetch', event => { + event.waitUntil(broadcast(event.request.url)); + event.respondWith(fetch(event.request)); +}); + +self.addEventListener('activate', event => { + self.clients.claim(); +});
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/origin/cross-origin-objects/cross-origin-objects.html b/third_party/blink/web_tests/external/wpt/html/browsers/origin/cross-origin-objects/cross-origin-objects.html index 888343b4..f664819 100644 --- a/third_party/blink/web_tests/external/wpt/html/browsers/origin/cross-origin-objects/cross-origin-objects.html +++ b/third_party/blink/web_tests/external/wpt/html/browsers/origin/cross-origin-objects/cross-origin-objects.html
@@ -12,11 +12,17 @@ <iframe id="B"></iframe> <iframe id="C"></iframe> <iframe id="D"></iframe> +<iframe id="E"></iframe> +<iframe id="F"></iframe> +<iframe id="G"></iframe> +<iframe id="H"></iframe> <script> /* - * Setup boilerplate. This gives us a same-origin window "B" and a cross-origin - * window "C". + * Setup boilerplate. This gives us a same-origin window "B", cross-origin + * windows "C" and "D", initially same-origin but then changing document.domain + * windows "E" and "F", and not-same-site (also cross-origin, of course) windows + * "G" and "H". */ var host_info = get_host_info(); @@ -26,9 +32,29 @@ var B = document.getElementById('B').contentWindow; var C = document.getElementById('C').contentWindow; var D = document.getElementById('D').contentWindow; +var E = document.getElementById('E').contentWindow; +var F = document.getElementById('F').contentWindow; +var G = document.getElementById('G').contentWindow; +var H = document.getElementById('H').contentWindow; B.frameElement.uriToLoad = path; C.frameElement.uriToLoad = get_host_info().HTTP_REMOTE_ORIGIN + path; D.frameElement.uriToLoad = get_host_info().HTTP_REMOTE_ORIGIN + pathWithThen; +E.frameElement.uriToLoad = path + "?setdomain"; +F.frameElement.uriToLoad = pathWithThen + "?setdomain"; +G.frameElement.uriToLoad = get_host_info().HTTP_NOTSAMESITE_ORIGIN + path; +H.frameElement.uriToLoad = get_host_info().HTTP_NOTSAMESITE_ORIGIN + pathWithThen; + +function winName(win) { + var iframes = document.getElementsByTagName('iframe'); + iframes.find = Array.prototype.find; + var found = iframes.find(function (ifr) { + return ifr.contentWindow == win; + }); + if (found) { + return found.id; + } + return "UNKNOWN"; +} function reloadSubframes(cb) { var iframes = document.getElementsByTagName('iframe'); @@ -48,24 +74,59 @@ * up throwing when it tries to format a message involving a cross-origin object. */ +/* + * List of tests. Each test is actually a pair: an array of tests to run and a + * boolean for whether these are promise tests. We reload all the subframes in + * between running each toplevel test. This is done to avoid having to reload + * all the subframes for every single test, which is overkill: some of these + * tests are known to touch only one subframe. And doing it makes the test + * really slow. + */ var testList = []; -function addTest(func, desc) { testList.push({func, desc, promiseTest: false}); } -function addPromiseTest(func, desc) { testList.push({func, desc, promiseTest: true}); } +function addTest(func, desc) { + testList.push( + {tests: [ + {func: func.bind(null, C), + desc: desc + " (cross-origin)"}, + {func: func.bind(null, E), + desc: desc + " (same-origin + document.domain)"}, + {func: func.bind(null, G), + desc: desc + " (cross-site)"}], + promiseTest: false}); +} + +/** + * A similar helper, but for the subframes that load frame-with-then.html + */ +function addThenTest(func, desc) { + testList.push( + {tests: [ + {func: func.bind(null, D), + desc: desc + " (cross-origin)"}, + {func: func.bind(null, F), + desc: desc + " (same-origin + document.domain)"}, + {func: func.bind(null, H), + desc: desc + " (cross-site)"}], + promiseTest: false}); +} + +function addPromiseTest(func, desc) { + testList.push({tests:[{func, desc}], promiseTest: true}); } /* * Basic sanity testing. */ -addTest(function() { +addTest(function(win) { // Note: we do not check location.host as its default port semantics are hard to reflect statically assert_equals(location.hostname, host_info.ORIGINAL_HOST, 'Need to run the top-level test from domain ' + host_info.ORIGINAL_HOST); assert_equals(get_port(location), host_info.HTTP_PORT, 'Need to run the top-level test from port ' + host_info.HTTP_PORT); assert_equals(B.parent, window, "window.parent works same-origin"); - assert_equals(C.parent, window, "window.parent works cross-origin"); + assert_equals(win.parent, window, "window.parent works cross-origin"); assert_equals(B.location.pathname, path, "location.href works same-origin"); - assert_throws("SecurityError", function() { C.location.pathname; }, "location.pathname throws cross-origin"); + assert_throws("SecurityError", function() { win.location.pathname; }, "location.pathname throws cross-origin"); assert_equals(B.frames, 'override', "Overrides visible in the same-origin case"); - assert_equals(C.frames, C, "Overrides invisible in the cross-origin case"); + assert_equals(win.frames, win, "Overrides invisible in the cross-origin case"); }, "Basic sanity-checking"); /* @@ -85,42 +146,42 @@ Symbol.isConcatSpreadable]; var whitelistedWindowProps = whitelistedWindowPropNames.concat(whitelistedSymbols); -addTest(function() { +addTest(function(win) { for (var prop in window) { if (whitelistedWindowProps.indexOf(prop) != -1) { - C[prop]; // Shouldn't throw. - Object.getOwnPropertyDescriptor(C, prop); // Shouldn't throw. - assert_true(Object.prototype.hasOwnProperty.call(C, prop), "hasOwnProperty for " + String(prop)); + win[prop]; // Shouldn't throw. + Object.getOwnPropertyDescriptor(win, prop); // Shouldn't throw. + assert_true(Object.prototype.hasOwnProperty.call(win, prop), "hasOwnProperty for " + String(prop)); } else { - assert_throws("SecurityError", function() { C[prop]; }, "Should throw when accessing " + String(prop) + " on Window"); - assert_throws("SecurityError", function() { Object.getOwnPropertyDescriptor(C, prop); }, + assert_throws("SecurityError", function() { win[prop]; }, "Should throw when accessing " + String(prop) + " on Window"); + assert_throws("SecurityError", function() { Object.getOwnPropertyDescriptor(win, prop); }, "Should throw when accessing property descriptor for " + prop + " on Window"); - assert_throws("SecurityError", function() { Object.prototype.hasOwnProperty.call(C, prop); }, + assert_throws("SecurityError", function() { Object.prototype.hasOwnProperty.call(win, prop); }, "Should throw when invoking hasOwnProperty for " + prop + " on Window"); } if (prop != 'location') - assert_throws("SecurityError", function() { C[prop] = undefined; }, "Should throw when writing to " + prop + " on Window"); + assert_throws("SecurityError", function() { win[prop] = undefined; }, "Should throw when writing to " + prop + " on Window"); } for (var prop in location) { if (prop == 'replace') { - C.location[prop]; // Shouldn't throw. - Object.getOwnPropertyDescriptor(C.location, prop); // Shouldn't throw. - assert_true(Object.prototype.hasOwnProperty.call(C.location, prop), "hasOwnProperty for " + prop); - assert_throws("SecurityError", function() { C.location[prop] = undefined; }, "Should throw when writing to " + prop + " on Location"); + win.location[prop]; // Shouldn't throw. + Object.getOwnPropertyDescriptor(win.location, prop); // Shouldn't throw. + assert_true(Object.prototype.hasOwnProperty.call(win.location, prop), "hasOwnProperty for " + prop); + assert_throws("SecurityError", function() { win.location[prop] = undefined; }, "Should throw when writing to " + prop + " on Location"); } else if (prop == 'href') { - Object.getOwnPropertyDescriptor(C.location, prop); // Shouldn't throw. - assert_true(Object.prototype.hasOwnProperty.call(C.location, prop), "hasOwnProperty for " + prop); - assert_throws("SecurityError", function() { C.location[prop] }, + Object.getOwnPropertyDescriptor(win.location, prop); // Shouldn't throw. + assert_true(Object.prototype.hasOwnProperty.call(win.location, prop), "hasOwnProperty for " + prop); + assert_throws("SecurityError", function() { win.location[prop] }, "Should throw reading href on Location"); } else { - assert_throws("SecurityError", function() { C.location[prop]; }, "Should throw when accessing " + prop + " on Location"); - assert_throws("SecurityError", function() { Object.getOwnPropertyDescriptor(C.location, prop); }, + assert_throws("SecurityError", function() { win.location[prop]; }, "Should throw when accessing " + prop + " on Location"); + assert_throws("SecurityError", function() { Object.getOwnPropertyDescriptor(win.location, prop); }, "Should throw when accessing property descriptor for " + prop + " on Location"); - assert_throws("SecurityError", function() { Object.prototype.hasOwnProperty.call(C.location, prop); }, + assert_throws("SecurityError", function() { Object.prototype.hasOwnProperty.call(win.location, prop); }, "Should throw when invoking hasOwnProperty for " + prop + " on Location"); - assert_throws("SecurityError", function() { C.location[prop] = undefined; }, "Should throw when writing to " + prop + " on Location"); + assert_throws("SecurityError", function() { win.location[prop] = undefined; }, "Should throw when writing to " + prop + " on Location"); } } }, "Only whitelisted properties are accessible cross-origin"); @@ -132,45 +193,45 @@ /* * [[GetPrototypeOf]] */ -addTest(function() { - assert_equals(Object.getPrototypeOf(C), null, "cross-origin Window proto is null"); - assert_equals(Object.getPrototypeOf(C.location), null, "cross-origin Location proto is null (__proto__)"); +addTest(function(win) { + assert_equals(Object.getPrototypeOf(win), null, "cross-origin Window proto is null"); + assert_equals(Object.getPrototypeOf(win.location), null, "cross-origin Location proto is null (__proto__)"); var protoGetter = Object.getOwnPropertyDescriptor(Object.prototype, '__proto__').get; - assert_equals(protoGetter.call(C), null, "cross-origin Window proto is null"); - assert_equals(protoGetter.call(C.location), null, "cross-origin Location proto is null (__proto__)"); - assert_throws("SecurityError", function() { C.__proto__; }, "__proto__ property not available cross-origin"); - assert_throws("SecurityError", function() { C.location.__proto__; }, "__proto__ property not available cross-origin"); + assert_equals(protoGetter.call(win), null, "cross-origin Window proto is null"); + assert_equals(protoGetter.call(win.location), null, "cross-origin Location proto is null (__proto__)"); + assert_throws("SecurityError", function() { win.__proto__; }, "__proto__ property not available cross-origin"); + assert_throws("SecurityError", function() { win.location.__proto__; }, "__proto__ property not available cross-origin"); }, "[[GetPrototypeOf]] should return null"); /* * [[SetPrototypeOf]] */ -addTest(function() { - assert_throws("SecurityError", function() { C.__proto__ = new Object(); }, "proto set on cross-origin Window"); - assert_throws("SecurityError", function() { C.location.__proto__ = new Object(); }, "proto set on cross-origin Location"); +addTest(function(win) { + assert_throws("SecurityError", function() { win.__proto__ = new Object(); }, "proto set on cross-origin Window"); + assert_throws("SecurityError", function() { win.location.__proto__ = new Object(); }, "proto set on cross-origin Location"); var setters = [Object.getOwnPropertyDescriptor(Object.prototype, '__proto__').set]; if (Object.setPrototypeOf) setters.push(function(p) { Object.setPrototypeOf(this, p); }); setters.forEach(function(protoSetter) { - assert_throws(new TypeError, function() { protoSetter.call(C, new Object()); }, "proto setter |call| on cross-origin Window"); - assert_throws(new TypeError, function() { protoSetter.call(C.location, new Object()); }, "proto setter |call| on cross-origin Location"); + assert_throws(new TypeError, function() { protoSetter.call(win, new Object()); }, "proto setter |call| on cross-origin Window"); + assert_throws(new TypeError, function() { protoSetter.call(win.location, new Object()); }, "proto setter |call| on cross-origin Location"); }); // Hack to avoid "duplicate test name" harness issues. setters.forEach(function(protoSetter) { - test(function() { protoSetter.call(C, null); }, - "proto setter |call| on cross-origin Window with null (" + protoSetter + ")"); - test(function() { protoSetter.call(C.location, null); }, - "proto setter |call| on cross-origin Location with null (" + protoSetter + ")"); + test(function() { protoSetter.call(win, null); }, + "proto setter |call| on cross-origin Window with null (" + protoSetter + ", " + winName(win) + ")"); + test(function() { protoSetter.call(win.location, null); }, + "proto setter |call| on cross-origin Location with null (" + protoSetter + ", " + winName(win) + ")"); }); if (Reflect.setPrototypeOf) { - assert_false(Reflect.setPrototypeOf(C, new Object()), + assert_false(Reflect.setPrototypeOf(win, new Object()), "Reflect.setPrototypeOf on cross-origin Window"); - assert_true(Reflect.setPrototypeOf(C, null), + assert_true(Reflect.setPrototypeOf(win, null), "Reflect.setPrototypeOf on cross-origin Window with null"); - assert_false(Reflect.setPrototypeOf(C.location, new Object()), + assert_false(Reflect.setPrototypeOf(win.location, new Object()), "Reflect.setPrototypeOf on cross-origin Location"); - assert_true(Reflect.setPrototypeOf(C.location, null), + assert_true(Reflect.setPrototypeOf(win.location, null), "Reflect.setPrototypeOf on cross-origin Location with null"); } }, "[[SetPrototypeOf]] should return false"); @@ -178,18 +239,18 @@ /* * [[IsExtensible]] */ -addTest(function() { - assert_true(Object.isExtensible(C), "cross-origin Window should be extensible"); - assert_true(Object.isExtensible(C.location), "cross-origin Location should be extensible"); +addTest(function(win) { + assert_true(Object.isExtensible(win), "cross-origin Window should be extensible"); + assert_true(Object.isExtensible(win.location), "cross-origin Location should be extensible"); }, "[[IsExtensible]] should return true for cross-origin objects"); /* * [[PreventExtensions]] */ -addTest(function() { - assert_throws(new TypeError, function() { Object.preventExtensions(C) }, +addTest(function(win) { + assert_throws(new TypeError, function() { Object.preventExtensions(win) }, "preventExtensions on cross-origin Window should throw"); - assert_throws(new TypeError, function() { Object.preventExtensions(C.location) }, + assert_throws(new TypeError, function() { Object.preventExtensions(win.location) }, "preventExtensions on cross-origin Location should throw"); }, "[[PreventExtensions]] should throw for cross-origin objects"); @@ -197,11 +258,11 @@ * [[GetOwnProperty]] */ -addTest(function() { - assert_true(isObject(Object.getOwnPropertyDescriptor(C, 'close')), "C.close is |own|"); - assert_true(isObject(Object.getOwnPropertyDescriptor(C, 'top')), "C.top is |own|"); - assert_true(isObject(Object.getOwnPropertyDescriptor(C.location, 'href')), "C.location.href is |own|"); - assert_true(isObject(Object.getOwnPropertyDescriptor(C.location, 'replace')), "C.location.replace is |own|"); +addTest(function(win) { + assert_true(isObject(Object.getOwnPropertyDescriptor(win, 'close')), "win.close is |own|"); + assert_true(isObject(Object.getOwnPropertyDescriptor(win, 'top')), "win.top is |own|"); + assert_true(isObject(Object.getOwnPropertyDescriptor(win.location, 'href')), "win.location.href is |own|"); + assert_true(isObject(Object.getOwnPropertyDescriptor(win.location, 'replace')), "win.location.replace is |own|"); }, "[[GetOwnProperty]] - Properties on cross-origin objects should be reported |own|"); function checkPropertyDescriptor(desc, propName, expectWritable) { @@ -229,52 +290,52 @@ "property descriptor for " + propName + " should " + (expectWritable ? "" : "not ") + "have setter"); } -addTest(function() { +addTest(function(win) { whitelistedWindowProps.forEach(function(prop) { - var desc = Object.getOwnPropertyDescriptor(C, prop); + var desc = Object.getOwnPropertyDescriptor(win, prop); checkPropertyDescriptor(desc, prop, prop == 'location'); }); - checkPropertyDescriptor(Object.getOwnPropertyDescriptor(C.location, 'replace'), 'replace', false); - checkPropertyDescriptor(Object.getOwnPropertyDescriptor(C.location, 'href'), 'href', true); - assert_equals(typeof Object.getOwnPropertyDescriptor(C.location, 'href').get, 'undefined', "Cross-origin location should have no href getter"); + checkPropertyDescriptor(Object.getOwnPropertyDescriptor(win.location, 'replace'), 'replace', false); + checkPropertyDescriptor(Object.getOwnPropertyDescriptor(win.location, 'href'), 'href', true); + assert_equals(typeof Object.getOwnPropertyDescriptor(win.location, 'href').get, 'undefined', "Cross-origin location should have no href getter"); whitelistedSymbols.forEach(function(prop) { - var desc = Object.getOwnPropertyDescriptor(C.location, prop); + var desc = Object.getOwnPropertyDescriptor(win.location, prop); checkPropertyDescriptor(desc, prop, false); }); }, "[[GetOwnProperty]] - Property descriptors for cross-origin properties should be set up correctly"); -addTest(function() { - assert_equals(typeof D.then, "object"); +addThenTest(function(win) { + assert_equals(typeof win.then, "object"); }, "[[GetOwnProperty]] - Subframe named 'then' should shadow the default 'then' value"); -addTest(function() { - assert_equals(typeof D.close, "function"); - assert_equals(typeof D.open, "object"); +addThenTest(function(win) { + assert_equals(typeof win.close, "function"); + assert_equals(typeof win.open, "object"); }, "[[GetOwnProperty]] - Subframes should be visible cross-origin only if their names don't match the names of cross-origin-exposed IDL properties"); -addTest(function() { - assert_equals(typeof Object.getOwnPropertyDescriptor(C, '0').value, "object"); - assert_equals(typeof Object.getOwnPropertyDescriptor(C, '1').value, "object"); +addTest(function(win) { + assert_equals(typeof Object.getOwnPropertyDescriptor(win, '0').value, "object"); + assert_equals(typeof Object.getOwnPropertyDescriptor(win, '1').value, "object"); assert_throws("SecurityError", function() { - Object.getOwnPropertyDescriptor(C, '2'); + Object.getOwnPropertyDescriptor(win, '2'); }); }, "[[GetOwnProperty]] - Should be able to get a property descriptor for an indexed property only if it corresponds to a child window."); /* * [[Delete]] */ -addTest(function() { - assert_throws("SecurityError", function() { delete C[0]; }, "Can't delete cross-origin indexed property"); - assert_throws("SecurityError", function() { delete C[100]; }, "Can't delete cross-origin indexed property"); - assert_throws("SecurityError", function() { delete C.location; }, "Can't delete cross-origin property"); - assert_throws("SecurityError", function() { delete C.parent; }, "Can't delete cross-origin property"); - assert_throws("SecurityError", function() { delete C.length; }, "Can't delete cross-origin property"); - assert_throws("SecurityError", function() { delete C.document; }, "Can't delete cross-origin property"); - assert_throws("SecurityError", function() { delete C.foopy; }, "Can't delete cross-origin property"); - assert_throws("SecurityError", function() { delete C.location.href; }, "Can't delete cross-origin property"); - assert_throws("SecurityError", function() { delete C.location.replace; }, "Can't delete cross-origin property"); - assert_throws("SecurityError", function() { delete C.location.port; }, "Can't delete cross-origin property"); - assert_throws("SecurityError", function() { delete C.location.foopy; }, "Can't delete cross-origin property"); +addTest(function(win) { + assert_throws("SecurityError", function() { delete win[0]; }, "Can't delete cross-origin indexed property"); + assert_throws("SecurityError", function() { delete win[100]; }, "Can't delete cross-origin indexed property"); + assert_throws("SecurityError", function() { delete win.location; }, "Can't delete cross-origin property"); + assert_throws("SecurityError", function() { delete win.parent; }, "Can't delete cross-origin property"); + assert_throws("SecurityError", function() { delete win.length; }, "Can't delete cross-origin property"); + assert_throws("SecurityError", function() { delete win.document; }, "Can't delete cross-origin property"); + assert_throws("SecurityError", function() { delete win.foopy; }, "Can't delete cross-origin property"); + assert_throws("SecurityError", function() { delete win.location.href; }, "Can't delete cross-origin property"); + assert_throws("SecurityError", function() { delete win.location.replace; }, "Can't delete cross-origin property"); + assert_throws("SecurityError", function() { delete win.location.port; }, "Can't delete cross-origin property"); + assert_throws("SecurityError", function() { delete win.location.foopy; }, "Can't delete cross-origin property"); }, "[[Delete]] Should throw on cross-origin objects"); /* @@ -286,31 +347,31 @@ assert_throws("SecurityError", function() { Object.defineProperty(obj, prop, valueDesc); }, "Can't define cross-origin value property " + prop); assert_throws("SecurityError", function() { Object.defineProperty(obj, prop, accessorDesc); }, "Can't define cross-origin accessor property " + prop); } -addTest(function() { - checkDefine(C, 'length'); - checkDefine(C, 'parent'); - checkDefine(C, 'location'); - checkDefine(C, 'document'); - checkDefine(C, 'foopy'); - checkDefine(C.location, 'href'); - checkDefine(C.location, 'replace'); - checkDefine(C.location, 'port'); - checkDefine(C.location, 'foopy'); +addTest(function(win) { + checkDefine(win, 'length'); + checkDefine(win, 'parent'); + checkDefine(win, 'location'); + checkDefine(win, 'document'); + checkDefine(win, 'foopy'); + checkDefine(win.location, 'href'); + checkDefine(win.location, 'replace'); + checkDefine(win.location, 'port'); + checkDefine(win.location, 'foopy'); }, "[[DefineOwnProperty]] Should throw for cross-origin objects"); /* * EnumerateObjectProperties (backed by [[OwnPropertyKeys]]) */ -addTest(function() { +addTest(function(win) { let i = 0; - for (var prop in C) { + for (var prop in win) { i++; assert_true(whitelistedWindowIndices.includes(prop), prop + " is not safelisted for a cross-origin Window"); } assert_equals(i, whitelistedWindowIndices.length, "Enumerate all enumerable safelisted cross-origin Window properties"); i = 0; - for (var prop in C.location) { + for (var prop in win.location) { i++; } assert_equals(i, 0, "There's nothing to enumerate for cross-origin Location properties"); @@ -320,30 +381,30 @@ * [[OwnPropertyKeys]] */ -addTest(function() { - assert_array_equals(Object.getOwnPropertyNames(C).sort(), +addTest(function(win) { + assert_array_equals(Object.getOwnPropertyNames(win).sort(), whitelistedWindowPropNames, "Object.getOwnPropertyNames() gives the right answer for cross-origin Window"); - assert_array_equals(Object.keys(C).sort(), + assert_array_equals(Object.keys(win).sort(), whitelistedWindowIndices, "Object.keys() gives the right answer for cross-origin Window"); - assert_array_equals(Object.getOwnPropertyNames(C.location).sort(), + assert_array_equals(Object.getOwnPropertyNames(win.location).sort(), whitelistedLocationPropNames, "Object.getOwnPropertyNames() gives the right answer for cross-origin Location"); - assert_equals(Object.keys(C.location).length, 0, + assert_equals(Object.keys(win.location).length, 0, "Object.keys() gives the right answer for cross-origin Location"); }, "[[OwnPropertyKeys]] should return all properties from cross-origin objects"); -addTest(function() { - assert_array_equals(Object.getOwnPropertySymbols(C), whitelistedSymbols, +addTest(function(win) { + assert_array_equals(Object.getOwnPropertySymbols(win), whitelistedSymbols, "Object.getOwnPropertySymbols() should return the three symbol-named properties that are exposed on a cross-origin Window"); - assert_array_equals(Object.getOwnPropertySymbols(C.location), + assert_array_equals(Object.getOwnPropertySymbols(win.location), whitelistedSymbols, "Object.getOwnPropertySymbols() should return the three symbol-named properties that are exposed on a cross-origin Location"); }, "[[OwnPropertyKeys]] should return the right symbol-named properties for cross-origin objects"); -addTest(function() { - var allWindowProps = Reflect.ownKeys(C); +addTest(function(win) { + var allWindowProps = Reflect.ownKeys(win); indexedWindowProps = allWindowProps.slice(0, whitelistedWindowIndices.length); stringWindowProps = allWindowProps.slice(0, -1 * whitelistedSymbols.length); symbolWindowProps = allWindowProps.slice(-1 * whitelistedSymbols.length); @@ -358,7 +419,7 @@ assert_array_equals(symbolWindowProps, whitelistedSymbols, "Reflect.ownKeys should end with the cross-origin symbols for a cross-origin Window."); - var allLocationProps = Reflect.ownKeys(C.location); + var allLocationProps = Reflect.ownKeys(win.location); stringLocationProps = allLocationProps.slice(0, -1 * whitelistedSymbols.length); symbolLocationProps = allLocationProps.slice(-1 * whitelistedSymbols.length); assert_array_equals(stringLocationProps.sort(), whitelistedLocationPropNames, @@ -367,20 +428,20 @@ "Reflect.ownKeys should end with the cross-origin symbols for a cross-origin Location.") }, "[[OwnPropertyKeys]] should place the symbols after the property names after the subframe indices"); -addTest(function() { - var stringProps = Object.getOwnPropertyNames(D); +addThenTest(function(win) { + var stringProps = Object.getOwnPropertyNames(win); // Named frames are not exposed via [[OwnPropertyKeys]]. assert_equals(stringProps.indexOf("a"), -1); assert_equals(stringProps.indexOf("b"), -1); - assert_equals(typeof D.a, "object"); - assert_equals(typeof D.b, "object"); + assert_equals(typeof win.a, "object"); + assert_equals(typeof win.b, "object"); assert_equals(stringProps[stringProps.length - 1], "then"); assert_equals(stringProps.indexOf("then"), stringProps.lastIndexOf("then")); }, "[[OwnPropertyKeys]] should not reorder where 'then' appears if it's a named subframe, nor add another copy of 'then'"); -addTest(function() { - assert_equals(B.eval('parent.C'), C, "A and B observe the same identity for C's Window"); - assert_equals(B.eval('parent.C.location'), C.location, "A and B observe the same identity for C's Location"); +addTest(function(win) { + assert_equals(B.eval('parent.' + winName(win)), win, "A and B observe the same identity for C's Window"); + assert_equals(B.eval('parent.' + winName(win) + '.location'), win.location, "A and B observe the same identity for C's Location"); }, "A and B jointly observe the same identity for cross-origin Window and Location"); function checkFunction(f, proto) { @@ -389,40 +450,40 @@ assert_equals(Object.getPrototypeOf(f), proto, f.name + " has the right prototype"); } -addTest(function() { - checkFunction(C.close, Function.prototype); - checkFunction(C.location.replace, Function.prototype); +addTest(function(win) { + checkFunction(win.close, Function.prototype); + checkFunction(win.location.replace, Function.prototype); }, "Cross-origin functions get local Function.prototype"); -addTest(function() { - assert_true(isObject(Object.getOwnPropertyDescriptor(C, 'parent')), +addTest(function(win) { + assert_true(isObject(Object.getOwnPropertyDescriptor(win, 'parent')), "Need to be able to use Object.getOwnPropertyDescriptor do this test"); - checkFunction(Object.getOwnPropertyDescriptor(C, 'parent').get, Function.prototype); - checkFunction(Object.getOwnPropertyDescriptor(C.location, 'href').set, Function.prototype); + checkFunction(Object.getOwnPropertyDescriptor(win, 'parent').get, Function.prototype); + checkFunction(Object.getOwnPropertyDescriptor(win.location, 'href').set, Function.prototype); }, "Cross-origin Window accessors get local Function.prototype"); -addTest(function() { +addTest(function(win) { checkFunction(close, Function.prototype); assert_not_equals(close, B.close, 'same-origin Window functions get their own object'); - assert_not_equals(close, C.close, 'cross-origin Window functions get their own object'); - var close_B = B.eval('parent.C.close'); + assert_not_equals(close, win.close, 'cross-origin Window functions get their own object'); + var close_B = B.eval('parent.' + winName(win) + '.close'); assert_not_equals(close, close_B, 'close_B is unique when viewed by the parent'); - assert_not_equals(close_B, C.close, 'different Window functions per-incumbent script settings object'); + assert_not_equals(close_B, win.close, 'different Window functions per-incumbent script settings object'); checkFunction(close_B, B.Function.prototype); checkFunction(location.replace, Function.prototype); - assert_not_equals(location.replace, C.location.replace, "cross-origin Location functions get their own object"); - var replace_B = B.eval('parent.C.location.replace'); - assert_not_equals(replace_B, C.location.replace, 'different Location functions per-incumbent script settings object'); + assert_not_equals(location.replace, win.location.replace, "cross-origin Location functions get their own object"); + var replace_B = B.eval('parent.' + winName(win) + '.location.replace'); + assert_not_equals(replace_B, win.location.replace, 'different Location functions per-incumbent script settings object'); checkFunction(replace_B, B.Function.prototype); }, "Same-origin observers get different functions for cross-origin objects"); -addTest(function() { - assert_true(isObject(Object.getOwnPropertyDescriptor(C, 'parent')), +addTest(function(win) { + assert_true(isObject(Object.getOwnPropertyDescriptor(win, 'parent')), "Need to be able to use Object.getOwnPropertyDescriptor do this test"); var get_self_parent = Object.getOwnPropertyDescriptor(window, 'parent').get; - var get_parent_A = Object.getOwnPropertyDescriptor(C, 'parent').get; - var get_parent_B = B.eval('Object.getOwnPropertyDescriptor(parent.C, "parent").get'); + var get_parent_A = Object.getOwnPropertyDescriptor(win, 'parent').get; + var get_parent_B = B.eval('Object.getOwnPropertyDescriptor(parent.' + winName(win) + ', "parent").get'); assert_not_equals(get_self_parent, get_parent_A, 'different Window accessors per-incumbent script settings object'); assert_not_equals(get_parent_A, get_parent_B, 'different Window accessors per-incumbent script settings object'); checkFunction(get_self_parent, Function.prototype); @@ -430,10 +491,10 @@ checkFunction(get_parent_B, B.Function.prototype); }, "Same-origin observers get different accessors for cross-origin Window"); -addTest(function() { +addTest(function(win) { var set_self_href = Object.getOwnPropertyDescriptor(window.location, 'href').set; - var set_href_A = Object.getOwnPropertyDescriptor(C.location, 'href').set; - var set_href_B = B.eval('Object.getOwnPropertyDescriptor(parent.C.location, "href").set'); + var set_href_A = Object.getOwnPropertyDescriptor(win.location, 'href').set; + var set_href_B = B.eval('Object.getOwnPropertyDescriptor(parent.' + winName(win) + '.location, "href").set'); assert_not_equals(set_self_href, set_href_A, 'different Location accessors per-incumbent script settings object'); assert_not_equals(set_href_A, set_href_B, 'different Location accessors per-incumbent script settings object'); checkFunction(set_self_href, Function.prototype); @@ -441,28 +502,64 @@ checkFunction(set_href_B, B.Function.prototype); }, "Same-origin observers get different accessors for cross-origin Location"); -addTest(function() { - assert_equals({}.toString.call(C), "[object Object]"); - assert_equals({}.toString.call(C.location), "[object Object]"); +addTest(function(win) { + assert_equals({}.toString.call(win), "[object Object]"); + assert_equals({}.toString.call(win.location), "[object Object]"); }, "{}.toString.call() does the right thing on cross-origin objects"); addPromiseTest(function() { return Promise.resolve(C).then((arg) => { assert_equals(arg, C); }); -}, "Resolving a promise with a cross-origin window without a 'then' subframe should work."); +}, "Resolving a promise with a cross-origin window without a 'then' subframe should work (cross-origin)."); + +addPromiseTest(function() { + return Promise.resolve(E).then((arg) => { + assert_equals(arg, E); + }); +}, "Resolving a promise with a cross-origin window without a 'then' subframe should work (same-origin + document.domain)."); + +addPromiseTest(function() { + return Promise.resolve(G).then((arg) => { + assert_equals(arg, G); + }); +}, "Resolving a promise with a cross-origin window without a 'then' subframe should work (cross-site)."); addPromiseTest(function() { return Promise.resolve(D).then((arg) => { assert_equals(arg, D); }); -}, "Resolving a promise with a cross-origin window with a 'then' subframe should work."); +}, "Resolving a promise with a cross-origin window with a 'then' subframe should work (cross-origin)."); + +addPromiseTest(function() { + return Promise.resolve(F).then((arg) => { + assert_equals(arg, F); + }); +}, "Resolving a promise with a cross-origin window with a 'then' subframe should work (same-origin + document.domain)."); + +addPromiseTest(function() { + return Promise.resolve(H).then((arg) => { + assert_equals(arg, H); + }); +}, "Resolving a promise with a cross-origin window with a 'then' subframe should work (cross-site)."); addPromiseTest(function() { return Promise.resolve(D.location).then((arg) => { assert_equals(arg, D.location); }); -}, "Resolving a promise with a cross-origin location should work."); +}, "Resolving a promise with a cross-origin location should work (cross-origin)."); + +addPromiseTest(function() { + return Promise.resolve(F.location).then((arg) => { + assert_equals(arg, F.location); + }); +}, "Resolving a promise with a cross-origin location should work (same-origin + document.domain)."); + +addPromiseTest(function() { + return Promise.resolve(H.location).then((arg) => { + assert_equals(arg, H.location); + }); +}, "Resolving a promise with a cross-origin location should work (cross-site)."); // We do a fresh load of the subframes for each test to minimize side-effects. // It would be nice to reload ourselves as well, but we can't do that without @@ -478,9 +575,14 @@ function runNextTest() { var entry = testList.shift(); if (entry.promiseTest) { - promise_test(() => entry.func().finally(testDone), entry.desc); + test(function() { + assert_equals(entry.tests.length, 1, "We can't handle this yet"); + }); + promise_test(() => entry.tests[0].func().finally(testDone), entry.tests[0].desc); } else { - test(entry.func, entry.desc); + for (t of entry.tests) { + test(t.func, t.desc); + } testDone(); } }
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/origin/cross-origin-objects/frame-with-then.html b/third_party/blink/web_tests/external/wpt/html/browsers/origin/cross-origin-objects/frame-with-then.html index 1127995..3eedeca 100644 --- a/third_party/blink/web_tests/external/wpt/html/browsers/origin/cross-origin-objects/frame-with-then.html +++ b/third_party/blink/web_tests/external/wpt/html/browsers/origin/cross-origin-objects/frame-with-then.html
@@ -1,5 +1,10 @@ <!doctype html> <html> + <script> + if (location.search == "?setdomain") { + document.domain = document.domain; + } + </script> <body> <!--- Some frames to test ordering --> <iframe name="a"></iframe>
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/origin/cross-origin-objects/frame.html b/third_party/blink/web_tests/external/wpt/html/browsers/origin/cross-origin-objects/frame.html index 0d81624..3226c87193 100644 --- a/third_party/blink/web_tests/external/wpt/html/browsers/origin/cross-origin-objects/frame.html +++ b/third_party/blink/web_tests/external/wpt/html/browsers/origin/cross-origin-objects/frame.html
@@ -2,6 +2,10 @@ <html> <head> <script> + if (location.search == "?setdomain") { + document.domain = document.domain; + } + // Override the |frames| property to test that such overrides are // properly ignored cross-origin. window.frames = "override";
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/windows/embedded-opener-remove-frame.html b/third_party/blink/web_tests/external/wpt/html/browsers/windows/embedded-opener-remove-frame.html index 9bce93f..a66f52e5 100644 --- a/third_party/blink/web_tests/external/wpt/html/browsers/windows/embedded-opener-remove-frame.html +++ b/third_party/blink/web_tests/external/wpt/html/browsers/windows/embedded-opener-remove-frame.html
@@ -1,10 +1,48 @@ <!doctype html> -<title>opener and "removed" embedded documents</title> +<title>opener and discarded browsing contexts</title> <script src=/resources/testharness.js></script> <script src=/resources/testharnessreport.js></script> <div id=log></div> <iframe name=matchesastring></iframe> <script> +function testOpener(t, otherW, thisW, discardOtherBC, isDiscardedFromATask) { + assert_equals(otherW.opener, thisW, "opener before removal"); + + const openerDesc = Object.getOwnPropertyDescriptor(otherW, "opener"), + openerGet = openerDesc.get; + + assert_equals(openerGet(), thisW, "opener before removal via directly invoking the getter"); + discardOtherBC(); + if (isDiscardedFromATask) { + t.step_timeout(() => { + testOpenerRemainder(t, otherW, openerDesc, openerGet); + }, 250); + } else { + testOpenerRemainder(t, otherW, openerDesc, openerGet); + } +} + +function testOpenerRemainder(t, otherW, openerDesc, openerGet) { + assert_equals(otherW.opener, null, "opener after removal"); + assert_equals(openerGet(), null, "opener after removal via directly invoking the getter"); + + otherW.opener = null; + assert_equals(openerGet(), null, "opener after setting it null via directly invoking the getter"); + const openerDescNull = Object.getOwnPropertyDescriptor(otherW, "opener"); + assert_not_equals(openerDescNull, openerDesc); + assert_object_equals(openerDescNull, openerDesc); + + otherW.opener = "immaterial"; + assert_equals(openerGet(), null, "opener after setting it \"immaterial\" via directly invoking the getter"); + const openerDescImmaterial = Object.getOwnPropertyDescriptor(otherW, "opener"); + assert_equals(openerDescImmaterial.value, "immaterial"); + assert_true(openerDescImmaterial.writable); + assert_true(openerDescImmaterial.enumerable); + assert_true(openerDescImmaterial.configurable); + + t.done(); +} + async_test(t => { const frame = document.querySelector("iframe"), frameW = frame.contentWindow; @@ -14,33 +52,15 @@ return; } - // Test bits - assert_equals(frameW.opener, window, "opener before removal"); - - const openerDesc = Object.getOwnPropertyDescriptor(frameW, "opener"), - openerGet = openerDesc.get; - - assert_equals(openerGet(), window, "opener before removal via directly invoking the getter"); - frame.remove(); - assert_equals(frameW.opener, null, "opener after removal"); - assert_equals(openerGet(), null, "opener after removal via directly invoking the getter"); - - frameW.opener = null; - assert_equals(openerGet(), null, "opener after setting it null via directly invoking the getter"); - const openerDescNull = Object.getOwnPropertyDescriptor(frameW, "opener"); - assert_not_equals(openerDescNull, openerDesc); - assert_object_equals(openerDescNull, openerDesc); - - frameW.opener = "immaterial"; - assert_equals(openerGet(), null, "opener after setting it \"immaterial\" via directly invoking the getter"); - const openerDescImmaterial = Object.getOwnPropertyDescriptor(frameW, "opener"); - assert_equals(openerDescImmaterial.value, "immaterial"); - assert_true(openerDescImmaterial.writable); - assert_true(openerDescImmaterial.enumerable); - assert_true(openerDescImmaterial.configurable); - - t.done(); + testOpener(t, frameW, window, () => frame.remove(), false); }); window.open("/common/blank.html", "matchesastring"); -}); +}, "opener of discarded nested browsing context"); + +async_test(t => { + const popupW = window.open("/common/blank.html"); + popupW.onload = t.step_func(() => { + testOpener(t, popupW, window, () => popupW.close(), true); + }); +}, "opener of discarded auxiliary browsing context"); </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.whitespace.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.whitespace.html index f4662b45f..efb263eb 100644 --- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.whitespace.html +++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.whitespace.html
@@ -12,8 +12,8 @@ <p class="output">Actual output:</p> -<canvas id="c" class="output" width=" - 100" height=" +<canvas id="c" class="output" width="
 + 100" height="
 100"><p class="fallback">FAIL (fallback content)</p></canvas> <p class="output expectedtext">Expected output:<p><img src="size.attributes.parse.whitespace.png" class="output expected" id="expected" alt=""> <ul id="d"></ul> @@ -24,8 +24,8 @@ _assertSame(canvas.width, 100, "canvas.width", "100"); _assertSame(canvas.height, 100, "canvas.height", "100"); _assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "100px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"100px\""); -_assertSame(canvas.getAttribute('width'), '\n\t\x0c100', "canvas.getAttribute('width')", "'\\n\\t\\x0c100'"); -_assertSame(canvas.getAttribute('height'), '\n\t\x0c100', "canvas.getAttribute('height')", "'\\n\\t\\x0c100'"); +_assertSame(canvas.getAttribute('width'), '\r\n\t\x0c100', "canvas.getAttribute('width')", "'\\r\\n\\t\\x0c100'"); +_assertSame(canvas.getAttribute('height'), '\r\n\t\x0c100', "canvas.getAttribute('height')", "'\\r\\n\\t\\x0c100'"); });
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.whitespace.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.whitespace.html index 9d85fe7..8a01f57 100644 --- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.whitespace.html +++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.whitespace.html
@@ -19,13 +19,13 @@ var t = async_test("Parsing of non-negative integers in setAttribute"); _addTest(function(canvas, ctx) { -canvas.setAttribute('width', '\n\t\x0c100'); -canvas.setAttribute('height', '\n\t\x0c100'); +canvas.setAttribute('width', '\r\n\t\x0c100'); +canvas.setAttribute('height', '\r\n\t\x0c100'); _assertSame(canvas.width, 100, "canvas.width", "100"); _assertSame(canvas.height, 100, "canvas.height", "100"); _assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "100px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"100px\""); -_assertSame(canvas.getAttribute('width'), '\n\t\x0c100', "canvas.getAttribute('width')", "'\\n\\t\\x0c100'"); -_assertSame(canvas.getAttribute('height'), '\n\t\x0c100', "canvas.getAttribute('height')", "'\\n\\t\\x0c100'"); +_assertSame(canvas.getAttribute('width'), '\r\n\t\x0c100', "canvas.getAttribute('width')", "'\\r\\n\\t\\x0c100'"); +_assertSame(canvas.getAttribute('height'), '\r\n\t\x0c100', "canvas.getAttribute('height')", "'\\r\\n\\t\\x0c100'"); });
diff --git a/third_party/blink/web_tests/external/wpt/import-maps/resolving.tentative-expected.txt b/third_party/blink/web_tests/external/wpt/import-maps/resolving.tentative-expected.txt index 4dc845e..b5da0063 100644 --- a/third_party/blink/web_tests/external/wpt/import-maps/resolving.tentative-expected.txt +++ b/third_party/blink/web_tests/external/wpt/import-maps/resolving.tentative-expected.txt
@@ -7,7 +7,7 @@ FAIL Unmapped / should fail for strings not parseable as absolute URLs and not starting with ./ ../ or / assert_throws: function "() => resolveUnderTest('https://ex ample.org/')" did not throw PASS Mapped using the "imports" key only (no scopes) / should fail when the mapping is to an empty array PASS Mapped using the "imports" key only (no scopes) / Package-like scenarios / should work for package main modules -FAIL Mapped using the "imports" key only (no scopes) / Package-like scenarios / should work for package submodules Failed to resolve module specifier moment/foo: Relative references must start with either "/", "./", or "../". +PASS Mapped using the "imports" key only (no scopes) / Package-like scenarios / should work for package submodules PASS Mapped using the "imports" key only (no scopes) / Package-like scenarios / should work for package names that end in a slash by just passing through PASS Mapped using the "imports" key only (no scopes) / Package-like scenarios / should still fail for package modules that are not declared PASS Mapped using the "imports" key only (no scopes) / Tricky specifiers / should work for explicitly-mapped specifiers that happen to have a slash @@ -18,5 +18,6 @@ PASS Mapped using the "imports" key only (no scopes) / URL-like specifiers / should fail for URLs that remap to empty arrays PASS Mapped using the "imports" key only (no scopes) / URL-like specifiers / should remap URLs that are just composed from / and . PASS Mapped using the "imports" key only (no scopes) / URL-like specifiers / should use the last entry's address when URL-like specifiers parse to the same absolute URL +PASS Mapped using the "imports" key only (no scopes) / overlapping entries with trailing slashes / most-specific wins Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/import-maps/resources/resolving.js b/third_party/blink/web_tests/external/wpt/import-maps/resources/resolving.js index ec2645e..0409962 100644 --- a/third_party/blink/web_tests/external/wpt/import-maps/resources/resolving.js +++ b/third_party/blink/web_tests/external/wpt/import-maps/resources/resolving.js
@@ -1,4 +1,9 @@ 'use strict'; + +// Imported from: +// https://github.com/WICG/import-maps/blob/master/reference-implementation/__tests__/resolving.js +// TODO: Upstream local changes. + const { URL } = require('url'); const { parseFromString } = require('../lib/parser.js'); const { resolve } = require('../lib/resolver.js'); @@ -203,4 +208,23 @@ expect(resolveUnderTest('/test')).toMatchURL('https://example.com/lib/test2.mjs'); }); }); + + describe('overlapping entries with trailing slashes', () => { + const resolveUnderTest = makeResolveUnderTest(`{ + "imports": { + "a": "/1", + "a/": "/2/", + "a/b": "/3", + "a/b/": "/4/" + } + }`); + + it('most-specific wins', () => { + expect(resolveUnderTest('a')).toMatchURL('https://example.com/1'); + expect(resolveUnderTest('a/')).toMatchURL('https://example.com/2/'); + expect(resolveUnderTest('a/b')).toMatchURL('https://example.com/3'); + expect(resolveUnderTest('a/b/')).toMatchURL('https://example.com/4/'); + expect(resolveUnderTest('a/b/c')).toMatchURL('https://example.com/4/c'); + }); + }); });
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/web-nfc.idl b/third_party/blink/web_tests/external/wpt/interfaces/web-nfc.idl index 11a36cd..a570916 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/web-nfc.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/web-nfc.idl
@@ -4,6 +4,7 @@ // Source: Web NFC API (https://w3c.github.io/web-nfc/) dictionary NDEFMessage { + DOMString? serialNumber; sequence<NDEFRecord> records; USVString url; };
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/webxr.idl b/third_party/blink/web_tests/external/wpt/interfaces/webxr.idl index 899bb0d..e91a50c 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/webxr.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/webxr.idl
@@ -88,6 +88,7 @@ }; enum XRReferenceSpaceType { + "identity", "stationary", "bounded", "unbounded"
diff --git a/third_party/blink/web_tests/external/wpt/screen-orientation/onchange-event.html b/third_party/blink/web_tests/external/wpt/screen-orientation/onchange-event.html index 401af09..635ff82 100644 --- a/third_party/blink/web_tests/external/wpt/screen-orientation/onchange-event.html +++ b/third_party/blink/web_tests/external/wpt/screen-orientation/onchange-event.html
@@ -1,6 +1,8 @@ <!DOCTYPE html> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> <script> promise_test(async t => { await test_driver.bless("request full screen", () => {
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/script-tests/cache-match.js b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/script-tests/cache-match.js index b2b731c..8bf7fda 100644 --- a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/script-tests/cache-match.js +++ b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/script-tests/cache-match.js
@@ -356,4 +356,62 @@ assert_equals(headers.get('set-cookie'), null); }, 'cors-exposed header should be stored correctly.'); +cache_test(async (cache) => { + // A URL that should load a resource with a known mime type. + const url = '/service-workers/cache-storage/resources/blank.html'; + const expected_mime_type = 'text/html'; + + // Verify we get the expected mime type from the network. Note, + // we cannot use an exact match here since some browsers append + // character encoding information to the blob.type value. + const net_response = await fetch(url); + const net_mime_type = (await net_response.blob()).type; + assert_true(net_mime_type.includes(expected_mime_type), + 'network response should include the expected mime type'); + + // Verify we get the exact same mime type when reading the same + // URL resource back out of the cache. + await cache.add(url); + const cache_response = await cache.match(url); + const cache_mime_type = (await cache_response.blob()).type; + assert_equals(cache_mime_type, net_mime_type, + 'network and cache response mime types should match'); + }, 'MIME type should be set from content-header correctly.'); + +cache_test(async (cache) => { + const url = '/dummy'; + const original_type = 'text/html'; + const init_with_headers = { + headers: { + 'content-type': original_type + } + } + + // Verify constructing a synthetic response with a content-type header + // gets the correct mime type. + const response = new Response('hello world', init_with_headers); + const original_response_type = (await response.blob()).type; + assert_true(original_response_type.includes(original_type), + 'original response should include the expected mime type'); + + // Verify overwriting the content-type header does not change the mime + // type. It should be fixed at Response construction time. + const overwritten_response = new Response('hello world', init_with_headers); + overwritten_response.headers.set('content-type', 'text/plain'); + const overwritten_response_type = (await overwritten_response.blob()).type; + assert_equals(overwritten_response_type, original_response_type, + 'original and overwritten response mime types should match'); + + // Verify the Response read from Cache uses the original mime type + // computed when it was first constructed. + const tmp = new Response('hello world', init_with_headers); + tmp.headers.set('content-type', 'text/plain'); + await cache.put(url, tmp); + const cache_response = await cache.match(url); + const cache_mime_type = (await cache_response.blob()).type; + assert_equals(cache_mime_type, original_response_type, + 'original and cached overwritten response mime types ' + + 'should match'); + }, 'MIME type should be frozen at response construction.'); + done();
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/serviceworker/cache-match.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/serviceworker/cache-match.https-expected.txt new file mode 100644 index 0000000..3f30ee1 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/serviceworker/cache-match.https-expected.txt
@@ -0,0 +1,28 @@ +This is a testharness.js-based test. +PASS Cache.match +PASS Cache.match with no matching entries +PASS Cache.match with URL +PASS Cache.match with Request +PASS Cache.match with multiple cache hits +PASS Cache.match with new Request +PASS Cache.match with HEAD +PASS Cache.match with ignoreSearch option (request with no search parameters) +PASS Cache.match with ignoreSearch option (request with search parameter) +PASS Cache.match supports ignoreMethod +PASS Cache.match supports ignoreVary +PASS Cache.match does not support cacheName option +PASS Cache.match with URL containing fragment +PASS Cache.match with string fragment "http" as query +PASS Cache.match with responses containing "Vary" header +PASS Cache.match with Request and Response objects with different URLs +PASS Cache.match invoked multiple times for the same Request/Response +PASS Cache.match blob should be sliceable +PASS Cache.match with POST Request +PASS Cache.match with a non-2xx Response +PASS Cache.match with a network error Response +PASS Cache produces large Responses that can be cloned and read correctly. +PASS cors-exposed header should be stored correctly. +PASS MIME type should be set from content-header correctly. +FAIL MIME type should be frozen at response construction. assert_equals: original and cached overwritten response mime types should match expected "text/html" but got "text/plain" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/window/cache-match.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/window/cache-match.https-expected.txt new file mode 100644 index 0000000..7326e23 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/window/cache-match.https-expected.txt
@@ -0,0 +1,27 @@ +This is a testharness.js-based test. +PASS Cache.match with no matching entries +PASS Cache.match with URL +PASS Cache.match with Request +PASS Cache.match with multiple cache hits +PASS Cache.match with new Request +PASS Cache.match with HEAD +PASS Cache.match with ignoreSearch option (request with no search parameters) +PASS Cache.match with ignoreSearch option (request with search parameter) +PASS Cache.match supports ignoreMethod +PASS Cache.match supports ignoreVary +PASS Cache.match does not support cacheName option +PASS Cache.match with URL containing fragment +PASS Cache.match with string fragment "http" as query +PASS Cache.match with responses containing "Vary" header +PASS Cache.match with Request and Response objects with different URLs +PASS Cache.match invoked multiple times for the same Request/Response +PASS Cache.match blob should be sliceable +PASS Cache.match with POST Request +PASS Cache.match with a non-2xx Response +PASS Cache.match with a network error Response +PASS Cache produces large Responses that can be cloned and read correctly. +PASS cors-exposed header should be stored correctly. +PASS MIME type should be set from content-header correctly. +FAIL MIME type should be frozen at response construction. assert_equals: original and cached overwritten response mime types should match expected "text/html" but got "text/plain" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/worker/cache-match.https-expected.txt b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/worker/cache-match.https-expected.txt new file mode 100644 index 0000000..7326e23 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/service-workers/cache-storage/worker/cache-match.https-expected.txt
@@ -0,0 +1,27 @@ +This is a testharness.js-based test. +PASS Cache.match with no matching entries +PASS Cache.match with URL +PASS Cache.match with Request +PASS Cache.match with multiple cache hits +PASS Cache.match with new Request +PASS Cache.match with HEAD +PASS Cache.match with ignoreSearch option (request with no search parameters) +PASS Cache.match with ignoreSearch option (request with search parameter) +PASS Cache.match supports ignoreMethod +PASS Cache.match supports ignoreVary +PASS Cache.match does not support cacheName option +PASS Cache.match with URL containing fragment +PASS Cache.match with string fragment "http" as query +PASS Cache.match with responses containing "Vary" header +PASS Cache.match with Request and Response objects with different URLs +PASS Cache.match invoked multiple times for the same Request/Response +PASS Cache.match blob should be sliceable +PASS Cache.match with POST Request +PASS Cache.match with a non-2xx Response +PASS Cache.match with a network error Response +PASS Cache produces large Responses that can be cloned and read correctly. +PASS cors-exposed header should be stored correctly. +PASS MIME type should be set from content-header correctly. +FAIL MIME type should be frozen at response construction. assert_equals: original and cached overwritten response mime types should match expected "text/html" but got "text/plain" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/shadow-dom/untriaged/shadow-trees/text-decoration-001-ref.html b/third_party/blink/web_tests/external/wpt/shadow-dom/untriaged/shadow-trees/text-decoration-001-ref.html deleted file mode 100644 index 8c10d25..0000000 --- a/third_party/blink/web_tests/external/wpt/shadow-dom/untriaged/shadow-trees/text-decoration-001-ref.html +++ /dev/null
@@ -1,13 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <meta charset="utf-8"> - <title>Shadow DOM Test</title> - <link rel="author" title="Masaya Iseki" href="mailto:iseki.m.aa@gmail.com"> - </head> - <body> - <span> - if NOT underlined, it is success. - </span> - </body> -</html>
diff --git a/third_party/blink/web_tests/external/wpt/shadow-dom/untriaged/shadow-trees/text-decoration-001.html b/third_party/blink/web_tests/external/wpt/shadow-dom/untriaged/shadow-trees/text-decoration-001.html deleted file mode 100644 index d8def126..0000000 --- a/third_party/blink/web_tests/external/wpt/shadow-dom/untriaged/shadow-trees/text-decoration-001.html +++ /dev/null
@@ -1,22 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <meta charset="utf-8" > - <title>Text Decoration Under Line Test</title> - <link rel="match" href="text-decoration-001-ref.html"> - <link rel="author" title="Masaya Iseki" href="mailto:iseki.m.aa@gmail.com"> - <link rel="help" href="https://www.w3.org/TR/shadow-dom/#text-decoration-property"> - <meta name="assert" content="When shadow host has text-decoration, shadow tree is not affected."> - </head> - <body> - <span id="parent" style="text-decoration: underline"> - </span> - <script> - var parent = document.getElementById('parent'); - var shadow = parent.attachShadow({mode: 'open'}); - var child = document.createElement('span'); - child.textContent = "if NOT underlined, it is success."; - shadow.appendChild(child); - </script> - </body> -</html>
diff --git a/third_party/blink/web_tests/external/wpt/tools/manifest/vcs.py b/third_party/blink/web_tests/external/wpt/tools/manifest/vcs.py index 5e5b8df5..ecd565cf 100644 --- a/third_party/blink/web_tests/external/wpt/tools/manifest/vcs.py +++ b/third_party/blink/web_tests/external/wpt/tools/manifest/vcs.py
@@ -100,16 +100,15 @@ for result in self.git(*cmd).split("\0")[:-1]: rel_path = result.split("\t")[-1] hash = result.split()[2] - if not os.path.isdir(os.path.join(self.root, rel_path)): - if rel_path in local_changes: - contents = self._show_file(rel_path) - else: - contents = None - yield SourceFile(self.root, - rel_path, - self.url_base, - hash, - contents=contents), True + if rel_path in local_changes: + contents = self._show_file(rel_path) + else: + contents = None + yield SourceFile(self.root, + rel_path, + self.url_base, + hash, + contents=contents), True def dump_caches(self): pass
diff --git a/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/metadata.py b/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/metadata.py index 8699ac4..b951ea5b 100644 --- a/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/metadata.py +++ b/third_party/blink/web_tests/external/wpt/tools/wptrunner/wptrunner/metadata.py
@@ -55,7 +55,7 @@ print("disabled: %s" % test.root.test_path) -def do_delayed_imports(serve_root): +def do_delayed_imports(serve_root=None): global manifest, manifestitem from manifest import manifest, item as manifestitem @@ -443,8 +443,9 @@ def create_test_tree(metadata_path, test_manifest): """Create a map of test_id to TestFileData for that test. """ + do_delayed_imports() id_test_map = {} - exclude_types = frozenset(["stub", "helper", "manual", "support", "conformancechecker"]) + exclude_types = frozenset(["stub", "helper", "manual", "support", "conformancechecker", "reftest_base"]) all_types = manifestitem.item_types.keys() include_types = set(all_types) - exclude_types for item_type, test_path, tests in test_manifest.itertypes(*include_types):
diff --git a/third_party/blink/web_tests/external/wpt/web-nfc/NFCReader-expected.txt b/third_party/blink/web_tests/external/wpt/web-nfc/NFCReader-expected.txt new file mode 100644 index 0000000..7643110f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/web-nfc/NFCReader-expected.txt
@@ -0,0 +1,6 @@ +This is a testharness.js-based test. +FAIL Test that NFCReader.start fails if NFCReaderOptions.url is missing components. promise_test: Unhandled rejection with value: object "ReferenceError: NFCReader is not defined" +FAIL Test that NFCReader.start fails if NFCReaderOptions.url is invalid. promise_test: Unhandled rejection with value: object "ReferenceError: NFCReader is not defined" +FAIL Test that NFCReader.start fails if NFCReaderOptions.url has wrong protocol. promise_test: Unhandled rejection with value: object "ReferenceError: NFCReader is not defined" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/web-nfc/NFCReader-manual.https-expected.txt b/third_party/blink/web_tests/external/wpt/web-nfc/NFCReader-manual.https-expected.txt new file mode 100644 index 0000000..c1656d8 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/web-nfc/NFCReader-manual.https-expected.txt
@@ -0,0 +1,8 @@ +This is a testharness.js-based test. +FAIL Test that nfc watch success if NFC HW is enabled. promise_test: Unhandled rejection with value: object "ReferenceError: NFCReader is not defined" +FAIL Test that NFCReader.start succeeds if NFCReaderOptions.url is valid URL. promise_test: Unhandled rejection with value: object "ReferenceError: NFCReader is not defined" +FAIL Test that NFCReader.start succeeds if NFCReaderOptions.url is valid URL with "*" wildcard character in path. promise_test: Unhandled rejection with value: object "ReferenceError: NFCReader is not defined" +FAIL Test that NFCReader.start succeeds if NFCReaderOptions.url is valid URL with "*" wildcard character in the beginning of path component followed by subpath. promise_test: Unhandled rejection with value: object "ReferenceError: NFCReader is not defined" +FAIL Test that NFCReader.start succeeds if NFCReaderOptions.url is empty. promise_test: Unhandled rejection with value: object "ReferenceError: NFCReader is not defined" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/web-nfc/NFCReader-manual.https.html b/third_party/blink/web_tests/external/wpt/web-nfc/NFCReader-manual.https.html new file mode 100644 index 0000000..a3171c3 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/web-nfc/NFCReader-manual.https.html
@@ -0,0 +1,64 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Web NFC: NFCReader tests</title> +<link rel="author" title="Intel" href="http://www.intel.com"/> +<link rel="help" href="https://w3c.github.io/web-nfc/"/> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<meta name="flags" content="interact"> + +<p>Tap an NFC tag to the test device with NFC support.</p> + +<p>Note: All the actions need to be done in 60 seconds, otherwise it will get TIMEOUT.</p> + +<div id="log"></div> + +<script> + +"use strict"; + +promise_test(async t => { + const reader = new NFCReader(); + const readerWatcher = new EventWatcher(t, reader, ["reading", "error"]); + reader.start(); + const event = await readerWatcher.wait_for("reading"); + assert_true(event instanceof NFCReadingEvent); +}, 'Test that nfc watch success if NFC HW is enabled.'); + +promise_test(async t => { + const reader = new NFCReader({url: "https://a.com"}); + const readerWatcher = new EventWatcher(t, reader, ["reading", "error"]); + reader.start(); + const event = await readerWatcher.wait_for("reading"); + assert_true(event instanceof NFCReadingEvent); +}, 'Test that NFCReader.start succeeds if NFCReaderOptions.url is valid URL.'); + +promise_test(async t => { + const reader = new NFCReader({url: "https://a.com/*"}); + const readerWatcher = new EventWatcher(t, reader, ["reading", "error"]); + reader.start(); + const event = await readerWatcher.wait_for("reading"); + assert_true(event instanceof NFCReadingEvent); +}, 'Test that NFCReader.start succeeds if NFCReaderOptions.url is valid URL with "*"' + + ' wildcard character in path.'); + +promise_test(async t => { + const reader = new NFCReader({url: "https://a.com/*/bar"}); + const readerWatcher = new EventWatcher(t, reader, ["reading", "error"]); + reader.start(); + const event = await readerWatcher.wait_for("reading"); + assert_true(event instanceof NFCReadingEvent); +}, 'Test that NFCReader.start succeeds if NFCReaderOptions.url is valid URL with "*"' + + ' wildcard character in the beginning of path component followed by' + + ' subpath.'); + +promise_test(async t => { + const reader = new NFCReader({url: ""}); + const readerWatcher = new EventWatcher(t, reader, ["reading", "error"]); + reader.start(); + const event = await readerWatcher.wait_for("reading"); + assert_true(event instanceof NFCReadingEvent); +}, 'Test that NFCReader.start succeeds if NFCReaderOptions.url is empty.'); + +</script>
diff --git a/third_party/blink/web_tests/external/wpt/web-nfc/NFCReader.html b/third_party/blink/web_tests/external/wpt/web-nfc/NFCReader.html new file mode 100644 index 0000000..5a0e884 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/web-nfc/NFCReader.html
@@ -0,0 +1,39 @@ +<!DOCTYPE html> +<meta charset=utf-8> +<title>Web NFC: NFCReader tests</title> +<link rel="author" title="Intel" href="http://www.intel.com"/> +<link rel="help" href="https://w3c.github.io/web-nfc/"/> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<div id="log"></div> + +<script> + +"use strict"; + +promise_test(async t => { + const reader = new NFCReader({url: "www.a.com"}); + const readerWatcher = new EventWatcher(t, reader, ["reading", "error"]); + reader.start(); + const event = await readerWatcher.wait_for("error"); + assert_equals(event.error.name, 'SyntaxError'); +}, 'Test that NFCReader.start fails if NFCReaderOptions.url is missing components.'); + +promise_test(async t => { + const reader = new NFCReader({url: "invalid"}); + const readerWatcher = new EventWatcher(t, reader, ["reading", "error"]); + reader.start(); + const event = await readerWatcher.wait_for("error"); + assert_equals(event.error.name, 'SyntaxError'); +}, 'Test that NFCReader.start fails if NFCReaderOptions.url is invalid.'); + +promise_test(async t => { + const reader = new NFCReader({url: "http://a.com"}); + const readerWatcher = new EventWatcher(t, reader, ["reading", "error"]); + reader.start(); + const event = await readerWatcher.wait_for("error"); + assert_equals(event.error.name, 'SyntaxError'); +}, 'Test that NFCReader.start fails if NFCReaderOptions.url has wrong protocol.'); + +</script>
diff --git a/third_party/blink/web_tests/external/wpt/web-nfc/NFCWriter_push.https-expected.txt b/third_party/blink/web_tests/external/wpt/web-nfc/NFCWriter_push.https-expected.txt new file mode 100644 index 0000000..78ff3bd --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/web-nfc/NFCWriter_push.https-expected.txt
@@ -0,0 +1,15 @@ +This is a testharness.js-based test. +FAIL Test that promise is rejected with TypeError if NDEFMessageSource is invalid. NFCWriter is not defined +FAIL 'Test that promise is rejected with SyntaxError if NDEFMessageSource contains invalid records. NFCWriter is not defined +FAIL NFCWriter.push should fail if the instance has already initiated NFC data transfer. NFCWriter is not defined +FAIL NFCWriter.push should fail if signal's aborted flag is set. NFCWriter is not defined +FAIL NFCWriter.push should fail with TypeError when invalid timeout is provided. NFCWriter is not defined +FAIL NFCWriter.push should fail with TypeError when invalid negative timeout value is provided. NFCWriter is not defined +FAIL NFCWriter.push should fail with TimeoutError when timer expires. NFCWriter is not defined +FAIL Reject promise with NotSupportedError if NFC message size exceeds 32KB. NFCWriter is not defined +FAIL Reject promise with SyntaxError if WebNFC Id cannot be created from provided URL. NFCWriter is not defined +FAIL Reject promise with SyntaxError if 'json' record cannot be serialized. NFCWriter is not defined +FAIL NFCWriter.push should fail with TypeError when invalid target value is provided. NFCWriter is not defined +FAIL Test that WebNFC API is not accessible from iframe context. promise_test: Unhandled rejection with value: undefined +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/web-nfc/nfc_push.https.html b/third_party/blink/web_tests/external/wpt/web-nfc/NFCWriter_push.https.html similarity index 63% rename from third_party/blink/web_tests/external/wpt/web-nfc/nfc_push.https.html rename to third_party/blink/web_tests/external/wpt/web-nfc/NFCWriter_push.https.html index c83217e12..f5a0a84 100644 --- a/third_party/blink/web_tests/external/wpt/web-nfc/nfc_push.https.html +++ b/third_party/blink/web_tests/external/wpt/web-nfc/NFCWriter_push.https.html
@@ -1,6 +1,6 @@ <!DOCTYPE html> <meta charset=utf-8> -<title>Web NFC: Test exceptions in nfc.push</title> +<title>Web NFC: Test exceptions in NFCWriter.push</title> <link rel="author" title="Intel" href="http://www.intel.com"/> <link rel="help" href="https://w3c.github.io/web-nfc/"/> <script src="/resources/testharness.js"></script> @@ -75,73 +75,89 @@ ]; promise_test(t => { - let promises = []; + const writer = new NFCWriter(); + const promises = []; invalid_type_messages.forEach(message => { promises.push( - promise_rejects(t, new TypeError(), navigator.nfc.push(message))); + promise_rejects(t, new TypeError(), writer.push(message))); }); return Promise.all(promises); -}, "Test that promise is rejected with TypeError if NDEFMessage is invalid."); +}, "Test that promise is rejected with TypeError if NDEFMessageSource is invalid."); promise_test(t => { - let promises = []; + const writer = new NFCWriter(); + const promises = []; invalid_syntax_messages.forEach(message => { promises.push( - promise_rejects(t, 'SyntaxError', navigator.nfc.push(message))); + promise_rejects(t, 'SyntaxError', writer.push(message))); }); return Promise.all(promises); -}, "'Test that promise is rejected with SyntaxError if NDEFMessage contains invalid records."); +}, "'Test that promise is rejected with SyntaxError if NDEFMessageSource contains invalid records."); promise_test(t => { - return promise_rejects(t, new TypeError(), navigator.nfc.push(test_text_data, { timeout: "invalid"})); -}, "nfc.push should fail with TypeError when invalid timeout is provided."); + const writer = new NFCWriter(); + const controller = new AbortController(); + const p = writer.push(test_text_data, { signal: controller.signal }); + controller.abort(); + return promise_rejects(t, 'NoModificationAllowedError', p); +}, "NFCWriter.push should fail if the instance has already initiated NFC data transfer."); promise_test(t => { - return promise_rejects(t, new TypeError(), navigator.nfc.push(test_text_data, { timeout: -1 })); -}, "nfc.push should fail with TypeError when invalid negative timeout value is provided."); + const writer = new NFCWriter(); + const controller = new AbortController(); + assert_false(controller.signal.aborted); + controller.abort(); + assert_true(controller.signal.aborted); + return promise_rejects(t, 'AbortError', writer.push(test_text_data, { signal: controller.signal })); +}, "NFCWriter.push should fail if signal's aborted flag is set."); promise_test(t => { - return promise_rejects(t, 'TimeoutError', navigator.nfc.push(test_text_data, { timeout: 1 })); -}, "nfc.push should fail with TimeoutError when timer expires."); + const writer = new NFCWriter(); + return promise_rejects(t, new TypeError(), writer.push(test_text_data, { timeout: "invalid"})); +}, "NFCWriter.push should fail with TypeError when invalid timeout is provided."); promise_test(t => { - let promise = navigator.nfc.push(test_text_data, { timeout: 100 }); - navigator.nfc.cancelPush(); - return promise_rejects(t, 'AbortError', promise); -}, "nfc.cancelPush should reject pending promise with AbortError."); + const writer = new NFCWriter(); + return promise_rejects(t, new TypeError(), writer.push(test_text_data, { timeout: -1 })); +}, "NFCWriter.push should fail with TypeError when invalid negative timeout value is provided."); promise_test(t => { - return promise_rejects(t, 'NotSupportedError', navigator.nfc.push(new ArrayBuffer(32 * 1024 + 1))); + const writer = new NFCWriter(); + return promise_rejects(t, 'TimeoutError', writer.push(test_text_data, { timeout: 1 })); +}, "NFCWriter.push should fail with TimeoutError when timer expires."); + +promise_test(t => { + const writer = new NFCWriter(); + return promise_rejects(t, 'NotSupportedError', writer.push(new ArrayBuffer(32 * 1024 + 1))); }, "Reject promise with NotSupportedError if NFC message size exceeds 32KB."); promise_test(t => { - let message = createMessage([createTextRecord(test_text_data)]); + const writer = new NFCWriter(); + const message = createMessage([createTextRecord(test_text_data)]); message.url = '%00/invalid/ path'; - return promise_rejects(t, 'SyntaxError', navigator.nfc.push(message)); + return promise_rejects(t, 'SyntaxError', writer.push(message)); }, "Reject promise with SyntaxError if WebNFC Id cannot be created from provided URL."); promise_test(t => { - let message = createMessage([createRecord('json','application/json', + const writer = new NFCWriter(); + const message = createMessage([createRecord('json','application/json', { get x(){ return this; } })]); - return promise_rejects(t, 'SyntaxError', navigator.nfc.push(message)); + return promise_rejects(t, 'SyntaxError', writer.push(message)); }, "Reject promise with SyntaxError if 'json' record cannot be serialized."); promise_test(t => { - return promise_rejects(t, new TypeError(), navigator.nfc.push(test_text_data, {target: "invalid"})); -}, "nfc.push should fail with TypeError when invalid target value is provided."); - -promise_test(t => { - return promise_rejects(t, new TypeError(), navigator.nfc.cancelPush("invalid")); -}, "nfc.cancelPush should fail with TypeError when invalid id value is provided."); + const writer = new NFCWriter(); + return promise_rejects(t, new TypeError(), writer.push(test_text_data, {target: "invalid"})); +}, "NFCWriter.push should fail with TypeError when invalid target value is provided."); promise_test(() => { return new Promise((resolve,reject) => { - let iframe = document.createElement('iframe'); + const iframe = document.createElement('iframe'); iframe.srcdoc = `<script> window.onmessage = message => { if (message.data === "Ready") { - let onSuccess = () => { parent.postMessage("Failure", "*"); }; - let onError = error => { + const onSuccess = () => { parent.postMessage("Failure", "*"); }; + const onError = error => { if (error.name == "SecurityError") { parent.postMessage("Success", "*"); } else { @@ -149,7 +165,8 @@ } }; try { - navigator.nfc.push("Test").then(onSuccess, onError); + const writer = new NFCWriter(); + writer.push("Test").then(onSuccess, onError); } catch(e) { parent.postMessage("Failure", "*"); }
diff --git a/third_party/blink/web_tests/external/wpt/web-nfc/nfc_watch.https.html b/third_party/blink/web_tests/external/wpt/web-nfc/nfc_watch.https.html deleted file mode 100644 index 455b643..0000000 --- a/third_party/blink/web_tests/external/wpt/web-nfc/nfc_watch.https.html +++ /dev/null
@@ -1,73 +0,0 @@ -<!DOCTYPE html> -<meta charset=utf-8> -<title>Web NFC: nfc.watch tests</title> -<link rel="author" title="Intel" href="http://www.intel.com"/> -<link rel="help" href="https://w3c.github.io/web-nfc/"/> -<script src="/resources/testharness.js"></script> -<script src="/resources/testharnessreport.js"></script> -<script src="resources/nfc_help.js"></script> - -<div id="log"></div> - -<script> - -"use strict"; - -promise_test(t => { - return promise_rejects(t, 'NotFoundError', navigator.nfc.cancelWatch(1)); -}, "Test that nfc.cancelWatch fails if invalid watch ID is provided."); - -promise_test(t => { - return promise_rejects(t, 'NotFoundError', navigator.nfc.cancelWatch()); -}, "Test that nfc.cancelWatch fails if there are no active watchers."); - -promise_test(t => { - return navigator.nfc.watch(noop).then(id => { - assert_equals(typeof(id), "number"); - assert_greater_than(id, 0, "greater than zero"); - }); -}, "Test that nfc watch success if NFC HW is enable."); - -promise_test(t => { - return navigator.nfc.watch(noop). - then(id => navigator.nfc.cancelWatch(id)); -}, "Test that nfc.cancelWatch succeeds if correct watch id is provided."); - -promise_test(t => { - return navigator.nfc.watch(noop).then(() => { - navigator.nfc.cancelWatch(); - }); -}, "Test that nfc.cancelWatch succeeds if there are active watchers."); - -promise_test(t => { - return promise_rejects(t, 'SyntaxError', navigator.nfc.watch(noop, {url:"www.a.com"})); -}, 'Test that nfc.watch fails if NFCWatchOptions.url is missing components.'); - -promise_test(t => { - return promise_rejects(t, 'SyntaxError', navigator.nfc.watch(noop, {url:"invalid"})); -}, 'Test that nfc.watch fails if NFCWatchOptions.url is invalid.'); - -promise_test(t => { - return promise_rejects(t, 'SyntaxError', navigator.nfc.watch(noop, {url:"http://a.com"})); -}, 'Test that nfc.watch fails if NFCWatchOptions.url has wrong protocol.'); - -promise_test(t => { - return navigator.nfc.watch(noop, {url:"https://a.com"}); -}, 'Test that nfc.watch succeeds if NFCWatchOptions.url is valid URL.'); - -promise_test(t => { - return navigator.nfc.watch(noop, {url:"https://a.com/*"}); -}, 'Test that nfc.watch succeeds if NFCWatchOptions.url is valid URL with "*"' + - ' wildcard character in path.'); - -promise_test(t => { - return navigator.nfc.watch(noop, {url:"https://a.com/*/bar"}); -}, 'Test that nfc.watch succeeds if NFCWatchOptions.url is valid URL with "*"' + - ' wildcard character in the beginning of path component followed by' + - ' subpath.'); - -promise_test(t => { - return navigator.nfc.watch(noop, {url:""}); -}, 'Test that nfc.watch succeeds if NFCWatchOptions.url is empty.'); - -</script>
diff --git a/third_party/blink/web_tests/fast/canvas/canvas-filter-origin-clean.html b/third_party/blink/web_tests/fast/canvas/canvas-filter-origin-clean.html index 90ecd27..3cbbf00 100644 --- a/third_party/blink/web_tests/fast/canvas/canvas-filter-origin-clean.html +++ b/third_party/blink/web_tests/fast/canvas/canvas-filter-origin-clean.html
@@ -2,7 +2,7 @@ <defs> <filter id="drop-shadow"> <feOffset dx="0" dy="10" result="offset" in="SourceAlpha"></feOffset> - <feFlood flood-color="rgba(0,0,0,1)"></feFlood> + <feFlood flood-color="currentcolor"></feFlood> <feComposite in2="offset" operator="in"></feComposite> <feMerge> <feMergeNode></feMergeNode> @@ -30,90 +30,85 @@ <script src="../../resources/testharnessreport.js"></script> <script> +function assert_not_tainted(performCommands, description) { + let ctx = document.createElement('canvas').getContext('2d'); + performCommands(ctx); + assert_not_equals(ctx.getImageData(0, 0, 1, 1), null, description); +} + +function assert_tainted(performCommands, description) { + let ctx = document.createElement('canvas').getContext('2d'); + performCommands(ctx); + assert_throws("SecurityError", () => ctx.getImageData(0, 0, 1, 1), description); +} + // CSS shorthand filters never taint the canvas. test(function() { - var canvas = document.createElement('canvas'); - var ctx = canvas.getContext('2d'); + assert_not_tainted(ctx => { ctx.fillStyle = '#0f0'; ctx.filter = 'brightness(0.5)'; ctx.fillRect(5, 5, 10, 10); - assert_not_equals(ctx.getImageData(0, 0, 1, 1), null); + }, 'brightness(0.5)'); - canvas = document.createElement('canvas'); - ctx = canvas.getContext('2d'); + assert_not_tainted(ctx => { ctx.filter = 'blur(5px)'; ctx.fillRect(5, 5, 10, 10); - assert_not_equals(ctx.getImageData(0, 0, 1, 1), null); + }, 'blur(5px)'); - canvas = document.createElement('canvas'); - ctx = canvas.getContext('2d'); + assert_not_tainted(ctx => { ctx.filter = 'hue-rotate(45deg) drop-shadow(16px 16px 20px blue)'; ctx.fillRect(5, 5, 10, 10); - assert_not_equals(ctx.getImageData(0, 0, 1, 1), null); + }, 'hue-rotate(45deg) drop-shadow(16px 16px 20px blue)'); }, "CSS shorthand filters never taint the canvas"); -// SVG reference filters taint the canvas, unless the filter DAG consists only -// of some combination of: -// 1. SourceGraphic -// 2. SourceAlpha -// 3. FillPaint -// 4. StrokePaint -// 5. feColorMatrix -// 6. feMerge +// SVG reference filters taint the canvas according to +// https://drafts.fxtf.org/filter-effects/#tainted-filter-primitives test(function() { - var canvas = document.createElement('canvas'); - var ctx = canvas.getContext('2d'); + assert_not_tainted(ctx => { ctx.filter = 'url(#merge-clean)'; ctx.fillRect(5, 5, 10, 10); - assert_not_equals(ctx.getImageData(0, 0, 1, 1), null); + }, 'url(#merge-clean)'); - canvas = document.createElement('canvas'); - ctx = canvas.getContext('2d'); + assert_not_tainted(ctx => { ctx.filter = 'blur(5px) url(#merge-clean) blur(5px)'; ctx.fillRect(5, 5, 10, 10); - assert_not_equals(ctx.getImageData(0, 0, 1, 1), null); + }, 'blur(5px) url(#merge-clean) blur(5px)'); }, "Whitelisted SVG filters don't taint the canvas"); test(function() { - var canvas = document.createElement('canvas'); - var ctx = canvas.getContext('2d'); + assert_tainted(ctx => { ctx.filter = 'url(#drop-shadow)'; ctx.fillRect(5, 5, 10, 10); - assert_throws("SecurityError", () => ctx.getImageData(0, 0, 1, 1)); + }, 'url(#drop-shadow)'); - canvas = document.createElement('canvas'); - ctx = canvas.getContext('2d'); + assert_tainted(ctx => { ctx.fillStyle = '#0f0'; ctx.filter = 'url(#drop-shadow) brightness(0.5) url(#merge-clean)'; ctx.fillRect(5, 5, 10, 10); - assert_throws("SecurityError", () => ctx.getImageData(0, 0, 1, 1)); + }, 'url(#drop-shadow) brightness(0.5) url(#merge-clean)'); - canvas = document.createElement('canvas'); - ctx = canvas.getContext('2d'); + assert_tainted(ctx => { ctx.fillStyle = '#0f0'; ctx.filter = 'brightness(0.5) url(#drop-shadow)'; ctx.fillRect(5, 5, 10, 10); - assert_throws("SecurityError", () => ctx.getImageData(0, 0, 1, 1)); + }, 'brightness(0.5) url(#drop-shadow)'); - canvas = document.createElement('canvas'); - ctx = canvas.getContext('2d'); + assert_tainted(ctx => { ctx.fillStyle = '#0f0'; ctx.filter = 'brightness(0.5) url(#drop-shadow) brightness(0.5)'; ctx.fillRect(5, 5, 10, 10); - assert_throws("SecurityError", () => ctx.getImageData(0, 0, 1, 1)); + }, 'brightness(0.5) url(#drop-shadow) brightness(0.5)'); - canvas = document.createElement('canvas'); - ctx = canvas.getContext('2d'); + assert_tainted(ctx => { ctx.fillStyle = '#0f0'; ctx.filter = 'brightness(0.5) url(#drop-shadow) brightness(0.5)'; ctx.fillRect(5, 5, 10, 10); - assert_throws("SecurityError", () => ctx.getImageData(0, 0, 1, 1)); + }, 'brightness(0.5) url(#drop-shadow) brightness(0.5)'); - canvas = document.createElement('canvas'); - ctx = canvas.getContext('2d'); + assert_tainted(ctx => { ctx.filter = 'url(#image)'; ctx.fillRect(5, 5, 10, 10); - assert_throws("SecurityError", () => ctx.getImageData(0, 0, 1, 1)); + }, 'url(#image)'); }, "Non-whitelisted SVG filters taint the canvas"); </script>
diff --git a/third_party/blink/web_tests/fast/forms/select/appearance-menulist-crash.html b/third_party/blink/web_tests/fast/forms/select/appearance-menulist-crash.html new file mode 100644 index 0000000..03f99d3 --- /dev/null +++ b/third_party/blink/web_tests/fast/forms/select/appearance-menulist-crash.html
@@ -0,0 +1,11 @@ +<!DOCTYPE html> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<div style="-webkit-appearance:menulist;"></div> +<div style="-webkit-appearance:menulist-button;"></div> +<script> +test(() => { + document.body.offsetBottom; +}, 'Check if menulist/menulist-button on neither SELECT nor INPUT does not crash'); +</script> +
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/paint/invalidation/filters/effect-reference-repaint-displacement-expected.txt b/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/paint/invalidation/filters/effect-reference-repaint-displacement-expected.txt index b49fe61..0870a05 100644 --- a/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/paint/invalidation/filters/effect-reference-repaint-displacement-expected.txt +++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=CompositeAfterPaint/paint/invalidation/filters/effect-reference-repaint-displacement-expected.txt
@@ -8,7 +8,7 @@ "paintInvalidations": [ { "object": "LayoutBlockFlow DIV class='box'", - "rect": [28, 20, 200, 200], + "rect": [8, 0, 240, 240], "reason": "background" } ]
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/editing/selection/4402375-expected.png b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/editing/selection/4402375-expected.png index b4f8160..1ce76b5 100644 --- a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/editing/selection/4402375-expected.png +++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/editing/selection/4402375-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/editing/selection/transformed-selection-rects-expected.png b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/editing/selection/transformed-selection-rects-expected.png index ddf66e8..1af763e4 100644 --- a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/editing/selection/transformed-selection-rects-expected.png +++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/editing/selection/transformed-selection-rects-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/http/tests/misc/slow-loading-image-in-pattern-expected.png b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/http/tests/misc/slow-loading-image-in-pattern-expected.png index 51c8d835..3326cfa 100644 --- a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/http/tests/misc/slow-loading-image-in-pattern-expected.png +++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/http/tests/misc/slow-loading-image-in-pattern-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-ltr-text-in-ltr-flow-with-markers-expected.png b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-ltr-text-in-ltr-flow-with-markers-expected.png index b6647d3d..c30ddb52 100644 --- a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-ltr-text-in-ltr-flow-with-markers-expected.png +++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-ltr-text-in-ltr-flow-with-markers-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-ltr-text-in-rtl-flow-with-markers-expected.png b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-ltr-text-in-rtl-flow-with-markers-expected.png index 2fe5c834..c7fc6b3 100644 --- a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-ltr-text-in-rtl-flow-with-markers-expected.png +++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-ltr-text-in-rtl-flow-with-markers-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-mixed-text-in-ltr-flow-with-markers-expected.png b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-mixed-text-in-ltr-flow-with-markers-expected.png index 7957b9f..241d68181 100644 --- a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-mixed-text-in-ltr-flow-with-markers-expected.png +++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-mixed-text-in-ltr-flow-with-markers-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-mixed-text-in-rtl-flow-with-markers-expected.png b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-mixed-text-in-rtl-flow-with-markers-expected.png index 8348db7ce..13749c5 100644 --- a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-mixed-text-in-rtl-flow-with-markers-expected.png +++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-mixed-text-in-rtl-flow-with-markers-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-rtl-text-in-ltr-flow-with-markers-expected.png b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-rtl-text-in-ltr-flow-with-markers-expected.png index 88ee146..d6d10fa 100644 --- a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-rtl-text-in-ltr-flow-with-markers-expected.png +++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-rtl-text-in-ltr-flow-with-markers-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-rtl-text-in-rtl-flow-with-markers-expected.png b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-rtl-text-in-rtl-flow-with-markers-expected.png index f69509a3..c0645ef1 100644 --- a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-rtl-text-in-rtl-flow-with-markers-expected.png +++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/markers/ellipsis-rtl-text-in-rtl-flow-with-markers-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/markers/inline_spelling_markers-expected.png b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/markers/inline_spelling_markers-expected.png index f4f20ef..2474efd73 100644 --- a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/markers/inline_spelling_markers-expected.png +++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/markers/inline_spelling_markers-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/markers/vertical-lr-expected.png b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/markers/vertical-lr-expected.png index e6172ed..00d3c1f 100644 --- a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/markers/vertical-lr-expected.png +++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/markers/vertical-lr-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/markers/vertical-rl-expected.png b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/markers/vertical-rl-expected.png index 0873496..57fe819 100644 --- a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/markers/vertical-rl-expected.png +++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/paint/markers/vertical-rl-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/svg/text/foreignObject-text-clipping-bug-expected.png b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/svg/text/foreignObject-text-clipping-bug-expected.png index 4a9abd2..c5ce752 100644 --- a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/svg/text/foreignObject-text-clipping-bug-expected.png +++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/svg/text/foreignObject-text-clipping-bug-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/svg/transforms/text-with-pattern-inside-transformed-html-expected.png b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/svg/transforms/text-with-pattern-inside-transformed-html-expected.png index 8eba742..5f81318 100644 --- a/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/svg/transforms/text-with-pattern-inside-transformed-html-expected.png +++ b/third_party/blink/web_tests/flag-specific/enable-blink-features=LayoutNG/svg/transforms/text-with-pattern-inside-transformed-html-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/paint/invalidation/filters/effect-reference-repaint-displacement-expected.txt b/third_party/blink/web_tests/paint/invalidation/filters/effect-reference-repaint-displacement-expected.txt index 38d460c8..4497b2d34a 100644 --- a/third_party/blink/web_tests/paint/invalidation/filters/effect-reference-repaint-displacement-expected.txt +++ b/third_party/blink/web_tests/paint/invalidation/filters/effect-reference-repaint-displacement-expected.txt
@@ -19,7 +19,7 @@ "paintInvalidations": [ { "object": "LayoutBlockFlow DIV class='box'", - "rect": [28, 20, 200, 200], + "rect": [8, 0, 240, 240], "reason": "background" } ]
diff --git a/third_party/blink/web_tests/platform/linux/external/wpt/html/browsers/windows/embedded-opener-remove-frame-expected.txt b/third_party/blink/web_tests/platform/linux/external/wpt/html/browsers/windows/embedded-opener-remove-frame-expected.txt new file mode 100644 index 0000000..1d304732 --- /dev/null +++ b/third_party/blink/web_tests/platform/linux/external/wpt/html/browsers/windows/embedded-opener-remove-frame-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +FAIL opener of discarded nested browsing context openerGet is not a function +FAIL opener of discarded auxiliary browsing context openerGet is not a function +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/html/browsers/windows/embedded-opener-remove-frame-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/html/browsers/windows/embedded-opener-remove-frame-expected.txt new file mode 100644 index 0000000..1d304732 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac/external/wpt/html/browsers/windows/embedded-opener-remove-frame-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +FAIL opener of discarded nested browsing context openerGet is not a function +FAIL opener of discarded auxiliary browsing context openerGet is not a function +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/platform/win7/external/wpt/html/browsers/windows/embedded-opener-remove-frame-expected.txt b/third_party/blink/web_tests/platform/win7/external/wpt/html/browsers/windows/embedded-opener-remove-frame-expected.txt new file mode 100644 index 0000000..1d304732 --- /dev/null +++ b/third_party/blink/web_tests/platform/win7/external/wpt/html/browsers/windows/embedded-opener-remove-frame-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +FAIL opener of discarded nested browsing context openerGet is not a function +FAIL opener of discarded auxiliary browsing context openerGet is not a function +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/svg/filters/feDisplacementMap-filterUnits-expected.png b/third_party/blink/web_tests/svg/filters/feDisplacementMap-filterUnits-expected.png deleted file mode 100644 index b57137cd..0000000 --- a/third_party/blink/web_tests/svg/filters/feDisplacementMap-filterUnits-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/svg/filters/feDisplacementMap-filterUnits-expected.svg b/third_party/blink/web_tests/svg/filters/feDisplacementMap-filterUnits-expected.svg new file mode 100644 index 0000000..13fad3c --- /dev/null +++ b/third_party/blink/web_tests/svg/filters/feDisplacementMap-filterUnits-expected.svg
@@ -0,0 +1,9 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="500" height="300"> + <rect fill="rgb(50%,50%,50%)" stroke="green" x="20" y="20" width="75" height="75"/> + <rect fill="rgb(50%,50%,50%)" stroke="green" x="186" y="20" width="54" height="75"/> + <rect fill="rgb(50%,50%,50%)" stroke="green" x="304" y="64" width="56" height="56"/> + + <rect fill="rgb(50%,50%,50%)" stroke="green" x="44" y="164" width="76" height="76"/> + <rect fill="rgb(50%,50%,50%)" stroke="green" x="140" y="140" width="75" height="75"/> + <rect fill="rgb(50%,50%,50%)" stroke="green" x="287" y="167" width="73" height="73"/> +</svg>
diff --git a/third_party/blink/web_tests/svg/filters/feDisplacementMap-negative-scale-expected.html b/third_party/blink/web_tests/svg/filters/feDisplacementMap-negative-scale-expected.html index c4536f2..f718ea6 100644 --- a/third_party/blink/web_tests/svg/filters/feDisplacementMap-negative-scale-expected.html +++ b/third_party/blink/web_tests/svg/filters/feDisplacementMap-negative-scale-expected.html
@@ -1,2 +1,2 @@ <!DOCTYPE html> -<div style="position: relative; left: 20px; top: 20px; width: 100px; height: 100px; background-color: green"></div> +<div style="width: 100px; height: 100px; background-color: green"></div>
diff --git a/third_party/blink/web_tests/virtual/disable-blink-gen-property-trees/animations/README.txt b/third_party/blink/web_tests/virtual/disable-blink-gen-property-trees/animations/README.txt new file mode 100644 index 0000000..b67b879 --- /dev/null +++ b/third_party/blink/web_tests/virtual/disable-blink-gen-property-trees/animations/README.txt
@@ -0,0 +1,2 @@ +# This suite runs tests with --disable-blink-features=BlinkGenPropertyTrees +# --enable-threaded-compositing and --disable-composited-antialiasing.
diff --git a/third_party/blink/web_tests/virtual/disable-blink-gen-property-trees/animations/rotate-transform-equivalent-expected.png b/third_party/blink/web_tests/virtual/disable-blink-gen-property-trees/animations/rotate-transform-equivalent-expected.png new file mode 100644 index 0000000..95695bb --- /dev/null +++ b/third_party/blink/web_tests/virtual/disable-blink-gen-property-trees/animations/rotate-transform-equivalent-expected.png Binary files differ
diff --git a/third_party/closure_compiler/externs/bookmark_manager_private.js b/third_party/closure_compiler/externs/bookmark_manager_private.js index cd0a6da..eb74345 100644 --- a/third_party/closure_compiler/externs/bookmark_manager_private.js +++ b/third_party/closure_compiler/externs/bookmark_manager_private.js
@@ -11,7 +11,6 @@ // IMPORTANT NOTE: Work-around for crbug.com/543822 // s/chrome.bookmarkManagerPrivate.bookmarks.BookmarkTreeNode/BookmarkTreeNode/ -// s/chrome.bookmarkManagerPrivate.bookmarks.CreateDetails/chrome.bookmarks.CreateDetails/ /** @fileoverview Externs generated from namespace: bookmarkManagerPrivate */ @@ -41,12 +40,6 @@ chrome.bookmarkManagerPrivate.BookmarkNodeData; /** - * Collection of meta info fields. - * @typedef {Object} - */ -chrome.bookmarkManagerPrivate.MetaInfoFields; - -/** * Copies the given bookmarks into the clipboard. * @param {!Array<string>} idList An array of string-valued ids * @param {function():void=} callback @@ -71,13 +64,6 @@ chrome.bookmarkManagerPrivate.paste = function(parentId, selectedIdList, callback) {}; /** - * Whether there are any bookmarks that can be pasted. - * @param {string} parentId The ID of the folder to paste into. - * @param {function(boolean):void} callback - */ -chrome.bookmarkManagerPrivate.canPaste = function(parentId, callback) {}; - -/** * Sorts the children of a given folder. * @param {string} parentId The ID of the folder to sort the children of. */ @@ -113,12 +99,6 @@ chrome.bookmarkManagerPrivate.getSubtree = function(id, foldersOnly, callback) {}; /** - * Whether bookmarks can be modified. - * @param {function(boolean):void} callback - */ -chrome.bookmarkManagerPrivate.canEdit = function(callback) {}; - -/** * Recursively removes list of bookmarks nodes. * @param {!Array<string>} idList An array of string-valued ids. * @param {function():void=} callback @@ -126,48 +106,6 @@ chrome.bookmarkManagerPrivate.removeTrees = function(idList, callback) {}; /** - */ -chrome.bookmarkManagerPrivate.recordLaunch = function() {}; - -/** - * Mimics the functionality of bookmarks.create, but will additionally set the - * given meta info fields. - * @param {!chrome.bookmarks.CreateDetails} bookmark - * @param {!chrome.bookmarkManagerPrivate.MetaInfoFields} metaInfo - * @param {function(!BookmarkTreeNode):void=} - * callback - */ -chrome.bookmarkManagerPrivate.createWithMetaInfo = function(bookmark, metaInfo, callback) {}; - -/** - * Gets meta info from a bookmark node. - * @param {string=} id The id of the bookmark to retrieve meta info from. If - * omitted meta info for all nodes is returned. - * @param {string=} key The key for the meta info to retrieve. If omitted, all - * fields are returned. - * @param {function(((string|Object)|undefined)):void=} callback - */ -chrome.bookmarkManagerPrivate.getMetaInfo = function(id, key, callback) {}; - -/** - * Sets a meta info value for a bookmark node. - * @param {string} id The id of the bookmark node to set the meta info on. - * @param {string} key The key of the meta info to set. - * @param {string} value The meta info to set. - * @param {function():void=} callback - */ -chrome.bookmarkManagerPrivate.setMetaInfo = function(id, key, value, callback) {}; - -/** - * Updates a set of meta info values for a bookmark node. - * @param {string} id The id of the bookmark node to update the meta info of. - * @param {!chrome.bookmarkManagerPrivate.MetaInfoFields} metaInfoChanges A set - * of meta info key/value pairs to update. - * @param {function():void=} callback - */ -chrome.bookmarkManagerPrivate.updateMetaInfo = function(id, metaInfoChanges, callback) {}; - -/** * Performs an undo of the last change to the bookmark model. */ chrome.bookmarkManagerPrivate.undo = function() {}; @@ -178,24 +116,6 @@ chrome.bookmarkManagerPrivate.redo = function() {}; /** - * Gets the information for the undo if available. - * @param {function({ - * enabled: boolean, - * label: string - * }):void} callback - */ -chrome.bookmarkManagerPrivate.getUndoInfo = function(callback) {}; - -/** - * Gets the information for the redo if available. - * @param {function({ - * enabled: boolean, - * label: string - * }):void} callback - */ -chrome.bookmarkManagerPrivate.getRedoInfo = function(callback) {}; - -/** * Fired when dragging bookmarks over the document. * @type {!ChromeEvent} */ @@ -212,9 +132,3 @@ * @type {!ChromeEvent} */ chrome.bookmarkManagerPrivate.onDrop; - -/** - * Fired when the meta info of a node changes. - * @type {!ChromeEvent} - */ -chrome.bookmarkManagerPrivate.onMetaInfoChanged;
diff --git a/third_party/flatbuffers/flatbuffer.gni b/third_party/flatbuffers/flatbuffer.gni index 11aae5ed..38ee2609 100644 --- a/third_party/flatbuffers/flatbuffer.gni +++ b/third_party/flatbuffers/flatbuffer.gni
@@ -128,10 +128,8 @@ public_deps = [ # The generated headers reference headers within FlatBuffers, so # dependencies must be able to find those headers too. - "//third_party/flatbuffers", - ] - deps = [ ":$action_name", + "//third_party/flatbuffers", ] # This will link any libraries in the deps (the use of invoker.deps in the
diff --git a/third_party/protobuf/BUILD.gn b/third_party/protobuf/BUILD.gn index 8e02f217..84ce0a6c 100644 --- a/third_party/protobuf/BUILD.gn +++ b/third_party/protobuf/BUILD.gn
@@ -222,6 +222,10 @@ # The SQLite fuzzer's corpus generator needs protobuf_full and is not # included in Chrome. "//third_party/sqlite:sqlite3_lpm_corpus_gen", + + # Some tests inside ChromeOS need reflection to parse golden files. + # Not included in production code. + "//chrome/browser/chromeos:time_limit_tests", ] sources = protobuf_lite_sources + [
diff --git a/tools/android/native_lib_memory/extract_resident_pages.py b/tools/android/native_lib_memory/extract_resident_pages.py new file mode 100755 index 0000000..ce04733 --- /dev/null +++ b/tools/android/native_lib_memory/extract_resident_pages.py
@@ -0,0 +1,131 @@ +#!/usr/bin/python +# +# Copyright 2019 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Generates Json file for native library's resident pages.""" + +import argparse +import json +import logging +import os +import sys + + +_SRC_PATH = os.path.abspath(os.path.join( + os.path.dirname(__file__), os.pardir, os.pardir, os.pardir)) +sys.path.insert(0, os.path.join(_SRC_PATH, 'third_party', 'catapult', 'devil')) +from devil.android import device_utils +from devil.android import device_errors + + +def _CreateArgumentParser(): + parser = argparse.ArgumentParser( + description='Create JSON file for residency pages') + parser.add_argument('--device-serial', type=str, required=True) + parser.add_argument('--on-device-file-path', type=str, + help='Path to residency.txt', required=True) + parser.add_argument('--output-directory', type=str, help='Output directory', + required=False) + return parser + + +def _ReadFileFromDevice(device_serial, file_path): + """Reads the file from the device, and returns its content. + + Args: + device_serial: (str) Device identifier + file_path: (str) On-device path to the residency file. + + Returns: + (str or None) The file content. + """ + content = None + try: + device = device_utils.DeviceUtils(device_serial) + content = device.ReadFile(file_path, True) + except device_errors.CommandFailedError: + logging.exception( + 'Possible failure reaching the device or reading the file') + + return content + + +def ParseResidentPages(resident_pages): + """Parses and converts the residency data into a list where + the index corresponds to the page number and the value 1 if resident + and 0 otherwise. + + |resident_pages| contains a string of resident pages: + 0 + 1 + ... + ... + N + + Args: + resident_pages: (str) As returned by ReadFileFromDevice() + + Returns: + (list) Pages list. + """ + pages_list = [] + expected = 0 + for page in resident_pages.splitlines(): + while expected < int(page): + pages_list.append(0) + expected += 1 + + pages_list.append(1) + expected += 1; + return pages_list + + +def _GetResidentPagesJSON(pages_list): + """Transforms the pages list to JSON object. + + Args: + pages_list: (list) As returned by ParseResidentPages() + + Returns: + (JSON object) Pages JSON object. + """ + json_data = [] + for i in range(len(pages_list)): + json_data.append({'page_num': i, 'resident': pages_list[i]}) + return json_data + + +def _WriteJSONToFile(json_data, output_file_path): + """Dumps JSON data to file. + + Args: + json_data: (JSON object) Data to be dumped in the file. + output_file_path: (str) Output file path + """ + with open(output_file_path, 'w') as f: + json.dump(json_data, f) + + +def main(): + parser = _CreateArgumentParser() + args = parser.parse_args() + logging.basicConfig(level=logging.INFO) + + content = _ReadFileFromDevice(args.device_serial, + args.on_device_file_path) + if not content: + logging.error('Error reading file from device') + return 1 + + pages_list = ParseResidentPages(content) + pages_json = _GetResidentPagesJSON(pages_list) + _WriteJSONToFile(pages_json, os.path.join(args.output_directory, + 'residency.json')) + + return 0 + + +if __name__ == '__main__': + sys.exit(main())
diff --git a/tools/android/native_lib_memory/extract_resident_pages_unittest.py b/tools/android/native_lib_memory/extract_resident_pages_unittest.py new file mode 100755 index 0000000..3c8a73a --- /dev/null +++ b/tools/android/native_lib_memory/extract_resident_pages_unittest.py
@@ -0,0 +1,39 @@ +#!/usr/bin/env python +# Copyright 2019 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Unit test for extracting resident pages.""" + +import random +import unittest + +import extract_resident_pages + +class ExtractResidentPagesUnittest(unittest.TestCase): + + def testParseResidentPages(self): + max_pages = 10600 + pages = [] + resident_pages = "" + + for i in range(max_pages): + is_resident = random.randint(0,1) + pages.append(is_resident) + if is_resident: + resident_pages += str(i) + '\n' + + pages_list = extract_resident_pages.ParseResidentPages(resident_pages) + + for i in range(len(pages_list)): + self.assertEqual(pages[i], pages_list[i]) + + # As ParseResidentPages is only aware of the maximum page number that is + # resident, check that all others are not resident. + for i in range(len(pages_list), len(pages)): + self.assertFalse(pages[i]) + + +if __name__ == '__main__': + + unittest.main()
diff --git a/tools/android/native_lib_memory/extract_symbols.py b/tools/android/native_lib_memory/extract_symbols.py index 60513665..a0bb2772 100755 --- a/tools/android/native_lib_memory/extract_symbols.py +++ b/tools/android/native_lib_memory/extract_symbols.py
@@ -224,8 +224,8 @@ 'by tools/cygprofile/process_profiles.py', required=False) parser.add_argument('--residency', type=str, - help='Path to a JSON file with residency data, as written' - ' by process_resdency.py', required=False) + help='Path to JSON file with residency pages, as written' + ' by extract_resident_pages.py', required=False) parser.add_argument('--build-directory', type=str, help='Build directory', required=True) parser.add_argument('--output-directory', type=str, help='Output directory', @@ -254,9 +254,12 @@ offset = 0 if args.residency: - with open(args.residency) as f: - residency = json.load(f) - offset = residency['offset'] + if not os.path.exists(args.residency): + logging.error('Residency file not found') + return 1 + residency_path = os.path.join(args.output_directory, 'residency.json') + if residency_path != args.residency: + shutil.copy(args.residency, residency_path) logging.info('Extracting symbols from %s', native_lib_filename) native_lib_symbols = symbol_extractor.SymbolInfosFromBinary( @@ -283,9 +286,6 @@ directory = os.path.dirname(__file__) for filename in ['visualize.html', 'visualize.js', 'visualize.css']: - if args.residency: - shutil.copy(args.residency, - os.path.join(args.output_directory, 'residency.json')) shutil.copy(os.path.join(directory, filename), os.path.join(args.output_directory, filename))
diff --git a/tools/android/native_lib_memory/visualize.js b/tools/android/native_lib_memory/visualize.js index 67ea517..53a22e61 100644 --- a/tools/android/native_lib_memory/visualize.js +++ b/tools/android/native_lib_memory/visualize.js
@@ -223,7 +223,10 @@ function createGraph(codePages, reachedPerPage, residency) { const PAGE_SIZE = 4096; + // Offset is relative to the start of libmonochrome.so not to .text + // All offsets are aligned down to page size. let offsets = codePages.map((x) => x.offset).sort((a, b) => a - b); + // |minOffset| is equal to start of text aligned down to page size. let minOffset = +offsets[0]; let maxOffset = +offsets[offsets.length - 1] + PAGE_SIZE; let startEndOfOrderedText = getStartAndEndOfOrderedText(codePages); @@ -239,15 +242,20 @@ } if (residency) { - let timestamps = Object.keys( - residency).map((x) => +x).sort((a, b) => a - b); - let lastTimestamp = +timestamps[timestamps.length - 1]; - let residencyData = residency[lastTimestamp]; - // Other offsets are relative to start of the native library. - let typedResidencyData = residencyData.map( + let typedResidencyData = residency.map( (page) => ( - {"type": RESIDENCY, "data": {"offset": page.offset + minOffset, + {"type": RESIDENCY, "data": {"offset": page.page_num * PAGE_SIZE + + minOffset, "resident": page.resident}})); + nextResidencyOffset + = (residency[residency.length - 1].page_num + 1) * PAGE_SIZE + + minOffset; + + for(let i = nextResidencyOffset; i < maxOffset; i+=PAGE_SIZE) { + typedResidencyData.push( + {"type": RESIDENCY, "data": {"offset": i, "resident": 0}}); + } + flatData = flatData.concat(typedResidencyData); }
diff --git a/tools/clang/scripts/clang_tidy_tool.py b/tools/clang/scripts/clang_tidy_tool.py new file mode 100755 index 0000000..b12e77b --- /dev/null +++ b/tools/clang/scripts/clang_tidy_tool.py
@@ -0,0 +1,186 @@ +#!/usr/bin/env python +# Copyright 2019 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +r"""Automatically fetch, build, and run clang-tidy from source. + +This script seeks to automate the steps detailed in docs/clang_tidy.md. + +Example: the following command disables clang-tidy's default checks (-*) and +enables the clang static analyzer checks. + + tools/clang/scripts/clang_tidy_tool.py \\ + --checks='-*,clang-analyzer-*,-clang-analyzer-alpha*' \\ + --header-filter='.*' \\ + out/Release chrome +""" + +import argparse +import os +import subprocess +import sys + + +def GetCheckoutDir(out_dir): + """Returns absolute path to the checked-out llvm repo.""" + return os.path.join(out_dir, 'tools', 'clang', 'third_party', 'llvm') + + +def GetBuildDir(out_dir): + return os.path.join(GetCheckoutDir(out_dir), 'build') + + +def FetchClang(out_dir): + """Clone llvm repo into |out_dir| or update if it already exists.""" + checkout_dir = GetCheckoutDir(out_dir) + + try: + # Create parent directories of the checkout directory + os.makedirs(os.path.dirname(checkout_dir)) + except OSError: + pass + + try: + # First, try to clone the repo. + args = [ + 'git', + 'clone', + 'https://github.com/llvm/llvm-project.git', + checkout_dir, + ] + subprocess.check_call(args, shell=sys.platform == 'win32') + except subprocess.CalledProcessError: + # Otherwise, try to update it. + print('-- Attempting to update existing repo') + args = ['git', 'pull', '--rebase', 'origin', 'master'] + subprocess.check_call(args, cwd=checkout_dir) + + +def BuildClang(out_dir): + """Build clang from llvm repo at |GetCheckoutDir(out_dir)|.""" + # Make <checkout>/build directory + build_dir = GetBuildDir(out_dir) + try: + os.mkdir(build_dir) + except OSError as e: + # Ignore errno 17 'File Exists' + if e.errno != 17: + raise e + + # From that dir, run cmake + cmake_args = [ + 'cmake', + '-GNinja', + '-DLLVM_ENABLE_PROJECTS=clang;clang-tools-extra', + '-DCMAKE_BUILD_TYPE=Release', + '../llvm', + ] + subprocess.check_call(cmake_args, cwd=build_dir) + + ninja_args = [ + 'ninja', + 'clang-tidy', + 'clang-apply-replacements', + ] + subprocess.check_call(ninja_args, cwd=build_dir) + + +def BuildNinjaTarget(out_dir, ninja_target): + args = ['ninja', '-C', out_dir, ninja_target] + subprocess.check_call(args) + + +def GenerateCompDb(out_dir): + gen_compdb_script = os.path.join( + os.path.dirname(__file__), 'generate_compdb.py') + comp_db_file = os.path.join(out_dir, 'compile_commands.json') + args = [gen_compdb_script, '-p', out_dir, '-o', comp_db_file] + subprocess.check_call(args) + + +def RunClangTidy(checks, header_filter, auto_fix, out_dir, ninja_target): + """Invoke the |clang-tidy| binary.""" + run_clang_tidy_script = os.path.join( + GetCheckoutDir(out_dir), 'clang-tools-extra', 'clang-tidy', 'tool', + 'run-clang-tidy.py') + + clang_tidy_binary = os.path.join(GetBuildDir(out_dir), 'bin', 'clang-tidy') + clang_apply_rep_binary = os.path.join( + GetBuildDir(out_dir), 'bin', 'clang-apply-replacements') + + args = [ + run_clang_tidy_script, + '-quiet', + '-p', + out_dir, + '-clang-tidy-binary', + clang_tidy_binary, + '-clang-apply-replacements-binary', + clang_apply_rep_binary, + ] + + if checks: + args.append('-checks={}'.format(checks)) + + if header_filter: + args.append('-header-filter={}'.format(header_filter)) + + if auto_fix: + args.append('-fix') + + args.append(ninja_target) + subprocess.check_call(args) + + +def main(): + script_name = sys.argv[0] + + parser = argparse.ArgumentParser( + formatter_class=argparse.RawDescriptionHelpFormatter, epilog=__doc__) + parser.add_argument( + '--fetch', action='store_true', help='Fetch and build clang sources') + parser.add_argument( + '--build', + action='store_true', + help='build clang sources to get clang-tidy') + parser.add_argument('--checks', help='passed to clang-tidy') + parser.add_argument('--header-filter', help='passed to clang-tidy') + parser.add_argument( + '--auto-fix', + action='store_true', + help='tell clang-tidy to auto-fix errors') + parser.add_argument('OUT_DIR', help='where we are building Chrome') + parser.add_argument('NINJA_TARGET', help='ninja target') + args = parser.parse_args() + + steps = [] + + if args.fetch: + steps.append(('Fetching clang sources', lambda: FetchClang(args.OUT_DIR))) + + if args.build: + steps.append(('Building clang', lambda: BuildClang(args.OUT_DIR))) + + steps += [ + ('Building ninja target: %s' % args.NINJA_TARGET, + lambda: BuildNinjaTarget(args.OUT_DIR, args.NINJA_TARGET)), + ('Generating compilation DB', lambda: GenerateCompDb(args.OUT_DIR)), + ('Running clang-tidy', + lambda: RunClangTidy(args.checks, args.header_filter, args.auto_fix, args + .OUT_DIR, args.NINJA_TARGET)), + ] + + # Run the steps in sequence. + for i, (msg, step_func) in enumerate(steps): + # Print progress message + print '-- %s %s' % (script_name, '-' * (80 - len(script_name) - 4)) + print '-- [%d/%d] %s' % (i + 1, len(steps), msg) + print 80 * '-' + + step_func() + + return 0 + + +if __name__ == '__main__': + sys.exit(main())
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index c9ac4a07..e4048c91 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -21792,6 +21792,8 @@ <int value="2821" label="CSSValueAppearanceTextarea"/> <int value="2822" label="CSSValueAppearanceTextFieldForOthersRendered"/> <int value="2823" label="CSSValueAppearanceTextFieldForTemporalRendered"/> + <int value="2824" label="BuiltInModuleKvStorage"/> + <int value="2825" label="BuiltInModuleVirtualScroller"/> </enum> <enum name="FeaturePolicyFeature"> @@ -46207,7 +46209,7 @@ <int value="8" label="FileThread"/> <int value="9" label="DatabaseThread"/> <int value="10" label="WebAudioThread"/> - <int value="11" label="ScriptStreamerThread"/> + <int value="11" label="ScriptStreamerThread (obsolete)"/> <int value="12" label="OfflineAudioRenderThread"/> <int value="13" label="ReverbConvolutionBackgroundThread"/> <int value="14" label="HRTFDatabaseLoaderThread"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 08418ebf..05ea8200 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -2974,7 +2974,7 @@ <histogram name="Android.TabNavigationInterceptResult" enum="NavigationInterceptResult"> - <owner>thildebr@chromium.org</owner> + <owner>tedchoc@chromium.org</owner> <summary> The distribution of results when running ExternalNavigationHandler, this shows how often we send intents to be handled by other applications. @@ -81399,7 +81399,8 @@ <histogram name="PartnerBookmark.FaviconThrottleFetchResult" enum="PartnerBookmark.FaviconFetchResult"> - <owner>thildebr@chromium.org</owner> + <owner>tedchoc@chromium.org</owner> + <owner>wychen@chromium.org</owner> <summary> The response we got back from our favicon fetching throttler, once for each bookmark at each cold start. Only recorded on Android. @@ -81463,7 +81464,8 @@ </histogram> <histogram name="PartnerBookmarksFaviconThrottle.NumEntries" units="entries"> - <owner>thildebr@chromium.org</owner> + <owner>tedchoc@chromium.org</owner> + <owner>wychen@chromium.org</owner> <summary> Number of elements read from the partner bookmarks favicon cache, recorded once per cold start when reading partner bookmarks. Only recorded on
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml index 5e91144..d1e3be0 100644 --- a/tools/metrics/ukm/ukm.xml +++ b/tools/metrics/ukm/ukm.xml
@@ -136,6 +136,39 @@ site-wide framework and not a reader experience. </summary> </metric> + <metric name="SubFrame.InteractiveTiming.FirstInputDelay3"> + <summary> + Measures First Input Delay, the duration between the hardware timestamp + and the start of event processing on the main thread for the first + meaningful input per navigation, in the AMP subframe. See + https://goo.gl/tr1oTZ for a detailed explanation. In milliseconds. + </summary> + </metric> + <metric name="SubFrame.MainFrameToSubFrameNavigationDelta"> + <summary> + Measures the time in milliseconds from the navigation in the main frame to + the navigation in the AMP subframe. Will be negative in cases where the + AMP subframe was prerendered. Will be positive in cases where the main + frame was a non-same-document navigation. Should be near-zero when the + main frame navigation is a same-document navigation and the AMP subframe + was not prerendered. + </summary> + </metric> + <metric name="SubFrame.PaintTiming.NavigationToFirstContentfulPaint"> + <summary> + Measures the time in milliseconds from navigation timing's navigation + start to the time when the page first paints content, in the AMP subframe. + A contentful paint includes a paint of text, image, SVG, or canvas. + </summary> + </metric> + <metric name="SubFrame.PaintTiming.NavigationToLargestContentPaint"> + <summary> + Measures the time in milliseconds from navigation timing's navigation + start to the time when the page first paints the largest content (text or + image) within viewport, in the AMP subframe. See + http://bit.ly/largest_contentful_paint_explainer for more details. + </summary> + </metric> <metric name="SubFrameAmpPageLoad"> <summary> True if the page loaded in any subframe is an AMP document (has an amp
diff --git a/tools/perf/benchmark.csv b/tools/perf/benchmark.csv index f6463a0..827e2b3 100644 --- a/tools/perf/benchmark.csv +++ b/tools/perf/benchmark.csv
@@ -30,8 +30,6 @@ media.mobile,dalecurtis@chromium.org,Internals>Media,,"aac,audio_only,audio_video,background,beginning_to_end,busyjs,cns,h264,mp3,mse,opus,pcm,seek,src,video_only,vorbis,vp9" media_perftests,"crouleau@chromium.org, dalecurtis@chromium.org",Internals>Media,, memory.desktop,erikchen@chromium.org,,, -memory.long_running_idle_gmail_background_tbmv2,ulan@chromium.org,,, -memory.long_running_idle_gmail_tbmv2,ulan@chromium.org,,, memory.top_10_mobile,perezju@chromium.org,,, net_perftests,xunjieli@chromium.org,,, octane,hablich@chromium.org,Blink>JavaScript,,
diff --git a/tools/perf/benchmarks/memory.py b/tools/perf/benchmarks/memory.py index c4af48d..e254596 100644 --- a/tools/perf/benchmarks/memory.py +++ b/tools/perf/benchmarks/memory.py
@@ -119,62 +119,3 @@ @classmethod def ShouldAddValue(cls, name, _): return DefaultShouldAddValueForMemoryMeasurement(name) - - -class _MemoryV8Benchmark(_MemoryInfra): - - # Report only V8-specific and overall renderer memory values. Note that - # detailed values reported by the OS (such as native heap) are excluded. - _V8_AND_OVERALL_MEMORY_RE = re.compile( - r'renderer_processes:' - r'(reported_by_chrome:v8|reported_by_os:system_memory:[^:]+$)') - - def CreateCoreTimelineBasedMeasurementOptions(self): - v8_categories = [ - 'blink.console', 'renderer.scheduler', 'v8', 'webkit.console'] - memory_categories = ['blink.console', 'disabled-by-default-memory-infra'] - category_filter = chrome_trace_category_filter.ChromeTraceCategoryFilter( - ','.join(['-*'] + v8_categories + memory_categories)) - options = timeline_based_measurement.Options(category_filter) - options.SetTimelineBasedMetrics(['v8AndMemoryMetrics']) - # Setting an empty memory dump config disables periodic dumps. - options.config.chrome_trace_config.SetMemoryDumpConfig( - chrome_trace_config.MemoryDumpConfig()) - return options - - @classmethod - def ShouldAddValue(cls, name, _): - if 'memory:chrome' in name: - # TODO(petrcermak): Remove the first two cases once - # https://codereview.chromium.org/2018503002/ lands in Catapult and rolls - # into Chromium. - return ('renderer:subsystem:v8' in name or - 'renderer:vmstats:overall' in name or - bool(cls._V8_AND_OVERALL_MEMORY_RE.search(name))) - return 'v8' in name - - -@benchmark.Info(emails=['ulan@chromium.org']) -class MemoryLongRunningIdleGmail(_MemoryV8Benchmark): - """Use (recorded) real world web sites and measure memory consumption - of long running idle Gmail page """ - page_set = page_sets.LongRunningIdleGmailPageSet - - @classmethod - def Name(cls): - return 'memory.long_running_idle_gmail_tbmv2' - - -@benchmark.Info(emails=['ulan@chromium.org']) -class MemoryLongRunningIdleGmailBackground(_MemoryV8Benchmark): - """Use (recorded) real world web sites and measure memory consumption - of long running idle Gmail page """ - page_set = page_sets.LongRunningIdleGmailBackgroundPageSet - SUPPORTED_PLATFORMS = [ - story.expectations.ANDROID_NOT_WEBVIEW, # Requires tabs. - story.expectations.ALL_DESKTOP - ] - - @classmethod - def Name(cls): - return 'memory.long_running_idle_gmail_background_tbmv2'
diff --git a/tools/perf/core/cli_helpers_unittest.py b/tools/perf/core/cli_helpers_unittest.py index 61a041fb..e8f3754 100644 --- a/tools/perf/core/cli_helpers_unittest.py +++ b/tools/perf/core/cli_helpers_unittest.py
@@ -11,36 +11,44 @@ from telemetry import decorators -# https://crbug.com/938487 -@decorators.Disabled('all') class CLIHelpersTest(unittest.TestCase): def testUnsupportedColor(self): with self.assertRaises(AssertionError): cli_helpers.Colored('message', 'pink') @mock.patch('__builtin__.print') + # https://crbug.com/938487 + @decorators.Disabled('all') def testPrintsInfo(self, print_mock): cli_helpers.Info('foo {sval} {ival}', sval='s', ival=42) print_mock.assert_called_once_with('foo s 42') @mock.patch('__builtin__.print') + # https://crbug.com/938487 + @decorators.Disabled('all') def testPrintsComment(self, print_mock): cli_helpers.Comment('foo') print_mock.assert_called_once_with('\033[93mfoo\033[0m') @mock.patch('__builtin__.print') @mock.patch('sys.exit') + # https://crbug.com/938487 + @decorators.Disabled('all') def testFatal(self, sys_exit_mock, print_mock): cli_helpers.Fatal('foo') print_mock.assert_called_once_with('\033[91mfoo\033[0m') sys_exit_mock.assert_called_once() @mock.patch('__builtin__.print') + # https://crbug.com/938487 + @decorators.Disabled('all') def testPrintsError(self, print_mock): cli_helpers.Error('foo') print_mock.assert_called_once_with('\033[91mfoo\033[0m') @mock.patch('__builtin__.print') + # https://crbug.com/938487 + @decorators.Disabled('all') def testPrintsStep(self, print_mock): long_step_name = 'foobar' * 15 cli_helpers.Step(long_step_name) @@ -52,6 +60,8 @@ @mock.patch('__builtin__.print') @mock.patch('__builtin__.raw_input') + # https://crbug.com/938487 + @decorators.Disabled('all') def testAskAgainOnInvalidAnswer(self, raw_input_mock, print_mock): raw_input_mock.side_effect = ['foobar', 'y'] self.assertTrue(cli_helpers.Ask('Ready?')) @@ -63,6 +73,8 @@ @mock.patch('__builtin__.print') @mock.patch('__builtin__.raw_input') + # https://crbug.com/938487 + @decorators.Disabled('all') def testAskWithCustomAnswersAndDefault(self, raw_input_mock, print_mock): raw_input_mock.side_effect = [''] self.assertFalse( @@ -72,6 +84,8 @@ @mock.patch('__builtin__.print') @mock.patch('__builtin__.raw_input') + # https://crbug.com/938487 + @decorators.Disabled('all') def testAskNoDefaultCustomAnswersAsList(self, raw_input_mock, print_mock): raw_input_mock.side_effect = ['', 'FoO'] self.assertEqual(cli_helpers.Ask('Ready?', ['foo', 'bar']), 'foo') @@ -81,6 +95,8 @@ mock.call('\033[96mReady? [foo/bar] \033[0m', end=' ') ]) + # https://crbug.com/938487 + @decorators.Disabled('all') def testAskWithInvalidDefaultAnswer(self): with self.assertRaises(ValueError): cli_helpers.Ask('Ready?', ['foo', 'bar'], 'baz') @@ -89,6 +105,8 @@ @mock.patch('subprocess.check_call') @mock.patch('__builtin__.open') @mock.patch('datetime.datetime') + # https://crbug.com/938487 + @decorators.Disabled('all') def testCheckLog( self, dt_mock, open_mock, check_call_mock, print_mock): file_mock = mock.Mock() @@ -115,6 +133,8 @@ @mock.patch('subprocess.check_call') @mock.patch('subprocess.call') @mock.patch('__builtin__.open') + # https://crbug.com/938487 + @decorators.Disabled('all') def testCheckLogError( self, open_mock, call_mock, check_call_mock, error_mock, print_mock): del print_mock, open_mock # Unused. @@ -133,6 +153,8 @@ @mock.patch('__builtin__.print') @mock.patch('subprocess.check_call') + # https://crbug.com/938487 + @decorators.Disabled('all') def testRun(self, check_call_mock, print_mock): check_call_mock.side_effect = [subprocess.CalledProcessError(87, ['cmd'])] with self.assertRaises(subprocess.CalledProcessError): @@ -143,17 +165,23 @@ @mock.patch('__builtin__.print') @mock.patch('subprocess.check_call') + # https://crbug.com/938487 + @decorators.Disabled('all') def testRunOkFail(self, check_call_mock, print_mock): del print_mock # Unused. check_call_mock.side_effect = [subprocess.CalledProcessError(87, ['cmd'])] cli_helpers.Run(['cmd'], ok_fail=True) + # https://crbug.com/938487 + @decorators.Disabled('all') def testRunWithNonListCommand(self): with self.assertRaises(ValueError): cli_helpers.Run('cmd with args') @mock.patch('__builtin__.print') @mock.patch('__builtin__.raw_input') + # https://crbug.com/938487 + @decorators.Disabled('all') def testPrompt(self, raw_input_mock, print_mock): raw_input_mock.side_effect = ['', '42'] self.assertEqual(cli_helpers.Prompt(
diff --git a/tools/perf/core/shard_maps/android-nexus5x-perf_map.json b/tools/perf/core/shard_maps/android-nexus5x-perf_map.json index 75df1325d..dae6397 100644 --- a/tools/perf/core/shard_maps/android-nexus5x-perf_map.json +++ b/tools/perf/core/shard_maps/android-nexus5x-perf_map.json
@@ -55,8 +55,6 @@ "begin": 90 }, "media.mobile": {}, - "memory.long_running_idle_gmail_background_tbmv2": {}, - "memory.long_running_idle_gmail_tbmv2": {}, "memory.top_10_mobile": { "end": 10 }
diff --git a/tools/perf/core/shard_maps/android-pixel2-perf_map.json b/tools/perf/core/shard_maps/android-pixel2-perf_map.json index 9b0d077..0f0c66f4 100644 --- a/tools/perf/core/shard_maps/android-pixel2-perf_map.json +++ b/tools/perf/core/shard_maps/android-pixel2-perf_map.json
@@ -39,8 +39,6 @@ "media.mobile": { "begin": 20 }, - "memory.long_running_idle_gmail_background_tbmv2": {}, - "memory.long_running_idle_gmail_tbmv2": {}, "memory.top_10_mobile": {}, "octane": {}, "power.typical_10_mobile": {},
diff --git a/tools/perf/core/shard_maps/android-pixel2_webview-perf_map.json b/tools/perf/core/shard_maps/android-pixel2_webview-perf_map.json index 15f7ee0..38ea5c0 100644 --- a/tools/perf/core/shard_maps/android-pixel2_webview-perf_map.json +++ b/tools/perf/core/shard_maps/android-pixel2_webview-perf_map.json
@@ -30,8 +30,6 @@ "begin": 40 }, "media.mobile": {}, - "memory.long_running_idle_gmail_background_tbmv2": {}, - "memory.long_running_idle_gmail_tbmv2": {}, "memory.top_10_mobile": { "end": 14 }
diff --git a/tools/perf/core/shard_maps/android_nexus5_perf_map.json b/tools/perf/core/shard_maps/android_nexus5_perf_map.json index 0733c44..13d006f9 100644 --- a/tools/perf/core/shard_maps/android_nexus5_perf_map.json +++ b/tools/perf/core/shard_maps/android_nexus5_perf_map.json
@@ -50,9 +50,7 @@ "loading.mobile": { "begin": 60 }, - "media.mobile": {}, - "memory.long_running_idle_gmail_background_tbmv2": {}, - "memory.long_running_idle_gmail_tbmv2": {} + "media.mobile": {} } }, "5": {
diff --git a/tools/perf/core/shard_maps/android_nexus5x_webview_perf_map.json b/tools/perf/core/shard_maps/android_nexus5x_webview_perf_map.json index b95e7d0c..a43fd386 100644 --- a/tools/perf/core/shard_maps/android_nexus5x_webview_perf_map.json +++ b/tools/perf/core/shard_maps/android_nexus5x_webview_perf_map.json
@@ -59,8 +59,6 @@ "begin": 92 }, "media.mobile": {}, - "memory.long_running_idle_gmail_background_tbmv2": {}, - "memory.long_running_idle_gmail_tbmv2": {}, "memory.top_10_mobile": { "end": 18 }
diff --git a/tools/perf/core/shard_maps/android_nexus6_webview_perf_map.json b/tools/perf/core/shard_maps/android_nexus6_webview_perf_map.json index d600911c..a15807f 100644 --- a/tools/perf/core/shard_maps/android_nexus6_webview_perf_map.json +++ b/tools/perf/core/shard_maps/android_nexus6_webview_perf_map.json
@@ -34,8 +34,6 @@ "begin": 73 }, "media.mobile": {}, - "memory.long_running_idle_gmail_background_tbmv2": {}, - "memory.long_running_idle_gmail_tbmv2": {}, "memory.top_10_mobile": {}, "octane": {}, "oortonline_tbmv2": {},
diff --git a/tools/perf/core/shard_maps/android_one_16_shard_map.json b/tools/perf/core/shard_maps/android_one_16_shard_map.json index 940cd14e..d09cc6e 100644 --- a/tools/perf/core/shard_maps/android_one_16_shard_map.json +++ b/tools/perf/core/shard_maps/android_one_16_shard_map.json
@@ -50,7 +50,6 @@ "wasm": {}, "dummy_benchmark.histogram_benchmark_1": {}, "speedometer": {}, - "memory.long_running_idle_gmail_tbmv2": {}, "octane": {}, "dummy_benchmark.noisy_benchmark_1": {}, "blink_perf.svg": {}, @@ -105,7 +104,6 @@ "blink_perf.layout": { "begin": 4 }, - "memory.long_running_idle_gmail_background_tbmv2": {}, "tab_switching.typical_25": {}, "blink_perf.dom": {}, "media.mobile": {},
diff --git a/tools/perf/core/shard_maps/linux-perf_map.json b/tools/perf/core/shard_maps/linux-perf_map.json index 5b7374ee..a9b3bb3 100644 --- a/tools/perf/core/shard_maps/linux-perf_map.json +++ b/tools/perf/core/shard_maps/linux-perf_map.json
@@ -74,8 +74,6 @@ "memory.desktop": { "begin": 4 }, - "memory.long_running_idle_gmail_background_tbmv2": {}, - "memory.long_running_idle_gmail_tbmv2": {}, "octane": {}, "power.desktop": { "end": 6
diff --git a/tools/perf/core/shard_maps/mac-10_12_laptop_low_end-perf_map.json b/tools/perf/core/shard_maps/mac-10_12_laptop_low_end-perf_map.json index c545cedf..2815296 100644 --- a/tools/perf/core/shard_maps/mac-10_12_laptop_low_end-perf_map.json +++ b/tools/perf/core/shard_maps/mac-10_12_laptop_low_end-perf_map.json
@@ -73,8 +73,6 @@ "memory.desktop": { "begin": 6 }, - "memory.long_running_idle_gmail_background_tbmv2": {}, - "memory.long_running_idle_gmail_tbmv2": {}, "octane": {}, "oortonline_tbmv2": {}, "power.desktop": {
diff --git a/tools/perf/core/shard_maps/mac-10_13_laptop_high_end-perf_map.json b/tools/perf/core/shard_maps/mac-10_13_laptop_high_end-perf_map.json index ea287f9..e4af6dac 100644 --- a/tools/perf/core/shard_maps/mac-10_13_laptop_high_end-perf_map.json +++ b/tools/perf/core/shard_maps/mac-10_13_laptop_high_end-perf_map.json
@@ -69,8 +69,6 @@ }, "6": { "benchmarks": { - "memory.long_running_idle_gmail_background_tbmv2": {}, - "memory.long_running_idle_gmail_tbmv2": {}, "octane": {}, "oortonline_tbmv2": {}, "power.desktop": {},
diff --git a/tools/perf/core/shard_maps/win-10-perf_map.json b/tools/perf/core/shard_maps/win-10-perf_map.json index b54bf6b5..16bf4c0 100644 --- a/tools/perf/core/shard_maps/win-10-perf_map.json +++ b/tools/perf/core/shard_maps/win-10-perf_map.json
@@ -72,9 +72,7 @@ "benchmarks": { "memory.desktop": { "begin": 2 - }, - "memory.long_running_idle_gmail_background_tbmv2": {}, - "memory.long_running_idle_gmail_tbmv2": {} + } } }, "7": {
diff --git a/tools/perf/core/shard_maps/win10_highdpi_shard_map.json b/tools/perf/core/shard_maps/win10_highdpi_shard_map.json index c3bf6cb1..98abca0 100644 --- a/tools/perf/core/shard_maps/win10_highdpi_shard_map.json +++ b/tools/perf/core/shard_maps/win10_highdpi_shard_map.json
@@ -10,7 +10,6 @@ "wasm": {}, "dummy_benchmark.histogram_benchmark_1": {}, "speedometer": {}, - "memory.long_running_idle_gmail_tbmv2": {}, "octane": {}, "dummy_benchmark.noisy_benchmark_1": {}, "blink_perf.svg": {}, @@ -34,7 +33,6 @@ "blink_perf.shadow_dom": {}, "blink_perf.events": {}, "blink_perf.layout": {}, - "memory.long_running_idle_gmail_background_tbmv2": {}, "tab_switching.typical_25": {}, "blink_perf.dom": {}, "start_with_url.cold.startup_pages": {},
diff --git a/tools/perf/core/shard_maps/win_7_nvidia_gpu_perf_map.json b/tools/perf/core/shard_maps/win_7_nvidia_gpu_perf_map.json index f3d23fb..5546e99 100644 --- a/tools/perf/core/shard_maps/win_7_nvidia_gpu_perf_map.json +++ b/tools/perf/core/shard_maps/win_7_nvidia_gpu_perf_map.json
@@ -22,8 +22,6 @@ "loading.desktop": {}, "media.desktop": {}, "memory.desktop": {}, - "memory.long_running_idle_gmail_background_tbmv2": {}, - "memory.long_running_idle_gmail_tbmv2": {}, "octane": {}, "power.desktop": { "end": 1
diff --git a/tools/perf/core/shard_maps/win_7_perf_map.json b/tools/perf/core/shard_maps/win_7_perf_map.json index c29ab10..3d07b860 100644 --- a/tools/perf/core/shard_maps/win_7_perf_map.json +++ b/tools/perf/core/shard_maps/win_7_perf_map.json
@@ -21,9 +21,7 @@ "kraken": {}, "loading.desktop": {}, "media.desktop": {}, - "memory.desktop": {}, - "memory.long_running_idle_gmail_background_tbmv2": {}, - "memory.long_running_idle_gmail_tbmv2": {} + "memory.desktop": {} } }, "1": {
diff --git a/tools/perf/core/undocumented_benchmarks.py b/tools/perf/core/undocumented_benchmarks.py index e0b9659..3bb142b0 100644 --- a/tools/perf/core/undocumented_benchmarks.py +++ b/tools/perf/core/undocumented_benchmarks.py
@@ -19,8 +19,6 @@ 'media.mobile', 'media_perftests', 'memory.desktop', - 'memory.long_running_idle_gmail_background_tbmv2', - 'memory.long_running_idle_gmail_tbmv2', 'memory.top_10_mobile', 'net_perftests', 'octane',
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config index 8610ff9..276756c1 100644 --- a/tools/perf/expectations.config +++ b/tools/perf/expectations.config
@@ -161,16 +161,6 @@ crbug.com/865400 [ Pixel_2 Android_Webview ] loading.mobile/VoiceMemos_cold_3g [ Skip ] crbug.com/919191 [ Nexus5X_Webview ] loading.mobile/OLX_3g [ Skip ] -# Benchmark: memory.long_running_idle_gmail_tbmv2 -crbug.com/611167 [ Android_Svelte ] memory.long_running_idle_gmail_tbmv2/* [ Skip ] -crbug.com/901510 [ Nexus6_Webview ] memory.long_running_idle_gmail_tbmv2/* [ Skip ] -crbug.com/901510 [ Nexus_5 ] memory.long_running_idle_gmail_tbmv2/* [ Skip ] -crbug.com/901510 [ Nexus5X_Webview ] memory.long_running_idle_gmail_tbmv2/* [ Skip ] -crbug.com/901510 [ Nexus_5X ] memory.long_running_idle_gmail_tbmv2/* [ Skip ] - -# Benchmark: memory.long_running_idle_gmail_background_tbmv2 -crbug.com/611167 [ Android_Svelte ] memory.long_running_idle_gmail_background_tbmv2/* [ Skip ] - # Benchmark: oilpan_gc_times.key_silk_cases crbug.com/446332 [ All ] oilpan_gc_times.key_silk_cases/slide_drawer [ Skip ] crbug.com/507865 [ All ] oilpan_gc_times.key_silk_cases/polymer_topeka [ Skip ]
diff --git a/tools/perf/page_sets/data/rendering_desktop.json b/tools/perf/page_sets/data/rendering_desktop.json index f183598..5d7eeffb0 100644 --- a/tools/perf/page_sets/data/rendering_desktop.json +++ b/tools/perf/page_sets/data/rendering_desktop.json
@@ -172,7 +172,7 @@ "DEFAULT": "rendering_desktop_004.wprgo" }, "linkedin_2018": { - "DEFAULT": "rendering_desktop_000.wprgo" + "DEFAULT": "rendering_desktop_6eb5e5be2a.wprgo" }, "linkedin_pinch_2018": { "DEFAULT": "rendering_desktop_007.wprgo"
diff --git a/tools/perf/page_sets/data/rendering_desktop_6eb5e5be2a.wprgo.sha1 b/tools/perf/page_sets/data/rendering_desktop_6eb5e5be2a.wprgo.sha1 new file mode 100644 index 0000000..fd9d4a4a --- /dev/null +++ b/tools/perf/page_sets/data/rendering_desktop_6eb5e5be2a.wprgo.sha1
@@ -0,0 +1 @@ +6eb5e5be2a9992e4e2e24b15bfcff5dfa919c53d \ No newline at end of file
diff --git a/tools/perf/page_sets/data/rendering_mobile.json b/tools/perf/page_sets/data/rendering_mobile.json index 3a2fdc5..162b4fae 100644 --- a/tools/perf/page_sets/data/rendering_mobile.json +++ b/tools/perf/page_sets/data/rendering_mobile.json
@@ -292,16 +292,16 @@ "DEFAULT": "rendering_mobile_025.wprgo" }, "linkedin_2018": { - "DEFAULT": "rendering_mobile_000.wprgo" + "DEFAULT": "rendering_mobile_d5f51fba2e.wprgo" }, "linkedin_desktop_gpu_raster_2018": { - "DEFAULT": "rendering_mobile_000.wprgo" + "DEFAULT": "rendering_mobile_fae11cb2b3.wprgo" }, "linkedin_mobile_2018": { - "DEFAULT": "rendering_mobile_011.wprgo" + "DEFAULT": "rendering_mobile_d5f51fba2e.wprgo" }, "linkedin_pathological_2018": { - "DEFAULT": "rendering_mobile_025.wprgo" + "DEFAULT": "rendering_mobile_d5f51fba2e.wprgo" }, "list_recycle_transform": { "DEFAULT": "rendering_mobile_018.wprgo"
diff --git a/tools/perf/page_sets/data/rendering_mobile_d5f51fba2e.wprgo.sha1 b/tools/perf/page_sets/data/rendering_mobile_d5f51fba2e.wprgo.sha1 new file mode 100644 index 0000000..6b87b05a --- /dev/null +++ b/tools/perf/page_sets/data/rendering_mobile_d5f51fba2e.wprgo.sha1
@@ -0,0 +1 @@ +d5f51fba2e1084bbc60888a70122821c62d22d3d \ No newline at end of file
diff --git a/tools/perf/page_sets/data/rendering_mobile_fae11cb2b3.wprgo.sha1 b/tools/perf/page_sets/data/rendering_mobile_fae11cb2b3.wprgo.sha1 new file mode 100644 index 0000000..00d64acc --- /dev/null +++ b/tools/perf/page_sets/data/rendering_mobile_fae11cb2b3.wprgo.sha1
@@ -0,0 +1 @@ +fae11cb2b32b17394533d28138abe46b574a70c0 \ No newline at end of file
diff --git a/tools/perf/page_sets/login_helpers/linkedin_login.py b/tools/perf/page_sets/login_helpers/linkedin_login.py index f65ebd25..2ca64819 100644 --- a/tools/perf/page_sets/login_helpers/linkedin_login.py +++ b/tools/perf/page_sets/login_helpers/linkedin_login.py
@@ -32,12 +32,16 @@ action_runner, password, 'input[type=password]') login_button_function = ( - 'document.getElementsByName("signin")[0]') + '''document.querySelectorAll("[aria-label^='Sign in']")[0]''') action_runner.WaitForElement(element_function=login_button_function) action_runner.ClickElement(element_function=login_button_function) + action_runner.Wait(2) + # This reload is needed for opening desktop page on mobile device + action_runner.ReloadPage() + search_bar_function = ( - 'document.getElementsByClassName("nav-search-bar")[0]') + "document.getElementById('extended-nav-search')") action_runner.WaitForElement(element_function=search_bar_function) @@ -51,12 +55,12 @@ action_runner.Navigate('https://www.linkedin.com/uas/login') action_runner.Wait(1) # Error page happens if this wait is not here. login_utils.InputWithSelector( - action_runner, '%s@gmail.com' % account_name, 'input[type=email]') + action_runner, '%s@gmail.com' % account_name, 'input[name=session_key]') login_utils.InputWithSelector( - action_runner, password, 'input[type=password]') + action_runner, password, 'input[name=session_password]') login_button_function = ( - 'document.getElementById("signin-submit")') + '''document.querySelectorAll("[aria-label^='Sign in']")[0]''') action_runner.WaitForElement(element_function=login_button_function) action_runner.ClickElement(element_function=login_button_function)
diff --git a/tools/perf/page_sets/long_running_idle_google_cases.py b/tools/perf/page_sets/long_running_idle_google_cases.py deleted file mode 100644 index 302cddf..0000000 --- a/tools/perf/page_sets/long_running_idle_google_cases.py +++ /dev/null
@@ -1,50 +0,0 @@ -# Copyright 2015 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. - -from telemetry import story - -from page_sets import google_pages - -IDLE_TIME_IN_SECONDS = 100 -SAMPLING_INTERVAL_IN_SECONDS = 1 -STEPS = IDLE_TIME_IN_SECONDS / SAMPLING_INTERVAL_IN_SECONDS - -def _IdleAction(action_runner): - action_runner.tab.browser.DumpMemory() - for _ in xrange(STEPS): - action_runner.Wait(SAMPLING_INTERVAL_IN_SECONDS) - action_runner.tab.browser.DumpMemory() - -def _CreateIdlePageClass(base_page_cls): - class DerivedIdlePage(base_page_cls): # pylint: disable=no-init - def RunPageInteractions(self, action_runner): - _IdleAction(action_runner) - return DerivedIdlePage - - -def _CreateIdleBackgroundPageClass(base_page_cls): - class DerivedIdlePage(base_page_cls): # pylint: disable=no-init - def RunPageInteractions(self, action_runner): - action_runner.tab.browser.tabs.New() - _IdleAction(action_runner) - return DerivedIdlePage - - -class LongRunningIdleGmailPageSet(story.StorySet): - def __init__(self): - super(LongRunningIdleGmailPageSet, self).__init__( - archive_data_file='data/long_running_idle_gmail_page.json', - cloud_storage_bucket=story.PARTNER_BUCKET) - self.AddStory( - _CreateIdlePageClass(google_pages.GmailPage)(self)) - - -class LongRunningIdleGmailBackgroundPageSet(story.StorySet): - def __init__(self): - # Reuse the wpr of foreground gmail. - super(LongRunningIdleGmailBackgroundPageSet, self).__init__( - archive_data_file='data/long_running_idle_gmail_page.json', - cloud_storage_bucket=story.PARTNER_BUCKET) - self.AddStory( - _CreateIdleBackgroundPageClass(google_pages.GmailPage)(self))
diff --git a/ui/base/accelerators/accelerator.cc b/ui/base/accelerators/accelerator.cc index bf214d0..a59d08c 100644 --- a/ui/base/accelerators/accelerator.cc +++ b/ui/base/accelerators/accelerator.cc
@@ -161,7 +161,10 @@ key = static_cast<wchar_t>(key_code_); else key = LOWORD(::MapVirtualKeyW(key_code_, MAPVK_VK_TO_CHAR)); - shortcut += key; + // If there is no translation for the given |key_code_| (e.g. + // VKEY_UNKNOWN), |::MapVirtualKeyW| returns 0. + if (key != 0) + shortcut += key; #elif defined(USE_AURA) || defined(OS_MACOSX) || defined(OS_ANDROID) const uint16_t c = DomCodeToUsLayoutCharacter( UsLayoutKeyboardCodeToDomCode(key_code_), false);
diff --git a/ui/base/accelerators/accelerator_unittest.cc b/ui/base/accelerators/accelerator_unittest.cc index f86c3ca..3627c50 100644 --- a/ui/base/accelerators/accelerator_unittest.cc +++ b/ui/base/accelerators/accelerator_unittest.cc
@@ -62,4 +62,9 @@ } } +TEST(AcceleratorTest, ShortcutTextForUnknownKey) { + const Accelerator accelerator(VKEY_UNKNOWN, EF_NONE); + EXPECT_EQ(base::string16(), accelerator.GetShortcutText()); +} + } // namespace ui
diff --git a/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js b/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js index 2036972..7e8a26f 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js +++ b/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js
@@ -918,7 +918,7 @@ const onSuccess = (entries) => { this.entries_ = entries; this.updateSubElementsFromList(recursive); - if (this.entries_.length > 0 && this.selected) { + if (this.entries_.length > 0) { this.expanded = true; } opt_successCallback && opt_successCallback();
diff --git a/ui/file_manager/integration_tests/file_manager/metadata.js b/ui/file_manager/integration_tests/file_manager/metadata.js index b4a7bb0f..3618e06 100644 --- a/ui/file_manager/integration_tests/file_manager/metadata.js +++ b/ui/file_manager/integration_tests/file_manager/metadata.js
@@ -121,7 +121,7 @@ // Navigate 2 folders deep, because navigating in directory tree might // trigger further metadata fetches. await remoteCall.navigateWithDirectoryTree( - appId, '/root/photos1/folder1', 'My Drive', 'drive'); + appId, '/root/photos1/folder1', 'My Drive'); // Fetch the metadata stats. const metadataStats = @@ -216,12 +216,11 @@ // Open Files app on Drive. const appId = await setupAndWaitUntilReady(RootPath.DRIVE, entries, entries); - console.log('setupAndWaitUntilReady finished!'); // Navigate only 1 folder deep,which is slightly different from // metadatatDrive test. await remoteCall.navigateWithDirectoryTree( - appId, '/root/folder1', 'My Drive', 'drive'); + appId, '/root/folder1', 'My Drive'); // Wait for the metadata stats to reach the desired count. // File list component, doesn't display all files at once for performance @@ -288,7 +287,7 @@ // Navigate to Team Drives root. await remoteCall.navigateWithDirectoryTree( - appId, '/team_drives', 'Team Drives', 'drive'); + appId, '/team_drives', 'Team Drives'); // Expand Team Drives, because expanding might need metadata. const expandIcon = teamDriveTreeItem + ' > .tree-row > .expand-icon';
diff --git a/ui/file_manager/integration_tests/file_manager/my_files.js b/ui/file_manager/integration_tests/file_manager/my_files.js index a06ea6d..aab3fb6 100644 --- a/ui/file_manager/integration_tests/file_manager/my_files.js +++ b/ui/file_manager/integration_tests/file_manager/my_files.js
@@ -294,40 +294,3 @@ appId, expectedRows2, {ignoreFileSize: true, ignoreLastModifiedTime: true}); }; - -/** - * Tests that MyFiles doesn't expand when it isn't selected. - */ -testcase.myFilesExpandWhenSelected = async () => { - // Open Files app on local Downloads. - const appId = await setupAndWaitUntilReady( - RootPath.DOWNLOADS, [ENTRIES.photos], [ENTRIES.beautiful]); - - // Collapse MyFiles. - const myFiles = '#directory-tree [entry-label="My files"]'; - let expandIcon = myFiles + '[expanded] > .tree-row > .expand-icon'; - await remoteCall.waitAndClickElement(appId, expandIcon); - await remoteCall.waitForElement(appId, myFiles + ':not([expanded])'); - - // Expand Google Drive. - const driveGrandRoot = '#directory-tree [entry-label="Google Drive"]'; - expandIcon = driveGrandRoot + ' > .tree-row > .expand-icon'; - await remoteCall.waitAndClickElement(appId, expandIcon); - - // Wait for its subtree to expand and display its children. - const expandedSubItems = - driveGrandRoot + ' > .tree-children[expanded] > .tree-item'; - await remoteCall.waitForElement(appId, expandedSubItems); - - // Click on My Drive - const myDrive = '#directory-tree [entry-label="My Drive"]'; - await remoteCall.waitAndClickElement(appId, myDrive); - - // Wait for My Drive to selected. - await remoteCall.waitForFiles( - appId, [ENTRIES.beautiful.getExpectedRow()], - {ignoreFileSize: true, ignoreLastModifiedTime: true}); - - // Check that MyFiles is still collapsed. - await remoteCall.waitForElement(appId, myFiles + ':not([expanded])'); -};
diff --git a/ui/ozone/platform/wayland/BUILD.gn b/ui/ozone/platform/wayland/BUILD.gn index 1aa2d7b..952e0c9 100644 --- a/ui/ozone/platform/wayland/BUILD.gn +++ b/ui/ozone/platform/wayland/BUILD.gn
@@ -158,6 +158,8 @@ "test/global_object.h", "test/mock_buffer.cc", "test/mock_buffer.h", + "test/mock_pointer.cc", + "test/mock_pointer.h", "test/mock_surface.cc", "test/mock_surface.h", "test/mock_xdg_popup.cc", @@ -188,8 +190,6 @@ "test/test_keyboard.h", "test/test_output.cc", "test/test_output.h", - "test/test_pointer.cc", - "test/test_pointer.h", "test/test_positioner.cc", "test/test_positioner.h", "test/test_region.cc",
diff --git a/ui/ozone/platform/wayland/test/mock_pointer.cc b/ui/ozone/platform/wayland/test/mock_pointer.cc new file mode 100644 index 0000000..e41ad81 --- /dev/null +++ b/ui/ozone/platform/wayland/test/mock_pointer.cc
@@ -0,0 +1,32 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/ozone/platform/wayland/test/mock_pointer.h" + +namespace wl { + +namespace { + +void SetCursor(wl_client* client, + wl_resource* pointer_resource, + uint32_t serial, + wl_resource* surface_resource, + int32_t hotspot_x, + int32_t hotspot_y) { + GetUserDataAs<MockPointer>(pointer_resource) + ->SetCursor(surface_resource, hotspot_x, hotspot_y); +} + +} // namespace + +const struct wl_pointer_interface kMockPointerImpl = { + &SetCursor, // set_cursor + &DestroyResource, // release +}; + +MockPointer::MockPointer(wl_resource* resource) : ServerObject(resource) {} + +MockPointer::~MockPointer() = default; + +} // namespace wl
diff --git a/ui/ozone/platform/wayland/test/mock_pointer.h b/ui/ozone/platform/wayland/test/mock_pointer.h new file mode 100644 index 0000000..811f854 --- /dev/null +++ b/ui/ozone/platform/wayland/test/mock_pointer.h
@@ -0,0 +1,36 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_OZONE_PLATFORM_WAYLAND_TEST_MOCK_POINTER_H_ +#define UI_OZONE_PLATFORM_WAYLAND_TEST_MOCK_POINTER_H_ + +#include <wayland-server-protocol.h> + +#include "base/macros.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "ui/ozone/platform/wayland/test/server_object.h" + +struct wl_resource; + +namespace wl { + +extern const struct wl_pointer_interface kMockPointerImpl; + +class MockPointer : public ServerObject { + public: + explicit MockPointer(wl_resource* resource); + ~MockPointer() override; + + MOCK_METHOD3(SetCursor, + void(wl_resource* surface_resource, + int32_t hotspot_x, + int32_t hotspot_y)); + + private: + DISALLOW_COPY_AND_ASSIGN(MockPointer); +}; + +} // namespace wl + +#endif // UI_OZONE_PLATFORM_WAYLAND_TEST_MOCK_POINTER_H_
diff --git a/ui/ozone/platform/wayland/test/test_pointer.cc b/ui/ozone/platform/wayland/test/test_pointer.cc deleted file mode 100644 index ed2c9c0..0000000 --- a/ui/ozone/platform/wayland/test/test_pointer.cc +++ /dev/null
@@ -1,18 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "ui/ozone/platform/wayland/test/test_pointer.h" - -namespace wl { - -const struct wl_pointer_interface kTestPointerImpl = { - nullptr, // set_cursor - &DestroyResource, // release -}; - -TestPointer::TestPointer(wl_resource* resource) : ServerObject(resource) {} - -TestPointer::~TestPointer() = default; - -} // namespace wl
diff --git a/ui/ozone/platform/wayland/test/test_pointer.h b/ui/ozone/platform/wayland/test/test_pointer.h deleted file mode 100644 index 7099fe2e..0000000 --- a/ui/ozone/platform/wayland/test/test_pointer.h +++ /dev/null
@@ -1,30 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef UI_OZONE_PLATFORM_WAYLAND_TEST_TEST_POINTER_H_ -#define UI_OZONE_PLATFORM_WAYLAND_TEST_TEST_POINTER_H_ - -#include <wayland-server-protocol.h> - -#include "base/macros.h" -#include "ui/ozone/platform/wayland/test/server_object.h" - -struct wl_resource; - -namespace wl { - -extern const struct wl_pointer_interface kTestPointerImpl; - -class TestPointer : public ServerObject { - public: - explicit TestPointer(wl_resource* resource); - ~TestPointer() override; - - private: - DISALLOW_COPY_AND_ASSIGN(TestPointer); -}; - -} // namespace wl - -#endif // UI_OZONE_PLATFORM_WAYLAND_TEST_MOCK_POINTER_H_
diff --git a/ui/ozone/platform/wayland/test/test_seat.cc b/ui/ozone/platform/wayland/test/test_seat.cc index b67dfdd..8ce5dca 100644 --- a/ui/ozone/platform/wayland/test/test_seat.cc +++ b/ui/ozone/platform/wayland/test/test_seat.cc
@@ -4,8 +4,8 @@ #include "ui/ozone/platform/wayland/test/test_seat.h" +#include "ui/ozone/platform/wayland/test/mock_pointer.h" #include "ui/ozone/platform/wayland/test/test_keyboard.h" -#include "ui/ozone/platform/wayland/test/test_pointer.h" #include "ui/ozone/platform/wayland/test/test_touch.h" namespace wl { @@ -15,11 +15,11 @@ constexpr uint32_t kSeatVersion = 4; void GetPointer(wl_client* client, wl_resource* resource, uint32_t id) { - wl_resource* pointer_resource = CreateResourceWithImpl<TestPointer>( + wl_resource* pointer_resource = CreateResourceWithImpl<MockPointer>( client, &wl_pointer_interface, wl_resource_get_version(resource), - &kTestPointerImpl, id); + &kMockPointerImpl, id); GetUserDataAs<TestSeat>(resource)->set_pointer( - GetUserDataAs<TestPointer>(pointer_resource)); + GetUserDataAs<MockPointer>(pointer_resource)); } void GetKeyboard(wl_client* client, wl_resource* resource, uint32_t id) {
diff --git a/ui/ozone/platform/wayland/test/test_seat.h b/ui/ozone/platform/wayland/test/test_seat.h index 8a33d87..773f434 100644 --- a/ui/ozone/platform/wayland/test/test_seat.h +++ b/ui/ozone/platform/wayland/test/test_seat.h
@@ -14,8 +14,8 @@ extern const struct wl_seat_interface kTestSeatImpl; +class MockPointer; class TestKeyboard; -class TestPointer; class TestTouch; // Manages a global wl_seat object. @@ -29,8 +29,8 @@ TestSeat(); ~TestSeat() override; - void set_pointer(TestPointer* pointer) { pointer_ = pointer; } - TestPointer* pointer() const { return pointer_; } + void set_pointer(MockPointer* pointer) { pointer_ = pointer; } + MockPointer* pointer() const { return pointer_; } void set_keyboard(TestKeyboard* keyboard) { keyboard_ = keyboard; } TestKeyboard* keyboard() const { return keyboard_; } @@ -39,7 +39,7 @@ TestTouch* touch() const { return touch_; } private: - TestPointer* pointer_; + MockPointer* pointer_; TestKeyboard* keyboard_; TestTouch* touch_;
diff --git a/ui/ozone/platform/wayland/wayland_cursor.cc b/ui/ozone/platform/wayland/wayland_cursor.cc index 0be77ee..db2d5913 100644 --- a/ui/ozone/platform/wayland/wayland_cursor.cc +++ b/ui/ozone/platform/wayland/wayland_cursor.cc
@@ -16,80 +16,71 @@ namespace ui { -WaylandCursor::WaylandCursor() : shared_memory_(new base::SharedMemory()) {} +WaylandCursor::WaylandCursor() = default; + +WaylandCursor::~WaylandCursor() = default; + +// static +void WaylandCursor::OnBufferRelease(void* data, wl_buffer* buffer) { + auto* cursor = static_cast<WaylandCursor*>(data); + DCHECK(cursor->buffers_.count(buffer) > 0); + cursor->buffers_.erase(buffer); +} void WaylandCursor::Init(wl_pointer* pointer, WaylandConnection* connection) { - if (input_pointer_ == pointer) - return; + DCHECK(connection); input_pointer_ = pointer; - DCHECK(connection); shm_ = connection->shm(); pointer_surface_.reset( wl_compositor_create_surface(connection->compositor())); } -WaylandCursor::~WaylandCursor() { - pointer_surface_.reset(); - buffer_.reset(); - - if (shared_memory_->handle().GetHandle()) { - shared_memory_->Unmap(); - shared_memory_->Close(); - } -} - void WaylandCursor::UpdateBitmap(const std::vector<SkBitmap>& cursor_image, - const gfx::Point& location, + const gfx::Point& hotspot, uint32_t serial) { if (!input_pointer_) return; - if (!cursor_image.size()) { - HideCursor(serial); - return; - } + if (!cursor_image.size()) + return HideCursor(serial); const SkBitmap& image = cursor_image[0]; SkISize size = image.dimensions(); - if (size.isEmpty()) { - HideCursor(serial); - return; - } + if (size.isEmpty()) + return HideCursor(serial); gfx::Size image_size = gfx::SkISizeToSize(size); - if (image_size != size_) { - wl_buffer* buffer = - wl::CreateSHMBuffer(image_size, shared_memory_.get(), shm_); - if (!buffer) { - LOG(ERROR) << "Failed to create SHM buffer for Cursor Bitmap."; - wl_pointer_set_cursor(input_pointer_, serial, nullptr, 0, 0); - return; - } - buffer_.reset(buffer); - size_ = image_size; + auto shared_memory = std::make_unique<base::SharedMemory>(); + wl::Object<wl_buffer> buffer( + wl::CreateSHMBuffer(image_size, shared_memory.get(), shm_)); + if (!buffer) { + LOG(ERROR) << "Failed to create SHM buffer for Cursor Bitmap."; + return HideCursor(serial); } - wl::DrawBitmapToSHMB(size_, *shared_memory_, image); + + static const struct wl_buffer_listener wl_buffer_listener { + &WaylandCursor::OnBufferRelease + }; + wl_buffer_add_listener(buffer.get(), &wl_buffer_listener, this); + + wl::DrawBitmapToSHMB(image_size, *shared_memory, image); wl_pointer_set_cursor(input_pointer_, serial, pointer_surface_.get(), - location.x(), location.y()); - wl_surface_attach(pointer_surface_.get(), buffer_.get(), 0, 0); - wl_surface_damage(pointer_surface_.get(), 0, 0, size_.width(), - size_.height()); + hotspot.x(), hotspot.y()); + wl_surface_attach(pointer_surface_.get(), buffer.get(), 0, 0); wl_surface_commit(pointer_surface_.get()); + + buffers_.emplace( + buffer.get(), + std::pair<wl::Object<wl_buffer>, std::unique_ptr<base::SharedMemory>>( + std::move(buffer), std::move(shared_memory))); } void WaylandCursor::HideCursor(uint32_t serial) { - size_ = gfx::Size(); + DCHECK(input_pointer_); wl_pointer_set_cursor(input_pointer_, serial, nullptr, 0, 0); - - buffer_.reset(); - - if (shared_memory_->handle().GetHandle()) { - shared_memory_->Unmap(); - shared_memory_->Close(); - } } } // namespace ui
diff --git a/ui/ozone/platform/wayland/wayland_cursor.h b/ui/ozone/platform/wayland/wayland_cursor.h index 074df84..e7e8368d 100644 --- a/ui/ozone/platform/wayland/wayland_cursor.h +++ b/ui/ozone/platform/wayland/wayland_cursor.h
@@ -6,12 +6,14 @@ #define UI_OZONE_PLATFORM_WAYLAND_WAYLAND_CURSOR_H_ #include <wayland-client.h> +#include <memory> +#include <utility> #include <vector> +#include "base/containers/flat_map.h" #include "base/macros.h" #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkSurface.h" -#include "ui/gfx/geometry/size.h" #include "ui/ozone/platform/wayland/wayland_object.h" namespace base { @@ -26,10 +28,14 @@ class WaylandConnection; -// The WaylandCursor class wraps the actual visual representation -// (what users see drawn) of a wl_pointer. +// Manages the actual visual representation (what users see drawn) of the +// 'pointer' (which is the Wayland term for mouse/mice). // -// 'pointer' is the Wayland terminology for mouse/mice. +// An instance of this class is aggregated by an instance of WaylandPointer +// and is exposed for updating the pointer bitmap with the single method call. +// +// Encapsulates the low-level job such as surface and buffer management and +// Wayland protocol calls. class WaylandCursor { public: WaylandCursor(); @@ -38,25 +44,29 @@ void Init(wl_pointer* pointer, WaylandConnection* connection); // Updates wl_pointer's visual representation with the given bitmap - // image set, at the hotspot specified by 'location'. + // image set and hotspot. void UpdateBitmap(const std::vector<SkBitmap>& bitmaps, - const gfx::Point& location, + const gfx::Point& hotspot, uint32_t serial); private: + // wl_buffer_listener: + static void OnBufferRelease(void* data, wl_buffer* wl_buffer); + void HideCursor(uint32_t serial); wl_shm* shm_ = nullptr; // Owned by WaylandConnection. wl_pointer* input_pointer_ = nullptr; // Owned by WaylandPointer. - wl::Object<wl_buffer> buffer_; + // Holds the buffers and their memory until the compositor releases them. + base::flat_map< + wl_buffer*, + std::pair<wl::Object<wl_buffer>, std::unique_ptr<base::SharedMemory>>> + buffers_; wl::Object<wl_surface> pointer_surface_; - std::unique_ptr<base::SharedMemory> shared_memory_; sk_sp<SkSurface> sk_surface_; - gfx::Size size_; - DISALLOW_COPY_AND_ASSIGN(WaylandCursor); };
diff --git a/ui/ozone/platform/wayland/wayland_pointer.cc b/ui/ozone/platform/wayland/wayland_pointer.cc index 9063900..4c05825 100644 --- a/ui/ozone/platform/wayland/wayland_pointer.cc +++ b/ui/ozone/platform/wayland/wayland_pointer.cc
@@ -6,6 +6,7 @@ #include <linux/input.h> #include <wayland-client.h> +#include <memory> #include "ui/events/base_event_utils.h" #include "ui/events/event.h" @@ -41,7 +42,7 @@ wl_pointer_add_listener(obj_.get(), &listener, this); - cursor_.reset(new WaylandCursor); + cursor_ = std::make_unique<WaylandCursor>(); } WaylandPointer::~WaylandPointer() {
diff --git a/ui/ozone/platform/wayland/wayland_pointer.h b/ui/ozone/platform/wayland/wayland_pointer.h index 1af7b970..109d08d 100644 --- a/ui/ozone/platform/wayland/wayland_pointer.h +++ b/ui/ozone/platform/wayland/wayland_pointer.h
@@ -16,6 +16,10 @@ class WaylandWindow; +// Wraps the wl_pointer object and transmits events to the dispatcher callback. +// +// Exposes an aggregated WaylandCursor that manages the visual shape of the +// pointer. class WaylandPointer { public: WaylandPointer(wl_pointer* pointer, const EventDispatchCallback& callback);
diff --git a/ui/ozone/platform/wayland/wayland_pointer_unittest.cc b/ui/ozone/platform/wayland/wayland_pointer_unittest.cc index 1242433..49dcfe7 100644 --- a/ui/ozone/platform/wayland/wayland_pointer_unittest.cc +++ b/ui/ozone/platform/wayland/wayland_pointer_unittest.cc
@@ -8,16 +8,19 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/events/event.h" +#include "ui/ozone/platform/wayland/test/mock_pointer.h" #include "ui/ozone/platform/wayland/test/mock_surface.h" -#include "ui/ozone/platform/wayland/test/test_pointer.h" #include "ui/ozone/platform/wayland/test/test_wayland_server_thread.h" +#include "ui/ozone/platform/wayland/wayland_cursor.h" #include "ui/ozone/platform/wayland/wayland_test.h" #include "ui/ozone/platform/wayland/wayland_window.h" #include "ui/ozone/test/mock_platform_window_delegate.h" #include "ui/platform_window/platform_window_init_properties.h" -using ::testing::SaveArg; using ::testing::_; +using ::testing::Mock; +using ::testing::Ne; +using ::testing::SaveArg; namespace ui { @@ -38,7 +41,7 @@ } protected: - wl::TestPointer* pointer_; + wl::MockPointer* pointer_; private: DISALLOW_COPY_AND_ASSIGN(WaylandPointerTest); @@ -312,6 +315,24 @@ EXPECT_EQ(gfx::PointF(50, 75), mouse_wheel_event->root_location_f()); } +TEST_P(WaylandPointerTest, SetBitmap) { + SkBitmap dummy_cursor; + dummy_cursor.setInfo( + SkImageInfo::Make(16, 16, kUnknown_SkColorType, kUnknown_SkAlphaType)); + + EXPECT_CALL(*pointer_, SetCursor(nullptr, 0, 0)); + connection_->SetCursorBitmap({}, {}); + connection_->ScheduleFlush(); + Sync(); + Mock::VerifyAndClearExpectations(pointer_); + + EXPECT_CALL(*pointer_, SetCursor(Ne(nullptr), 5, 8)); + connection_->SetCursorBitmap({dummy_cursor}, gfx::Point(5, 8)); + connection_->ScheduleFlush(); + Sync(); + Mock::VerifyAndClearExpectations(pointer_); +} + INSTANTIATE_TEST_SUITE_P(XdgVersionV5Test, WaylandPointerTest, ::testing::Values(kXdgShellV5));
diff --git a/ui/ozone/platform/wayland/wayland_screen_unittest.cc b/ui/ozone/platform/wayland/wayland_screen_unittest.cc index 2e680a1..a6513be6 100644 --- a/ui/ozone/platform/wayland/wayland_screen_unittest.cc +++ b/ui/ozone/platform/wayland/wayland_screen_unittest.cc
@@ -8,8 +8,8 @@ #include "testing/gtest/include/gtest/gtest.h" #include "ui/display/display_observer.h" +#include "ui/ozone/platform/wayland/test/mock_pointer.h" #include "ui/ozone/platform/wayland/test/mock_surface.h" -#include "ui/ozone/platform/wayland/test/test_pointer.h" #include "ui/ozone/platform/wayland/test/test_wayland_server_thread.h" #include "ui/ozone/platform/wayland/wayland_connection.h" #include "ui/ozone/platform/wayland/wayland_output_manager.h" @@ -450,7 +450,7 @@ Sync(); - wl::TestPointer* pointer = server_.seat()->pointer(); + wl::MockPointer* pointer = server_.seat()->pointer(); ASSERT_TRUE(pointer); uint32_t serial = 0;
diff --git a/ui/ozone/platform/wayland/wayland_window_unittest.cc b/ui/ozone/platform/wayland/wayland_window_unittest.cc index f6f936c..d3a99e1 100644 --- a/ui/ozone/platform/wayland/wayland_window_unittest.cc +++ b/ui/ozone/platform/wayland/wayland_window_unittest.cc
@@ -16,8 +16,8 @@ #include "ui/base/hit_test.h" #include "ui/events/base_event_utils.h" #include "ui/events/event.h" +#include "ui/ozone/platform/wayland/test/mock_pointer.h" #include "ui/ozone/platform/wayland/test/mock_surface.h" -#include "ui/ozone/platform/wayland/test/test_pointer.h" #include "ui/ozone/platform/wayland/test/test_wayland_server_thread.h" #include "ui/ozone/platform/wayland/wayland_test.h" #include "ui/ozone/platform/wayland/wayland_util.h" @@ -597,7 +597,7 @@ Sync(); - wl::TestPointer* pointer = server_.seat()->pointer(); + wl::MockPointer* pointer = server_.seat()->pointer(); ASSERT_TRUE(pointer); wl_pointer_send_enter(pointer->resource(), 1, surface_->resource(), 0, 0);