diff --git a/DEPS b/DEPS index a114032f..0556d19 100644 --- a/DEPS +++ b/DEPS
@@ -105,11 +105,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': 'e72c144af687830af85f6d8546a61475a3c1fb9f', + 'skia_revision': '9eb1c7d80fb3a0b23c0f6a156424a381b4120d3c', # 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': '4a1379f94c23d6366b27ba643d8dc56c3baec413', + 'v8_revision': '8768fa97f4f1c449f5d509d90f0b3dcdde7c6cb0', # 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. @@ -125,11 +125,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': '659d89e94bf94240805b1d075017e43e8b388095', + 'swiftshader_revision': '6b21ba98f6e43eace87729b96a5443de50e1e0a4', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': 'd774a73b59ac36d533064041196d051c032eee6b', + 'pdfium_revision': '86b4f67d40c351ea8e67ba7b7dcc9d8dd7ad371e', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling openmax_dl # and whatever else without interference from each other. @@ -165,7 +165,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '82213060d5ce0d376671dda9ca3928b5ad1c9c69', + 'catapult_revision': '8355b184a56e847ebed034731ee14d6a42543b9a', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -540,7 +540,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'c79c3e591230b186572bc94550d73b74a1063ead', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'f3dacdb5a2e80975b0a78a3e1eca32a0a774da02', 'condition': 'checkout_linux', }, @@ -913,7 +913,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + 'd91316e9576a7baa1eed77caadcecca3edbe2793', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '313aeeeaf50382714be545962ee751d0c907b199', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78', @@ -1035,7 +1035,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'a5c263cc63ffc2cc189b5214074c8792067c1853', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'f4aeb891b7aa34f53a412559c244b468757bbd56', + Var('webrtc_git') + '/src.git' + '@' + 'c480e9d7a86d8d5ab0f45ff4a0e9160c3b34c1a0', 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
diff --git a/base/BUILD.gn b/base/BUILD.gn index cb84017..e574f0c 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -1207,6 +1207,7 @@ defines = [] data = [] data_deps = [] + libs = [] configs += [ ":base_flags", @@ -1240,7 +1241,7 @@ # more robust check for this. if (!use_sysroot && (is_android || (is_linux && !is_chromecast)) && host_toolchain != "//build/toolchain/cros:host") { - libs = [ "atomic" ] + libs += [ "atomic" ] } if (use_allocator_shim) { @@ -1342,7 +1343,7 @@ # This is actually a linker script, but it can be added to the link in the # same way as a library. - libs = [ "android/library_loader/anchor_functions.lds" ] + libs += [ "android/library_loader/anchor_functions.lds" ] } # Chromeos. @@ -1599,7 +1600,7 @@ # TODO(jschuh): crbug.com/167187 fix size_t to int truncations. configs += [ "//build/config/compiler:no_size_t_to_int_warning" ] - libs = [ + libs += [ "cfgmgr32.lib", "powrprof.lib", "propsys.lib", @@ -1627,7 +1628,7 @@ "time/time_mac.cc", ] - libs = [ + libs += [ "ApplicationServices.framework", "AppKit.framework", "bsm",
diff --git a/build/android/gradle/generate_gradle.py b/build/android/gradle/generate_gradle.py index 9f6242e..566e63a 100755 --- a/build/android/gradle/generate_gradle.py +++ b/build/android/gradle/generate_gradle.py
@@ -390,6 +390,12 @@ for s in self.AllResZips(root_entry)) return tuples + def GenerateManifest(self, root_entry): + android_manifest = root_entry.DepsInfo().get('android_manifest') + if not android_manifest: + android_manifest = self._GenCustomManifest(root_entry) + return self._Relativize(root_entry, android_manifest) + def Generate(self, root_entry): # TODO(agrieve): Add an option to use interface jars and see if that speeds # things up at all. @@ -415,11 +421,6 @@ res_dirs.add( os.path.join(self.EntryOutputDir(root_entry), _RES_SUBDIR)) variables['res_dirs'] = self._Relativize(root_entry, res_dirs) - android_manifest = root_entry.DepsInfo().get('android_manifest') - if not android_manifest: - android_manifest = self._GenCustomManifest(root_entry) - variables['android_manifest'] = self._Relativize( - root_entry, android_manifest) if self.split_projects: deps = [_ProjectEntry.FromBuildConfigPath(p) for p in root_entry.Gradle()['dependent_android_projects']] @@ -546,10 +547,7 @@ def _GenerateBaseVars(generator, build_vars, source_properties): - variables = { - 'sourceSetName': 'main', - 'depCompileName': 'compile', - } + variables = {} variables['build_tools_version'] = source_properties['Pkg.Revision'] variables['compile_sdk_version'] = ( 'android-%s' % build_vars['android_sdk_version']) @@ -570,6 +568,9 @@ gradle = entry.Gradle() variables = _GenerateBaseVars(generator, build_vars, source_properties) + + sourceSetName = 'main' + if deps_info['type'] == 'android_apk': target_type = 'android_apk' elif deps_info['type'] == 'java_library': @@ -584,14 +585,18 @@ variables['main_class'] = deps_info.get('main_class') elif deps_info['type'] == 'junit_binary': target_type = 'android_junit' - variables['sourceSetName'] = 'test' - variables['depCompileName'] = 'testCompile' + sourceSetName = 'test' else: return None variables['target_name'] = os.path.splitext(deps_info['name'])[0] variables['template_type'] = target_type - variables['main'] = generator.Generate(entry) + + variables['main'] = {} + variables[sourceSetName] = generator.Generate(entry) + + variables['main']['android_manifest'] = generator.GenerateManifest(entry) + bootclasspath = gradle.get('bootclasspath') if bootclasspath: # Must use absolute path here. @@ -600,6 +605,7 @@ variables['android_test'] = [] for e in entry.android_test_entries: test_entry = generator.Generate(e) + test_entry['android_manifest'] = generator.GenerateManifest(e) variables['android_test'].append(test_entry) for key, value in test_entry.iteritems(): if isinstance(value, list):
diff --git a/build/android/gyp/apkbuilder.py b/build/android/gyp/apkbuilder.py index 1383360..16c1d62 100755 --- a/build/android/gyp/apkbuilder.py +++ b/build/android/gyp/apkbuilder.py
@@ -11,6 +11,7 @@ import os import shutil import sys +import tempfile import zipfile import finalize_apk @@ -48,6 +49,8 @@ parser.add_argument('--output-apk', help='Path to the output file', required=True) + parser.add_argument('--format', choices=['apk', 'bundle-module'], + default='apk', help='Specify output format.') parser.add_argument('--apk-pak-info-path', help='Path to the *.apk.pak.info file') parser.add_argument('--apk-res-info-path', @@ -80,15 +83,15 @@ choices=['true', 'True', 'false', 'False'], help='Whether to uncompress native shared libraries. Argument must be ' 'a boolean value.') - parser.add_argument('--apksigner-path', required=True, + parser.add_argument('--apksigner-path', help='Path to the apksigner executable.') - parser.add_argument('--zipalign-path', required=True, + parser.add_argument('--zipalign-path', help='Path to the zipalign executable.') - parser.add_argument('--key-path', required=True, + parser.add_argument('--key-path', help='Path to keystore for signing.') - parser.add_argument('--key-passwd', required=True, + parser.add_argument('--key-passwd', help='Keystore password') - parser.add_argument('--key-name', required=True, + parser.add_argument('--key-name', help='Keystore name') options = parser.parse_args(args) options.assets = build_utils.ParseGnList(options.assets) @@ -108,6 +111,16 @@ secondary_libs.extend(build_utils.ParseGnList(gyp_list)) options.secondary_native_libs = secondary_libs + # --apksigner-path, --zipalign-path, --key-xxx arguments are + # required when building an APK, but not a bundle module. + if options.format == 'apk': + required_args = ['apksigner_path', 'zipalign_path', 'key_path', + 'key_passwd', 'key_name'] + for required in required_args: + if not vars(options)[required]: + raise Exception('Argument --%s is required for APKs.' % ( + required.replace('_', '-'))) + options.uncompress_shared_libraries = \ options.uncompress_shared_libraries in [ 'true', 'True' ] @@ -257,10 +270,10 @@ # Included via .build_config, so need to write it to depfile. depfile_deps.extend(options.java_resources) - _assets = _ExpandPaths(options.assets) - _uncompressed_assets = _ExpandPaths(options.uncompressed_assets) + assets = _ExpandPaths(options.assets) + uncompressed_assets = _ExpandPaths(options.uncompressed_assets) - for src_path, dest_path in itertools.chain(_assets, _uncompressed_assets): + for src_path, dest_path in itertools.chain(assets, uncompressed_assets): # Included via .build_config, so need to write it to depfile. depfile_deps.append(src_path) input_strings.append(dest_path) @@ -271,14 +284,34 @@ if options.apk_res_info_path: output_paths.append(options.apk_res_info_path) + # Bundle modules have a structure similar to APKs, except that resources + # are compiled in protobuf format (instead of binary xml), and that some + # files are located into different top-level directories, e.g.: + # AndroidManifest.xml -> manifest/AndroidManifest.xml + # classes.dex -> dex/classes.dex + # res/ -> res/ (unchanged) + # assets/ -> assets/ (unchanged) + # <other-file> -> root/<other-file> + # + # Hence, the following variables are used to control the location of files in + # the final archive. + if options.format == 'bundle-module': + apk_manifest_dir = 'manifest/' + apk_root_dir = 'root/' + apk_dex_dir = 'dex/' + else: + apk_manifest_dir = '' + apk_root_dir = '' + apk_dex_dir = '' + def on_stale_md5(): - tmp_apk = options.output_apk + '.tmp' - try: + with tempfile.NamedTemporaryFile() as tmp_apk: + tmp_file = tmp_apk.name with zipfile.ZipFile(options.resource_apk) as resource_apk, \ - zipfile.ZipFile(tmp_apk, 'w', zipfile.ZIP_DEFLATED) as out_apk: - def copy_resource(zipinfo): + zipfile.ZipFile(tmp_file, 'w', zipfile.ZIP_DEFLATED) as out_apk: + def copy_resource(zipinfo, out_dir=''): compress = zipinfo.compress_type != zipfile.ZIP_STORED - build_utils.AddToZipHermetic(out_apk, zipinfo.filename, + build_utils.AddToZipHermetic(out_apk, out_dir + zipinfo.filename, data=resource_apk.read(zipinfo.filename), compress=compress) @@ -288,24 +321,25 @@ # 1. AndroidManifest.xml assert resource_infos[0].filename == 'AndroidManifest.xml' - copy_resource(resource_infos[0]) + copy_resource(resource_infos[0], out_dir=apk_manifest_dir) # 2. Assets if options.write_asset_list: data = _CreateAssetsList( - itertools.chain(_assets, _uncompressed_assets)) + itertools.chain(assets, uncompressed_assets)) build_utils.AddToZipHermetic(out_apk, 'assets/assets_list', data=data) - _AddAssets(out_apk, _assets, disable_compression=False) - _AddAssets(out_apk, _uncompressed_assets, disable_compression=True) + _AddAssets(out_apk, assets, disable_compression=False) + _AddAssets(out_apk, uncompressed_assets, disable_compression=True) # 3. Dex files if options.dex_file and options.dex_file.endswith('.zip'): with zipfile.ZipFile(options.dex_file, 'r') as dex_zip: for dex in (d for d in dex_zip.namelist() if d.endswith('.dex')): - build_utils.AddToZipHermetic(out_apk, dex, data=dex_zip.read(dex)) + build_utils.AddToZipHermetic(out_apk, apk_dex_dir + dex, + data=dex_zip.read(dex)) elif options.dex_file: - build_utils.AddToZipHermetic(out_apk, 'classes.dex', + build_utils.AddToZipHermetic(out_apk, apk_dex_dir + 'classes.dex', src_path=options.dex_file) # 4. Native libraries. @@ -354,7 +388,8 @@ continue build_utils.AddToZipHermetic( - out_apk, apk_path, data=java_resource_jar.read(apk_path)) + out_apk, apk_root_dir + apk_path, + data=java_resource_jar.read(apk_path)) if options.apk_pak_info_path: _MergePakInfoFiles(options.apk_pak_info_path, @@ -362,13 +397,15 @@ if options.apk_res_info_path: _MergeResInfoFiles(options.apk_res_info_path, options.resource_apk) - finalize_apk.FinalizeApk(options.apksigner_path, options.zipalign_path, - tmp_apk, options.output_apk, - options.key_path, options.key_passwd, - options.key_name) - finally: - if os.path.exists(tmp_apk): - os.unlink(tmp_apk) + if options.format == 'apk': + finalize_apk.FinalizeApk(options.apksigner_path, options.zipalign_path, + tmp_file, options.output_apk, + options.key_path, options.key_passwd, + options.key_name) + else: + shutil.move(tmp_file, options.output_apk) + + tmp_apk.delete = False build_utils.CallAndWriteDepfileIfStale( on_stale_md5,
diff --git a/build/android/gyp/app_bundle_to_apks.py b/build/android/gyp/app_bundle_to_apks.py new file mode 100755 index 0000000..cb374d4 --- /dev/null +++ b/build/android/gyp/app_bundle_to_apks.py
@@ -0,0 +1,70 @@ +#!/usr/bin/env python +# +# 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. + +"""Process an app bundle (.aab) file into a set of split APKS (.apks)""" + +import argparse +import itertools +import os +import shutil +import sys +import tempfile +import zipfile + +# NOTE: Keep this consistent with the _app_bundle_to_apk_py_imports definition +# in build/config/android/rules.gni +from util import build_utils +import bundletool + +def _ParseArgs(args): + parser = argparse.ArgumentParser(description=__doc__) + + parser.add_argument('--aapt2', required=True, + help='Path to aapt2 tool') + parser.add_argument('--bundle', required=True, + help='Input bundle file.') + parser.add_argument('--out-zip', required=True, + help='Output zip archive that will contain all APKs.') + parser.add_argument('--keystore-path', required=True, + help='Keystore path') + parser.add_argument('--keystore-password', required=True, + help='Keystore password') + parser.add_argument('--key-name', required=True, + help='Keystore key name') + + options = parser.parse_args(args) + + return options + + +def main(args): + args = build_utils.ExpandFileArgs(args) + options = _ParseArgs(args) + + with build_utils.TempDir() as tmp_dir: + # NOTE: The bundletool build-apks command requires the --output + # path to not exist, and to end with '.apks'. + tmp_bundle = os.path.join(tmp_dir, + os.path.basename(options.bundle) + '.apks') + + cmd_args = ['java', '-jar', bundletool.BUNDLETOOL_JAR_PATH, 'build-apks'] + cmd_args += ['--aapt2=%s' % options.aapt2] + cmd_args += ['--bundle=%s' % options.bundle] + + cmd_args += ['--output=%s' % tmp_bundle] + if options.keystore_path: + cmd_args += [ + '--ks=%s' % options.keystore_path, + '--ks-key-alias=%s' % options.key_name, + '--ks-pass=pass:%s' % options.keystore_password + ] + + build_utils.CheckOutput(cmd_args) + shutil.move(tmp_bundle, options.out_zip) + + +if __name__ == '__main__': + main(sys.argv[1:])
diff --git a/build/android/gyp/create_app_bundle.py b/build/android/gyp/create_app_bundle.py new file mode 100755 index 0000000..08a30f3 --- /dev/null +++ b/build/android/gyp/create_app_bundle.py
@@ -0,0 +1,279 @@ +#!/usr/bin/env python +# +# 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. + +"""Create an Android application bundle from one or more bundle modules.""" + +import argparse +import itertools +import json +import os +import shutil +import sys +import tempfile +import zipfile + +# NOTE: Keep this consistent with the _create_app_bundle_py_imports definition +# in build/config/android/rules.py +from util import build_utils +from util import resource_utils + +import bundletool + +# Location of language-based assets in bundle modules. +_LOCALES_SUBDIR = 'assets/locales/' + +# The fallback language should always have its .pak files included in +# the base apk, i.e. not use language-based asset targetting. This ensures +# that Chrome won't crash on startup if its bundle is installed on a device +# with an unsupported system locale (e.g. fur-rIT). +_FALLBACK_LANGUAGE = 'en' + +# List of split dimensions recognized by this tool. +_ALL_SPLIT_DIMENSIONS = [ 'ABI', 'SCREEN_DENSITY', 'LANGUAGE' ] + +# Due to historical reasons, certain languages identified by Chromium with a +# 3-letters ISO 639-2 code, are mapped to a nearly equivalent 2-letters +# ISO 639-1 code instead (due to the fact that older Android releases only +# supported the latter when matching resources). +# +# the same conversion as for Java resources. +_SHORTEN_LANGUAGE_CODE_MAP = { + 'fil': 'tl', # Filipino to Tagalog. +} + +def _ParseArgs(args): + parser = argparse.ArgumentParser() + parser.add_argument('--out-bundle', required=True, + help='Output bundle zip archive.') + parser.add_argument('--module-zips', required=True, + help='GN-list of module zip archives.') + parser.add_argument('--uncompressed-assets', action='append', + help='GN-list of uncompressed assets.') + parser.add_argument('--uncompress-shared-libraries', action='append', + help='Whether to store native libraries uncompressed. ' + 'This is a string to allow @FileArg usage.') + parser.add_argument('--keystore-path', help='Keystore path') + parser.add_argument('--keystore-password', help='Keystore password') + parser.add_argument('--key-name', help='Keystore key name') + + options = parser.parse_args(args) + options.module_zips = build_utils.ParseGnList(options.module_zips) + + if len(options.module_zips) == 0: + raise Exception('The module zip list cannot be empty.') + + # Signing is optional, but all --keyXX parameters should be set. + if options.keystore_path or options.keystore_password or options.key_name: + if not options.keystore_path or not options.keystore_password or \ + not options.key_name: + raise Exception('When signing the bundle, use --keystore-path, ' + '--keystore-password and --key-name.') + + # Merge all uncompressed assets into a set. + uncompressed_list = [] + for l in options.uncompressed_assets: + for entry in build_utils.ParseGnList(l): + # Each entry has the following format: 'zipPath' or 'srcPath:zipPath' + pos = entry.find(':') + if pos >= 0: + uncompressed_list.append(entry[pos + 1:]) + else: + uncompressed_list.append(entry) + + options.uncompressed_assets = set(uncompressed_list) + + # Merge uncompressed native libs flags, they all must have the same value. + if options.uncompress_shared_libraries: + uncompressed_libs = set(options.uncompress_shared_libraries) + if len(uncompressed_libs) > 1: + raise Exception('Inconsistent uses of --uncompress-native-libs!') + options.uncompress_shared_libraries = 'True' in uncompressed_libs + + return options + + +def _MakeSplitDimension(value, enabled): + """Return dict modelling a BundleConfig splitDimension entry.""" + return {'value': value, 'negate': not enabled} + + +def _GenerateBundleConfigJson(uncompressed_assets, + uncompress_shared_libraries, + split_dimensions): + """Generate a dictionary that can be written to a JSON BuildConfig. + + Args: + uncompressed_assets: A list or set of file paths under assets/ that always + be stored uncompressed. + uncompress_shared_libraries: Boolean, whether to uncompress all native libs. + split_dimensions: list of split dimensions. + Returns: + A dictionary that can be written as a json file. + """ + # Compute splitsConfig list. Each item is a dictionary that can have + # the following keys: + # 'value': One of ['LANGUAGE', 'DENSITY', 'ABI'] + # 'negate': Boolean, True to indicate that the bundle should *not* be + # split (unused at the moment by this script). + + split_dimensions = [ _MakeSplitDimension(dim, dim in split_dimensions) + for dim in _ALL_SPLIT_DIMENSIONS ] + + # Compute uncompressedGlob list. + if uncompress_shared_libraries: + uncompressed_globs = [ + 'lib/*/*.so', # All native libraries. + ] + else: + uncompressed_globs = [ + 'lib/*/crazy.*', # Native libraries loaded by the crazy linker. + ] + + uncompressed_globs.extend('assets/' + x for x in uncompressed_assets) + + data = { + 'optimizations': { + 'splitsConfig': { + 'splitDimension': split_dimensions, + }, + }, + 'compression': { + 'uncompressedGlob': sorted(uncompressed_globs), + }, + } + + return json.dumps(data, indent=2) + + +def _RewriteLanguageAssetPath(src_path): + """Rewrite the destination path of a locale asset for language-based splits. + + Should only be used when generating bundles with language-based splits. + This will rewrite paths that look like locales/<locale>.pak into + locales#<language>/<locale>.pak, where <language> is the language code + from the locale. + """ + if not src_path.startswith(_LOCALES_SUBDIR) or not src_path.endswith('.pak'): + return src_path + + locale = src_path[len(_LOCALES_SUBDIR):-4] + locale = resource_utils.CHROME_TO_ANDROID_LOCALE_MAP.get(locale, locale) + + # The locale format is <lang>-<region> or <lang>. Extract the language. + pos = locale.find('-') + if pos >= 0: + language = locale[:pos] + else: + language = locale + + if language == _FALLBACK_LANGUAGE: + return 'assets/locales/%s.pak' % locale + + return 'assets/locales#lang_%s/%s.pak' % (language, locale) + + +def _SplitModuleForAssetTargeting(src_module_zip, tmp_dir, split_dimensions): + """Splits assets in a module if needed. + + Args: + src_module_zip: input zip module path. + tmp_dir: Path to temporary directory, where the new output module might + be written to. + split_dimensions: list of split dimensions. + + Returns: + If the module doesn't need asset targeting, doesn't do anything and + returns src_module_zip. Otherwise, create a new module zip archive under + tmp_dir with the same file name, but which contains assets paths targeting + the proper dimensions. + """ + split_language = 'LANGUAGE' in split_dimensions + if not split_language: + # Nothing to target, so return original module path. + return src_module_zip + + with zipfile.ZipFile(src_module_zip, 'r') as src_zip: + language_files = [ + f for f in src_zip.namelist() if f.startswith(_LOCALES_SUBDIR)] + + if not language_files: + # Not language-based assets to split in this module. + return src_module_zip + + tmp_zip = os.path.join(tmp_dir, os.path.basename(src_module_zip)) + with zipfile.ZipFile(tmp_zip, 'w') as dst_zip: + for info in src_zip.infolist(): + src_path = info.filename + is_compressed = info.compress_type != zipfile.ZIP_STORED + + dst_path = src_path + if src_path in language_files: + dst_path = _RewriteLanguageAssetPath(src_path) + + build_utils.AddToZipHermetic(dst_zip, dst_path, + data=src_zip.read(src_path), + compress=is_compressed) + + return tmp_zip + + +def main(args): + args = build_utils.ExpandFileArgs(args) + options = _ParseArgs(args) + + # TODO(crbug.com/846633): Enable language-based configuration splits once + # Chromium detects the appropriate fallback locales when needed. + # split_dimensions = [ 'LANGUAGE' ] + split_dimensions = [] + + bundle_config = _GenerateBundleConfigJson(options.uncompressed_assets, + options.uncompress_shared_libraries, + split_dimensions) + with build_utils.TempDir() as tmp_dir: + module_zips = [ + _SplitModuleForAssetTargeting(module, tmp_dir, split_dimensions) \ + for module in options.module_zips] + + tmp_bundle = os.path.join(tmp_dir, 'tmp_bundle') + + tmp_unsigned_bundle = tmp_bundle + if options.keystore_path: + tmp_unsigned_bundle = tmp_bundle + '.unsigned' + + # Important: bundletool requires that the bundle config file is + # named with a .pb.json extension. + tmp_bundle_config = tmp_bundle + '.BundleConfig.pb.json' + + with open(tmp_bundle_config, 'w') as f: + f.write(bundle_config) + + cmd_args = ['java', '-jar', bundletool.BUNDLETOOL_JAR_PATH, 'build-bundle'] + cmd_args += ['--modules=%s' % ','.join(module_zips)] + cmd_args += ['--output=%s' % tmp_unsigned_bundle] + cmd_args += ['--config=%s' % tmp_bundle_config] + + build_utils.CheckOutput(cmd_args, print_stdout=True, print_stderr=True) + + if options.keystore_path: + # NOTE: As stated by the public documentation, apksigner cannot be used + # to sign the bundle (because it rejects anything that isn't an APK). + # The signature and digest algorithm selection come from the internal + # App Bundle documentation. There is no corresponding public doc :-( + signing_cmd_args = [ + 'jarsigner', '-sigalg', 'SHA256withRSA', '-digestalg', 'SHA-256', + '-keystore', 'file:' + options.keystore_path, + '-storepass' , options.keystore_password, + '-signedjar', tmp_bundle, + tmp_unsigned_bundle, + options.key_name, + ] + build_utils.CheckOutput(signing_cmd_args, print_stderr=True) + + shutil.move(tmp_bundle, options.out_bundle) + + +if __name__ == '__main__': + main(sys.argv[1:])
diff --git a/build/config/android/config.gni b/build/config/android/config.gni index cf0ecabfc..b919f18 100644 --- a/build/config/android/config.gni +++ b/build/config/android/config.gni
@@ -354,16 +354,11 @@ android_libcpp_lib_dir = "${android_libcpp_root}/libs/${android_app_abi}" } - # Dynamic app bundles ------------------------------------------------------- - declare_args() { # Location of aapt2 binary used for app bundles. For now, a more recent version # than the one distributed with the Android SDK is required. android_sdk_tools_bundle_aapt2 = "//third_party/android_build_tools/aapt2/aapt2" - - # Set this variable to true to enable building app bundles. - android_enable_app_bundles = false } }
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni index 3b158188..3bc9c8b7 100644 --- a/build/config/android/internal_rules.gni +++ b/build/config/android/internal_rules.gni
@@ -3331,3 +3331,87 @@ } } } + +# Create a zip archive corresponding to an application bundle module. +# +# Each module corresponds to the content of an existing android_apk() target +# except that the internal directory layout is slightly different, and +# resources as well as xml files are compiled into a protocol buffer format, +# instead of the regular binary xml + resources.arsc. +# +# A final application bundle is built from one or more module bundle modules, +# plus some configuration file. +# +# Variables: +# apk_target: Name of the android_apk target this module refers to. +# The archive will contain the same content, but organized slightly +# differently. +# +# module_path: Output module path. +# +template("android_app_bundle_module") { + _apk_target = invoker.apk_target + _apk_target_name = get_label_info(_apk_target, "name") + _apk_target_gen_dir = get_label_info(_apk_target, "target_gen_dir") + + _apk_build_config = "$_apk_target_gen_dir/${_apk_target_name}.build_config" + _rebased_apk_build_config = rebase_path(_apk_build_config, root_build_dir) + + action(target_name) { + forward_variables_from(invoker, + [ + "testonly", + "visibility", + ]) + script = "//build/android/gyp/apkbuilder.py" + depfile = "$target_gen_dir/$target_name.d" + + # NOTE: Building the APK is not necessary to build the bundle module, + # only its individual components, hence depend on their intermediate + # targets itself. This also allows building the APK and the bundle module + # in parallel if necessary. + deps = [ + "${_apk_target}__build_config", + "${_apk_target}__compile_proto_resources", + "${_apk_target}__create", # Required to get final dex zip. + "${_apk_target}__merge_manifests", + ] + + # NOTE: Compared to the inputs of the "package_apk" template action, + # this list is much smaller, since finalize_apk is never called + # by apkbuild.py --format=bundle-module. This means not using + # apksigner and zipalign as well, nor the keystore. Other + # dependencies like extra native libraries are all pulled from the + # .build_config through @FileArg() references (see below) and + # will be listed in the generated depfile instead. + inputs = build_utils_py + [ _apk_build_config ] + outputs = [ + invoker.module_path, + ] + args = [ + "--depfile", + rebase_path(depfile, root_build_dir), + "--format=bundle-module", + "--output-apk", + rebase_path(invoker.module_path, root_build_dir), + "--dex-file=@FileArg($_rebased_apk_build_config:final_dex:path)", + "--resource-apk=@FileArg(" + + "$_rebased_apk_build_config:deps_info:proto_resources_path)", + "--assets=@FileArg($_rebased_apk_build_config:assets)", + "--uncompressed-assets=@FileArg(" + + "$_rebased_apk_build_config:uncompressed_assets)", + "--native-libs=@FileArg($_rebased_apk_build_config:native:libraries)", + "--native-libs=@FileArg($_rebased_apk_build_config:native:extra_shared_libraries)", + "--android-abi=$android_app_abi", + "--uncompress-shared-libraries=@FileArg(" + + "$_rebased_apk_build_config:native:uncompress_shared_libraries)", + ] + if (defined(android_app_secondary_abi)) { + args += [ + "--secondary-native-libs=@FileArg(" + + "$_rebased_apk_build_config:native:secondary_abi_libraries)", + "--secondary-android-abi=$android_app_secondary_abi", + ] + } + } +}
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni index e6a50b4..c5993fc 100644 --- a/build/config/android/rules.gni +++ b/build/config/android/rules.gni
@@ -2170,19 +2170,17 @@ _compile_resources_target = "${_template_name}__compile_resources" - if (android_enable_app_bundles) { - # Path to the intermediate proto-format resources zip file. - _packaged_proto_resources_path = - "$root_gen_dir/proto_resources/" + - rebase_path(_final_apk_path_no_ext, root_build_dir) + ".proto.ap_" + # Path to the intermediate proto-format resources zip file. + _packaged_proto_resources_path = + "$root_gen_dir/proto_resources/" + + rebase_path(_final_apk_path_no_ext, root_build_dir) + ".proto.ap_" - # Define another target used to generate an archive containing the - # resources compiled in protocol buffer format. This is not used by - # the APK itself, but by android_bundle_module() targets that depend - # on it. - _compile_proto_resources_target = - "${_template_name}__compile_proto_resources" - } + # Define another target used to generate an archive containing the + # resources compiled in protocol buffer format. This is not used by + # the APK itself, but by android_bundle_module() targets that depend + # on it. + _compile_proto_resources_target = + "${_template_name}__compile_proto_resources" compile_apk_resources(_compile_resources_target) { forward_variables_from(invoker, @@ -2237,10 +2235,8 @@ ] } - if (android_enable_app_bundles) { - proto_output = _packaged_proto_resources_path - proto_resources_target = _compile_proto_resources_target - } + proto_output = _packaged_proto_resources_path + proto_resources_target = _compile_proto_resources_target } _srcjar_deps += [ ":$_compile_resources_target" ] @@ -2380,9 +2376,7 @@ final_dex_path = _final_dex_path apk_path = _final_apk_path - if (android_enable_app_bundles) { - proto_resources_path = _packaged_proto_resources_path - } + proto_resources_path = _packaged_proto_resources_path incremental_allowed = _incremental_allowed incremental_apk_path = "${_final_apk_path_no_ext}_incremental.apk" @@ -3469,6 +3463,219 @@ } } } + + # Create an Android application bundle from one base android_apk target, + # and zero or more associated android_apk. + # + # Variables: + # base_apk_target: Name of the android_apk target corresponding to the + # base module for this application bundle. The bundle file will include + # the same content in its base module, though in a slightly different + # format. + # + # extra_modules: Optional list of scopes, one per extra module used by + # this bundle. Each scope must have a 'name' field that specifies the + # module name (which cannot be 'base', since this is reserved for the + # base module), and an 'apk_target' field that specified the + # corresponding android_apk target name the module is modeled on. + # + # extra_module_apk_targets: Optional list of android_apk target matching + # the names listed in extra_module_names. + # + # generate_apks: Optional. If true, generate an .apks archive that + # contains all generated APK splits from the bundle. These are + # installable to a local device using the bundletool 'install-apks' + # command. + # + # NOTE: This creates a new target with the name "${target_name}_apks" + # + # sign_bundle: Optional. If true, sign the bundle. Default is false + # because signing is very slow, and there is no reason to do it + # unless one wants to upload the bundle to the Play Store (e.g. + # for official builds). + # + # keystore_path: optional keystore path, used only when generating APKs. + # keystore_name: optional keystore name, used only when generating APKs. + # keystore_password: optional keystore password, used only when + # generating APKs. + # + # Example: + # android_app_bundle("chrome_public_bundle") { + # base_apk_target = "//chrome/android:chrome_public_apk" + # extra_modules = [ + # { # NOTE: Scopes require one field per line, and no comma separators. + # name = "my_module" + # apk_target = ":my_module_apk" + # }, + # ] + # } + # + template("android_app_bundle") { + _all_modules = [ + { + name = "base" + apk_target = invoker.base_apk_target + }, + ] + + if (defined(invoker.extra_modules)) { + _module_count = 0 + foreach(_module, invoker.extra_modules) { + _module_count += 1 + assert(defined(_module.name), + "Missing 'name' field for extra module #${_module_count}.") + assert(_module.name != "base", + "Module name 'base' is reserved for the main bundle module") + assert(defined(_module.apk_target), + "Missing 'apk_target' field for extra module ${_module.name}.") + } + _all_modules += invoker.extra_modules + } + + # Generate one module .zip file per APK. + _all_module_targets = [] + _all_module_paths = [] + _all_module_build_configs = [] + foreach(_module, _all_modules) { + # Important: the bundle tool uses the module's zip filename as + # the internal module name inside the final bundle, in other words, + # this file *must* be named ${_module.name}.zip + _module_target = "${target_name}__module__${_module.name}" + _module_path = "$target_gen_dir/$target_name/${_module.name}.zip" + _apk_target = _module.apk_target + _apk_build_config_target = "${_apk_target}__build_config" + + android_app_bundle_module(_module_target) { + apk_target = _apk_target + module_path = _module_path + } + + # Determine the rebased path to the module's target .build_config + # In order to pass its list of uncompressed assets later. + _apk_target_name = get_label_info(_apk_target, "name") + _apk_target_gen_dir = get_label_info(_apk_target, "target_gen_dir") + _apk_build_config = + "$_apk_target_gen_dir/${_apk_target_name}.build_config" + + _all_module_targets += [ + ":$_module_target", + _apk_build_config_target, + ] + _all_module_paths += [ _module_path ] + _all_module_build_configs += [ _apk_build_config ] + } + + _all_rebased_module_paths = rebase_path(_all_module_paths, root_build_dir) + + _bundle_path = "$target_gen_dir/$target_name.aab" + _rebased_bundle_path = rebase_path(_bundle_path, root_build_dir) + + _sign_bundle = defined(invoker.sign_bundle) && invoker.sign_bundle + _generate_apks = defined(invoker.generate_apks) && invoker.generate_apks + + if (_sign_bundle || _generate_apks) { + _keystore_path = android_keystore_path + _keystore_password = android_keystore_password + _keystore_name = android_keystore_name + + if (defined(invoker.keystore_path)) { + _keystore_path = invoker.keystore_path + _keystore_password = invoker.keystore_password + _keystore_name = invoker.keystore_name + } + + _rebased_keystore_path = rebase_path(_keystore_path, root_build_dir) + + if (_sign_bundle) { + # For now, the same keys are used to sign the bundle and the set of + # generated APKs. In the future, signing the bundle may require a + # different set of keys. + _bundle_keystore_name = _keystore_name + } + } + + # NOTE: Keep this consistent with the imports of create_app_bundle.py + _create_app_bundle_py_imports = + build_utils_py + [ + "//build/android/gyp/util/resource_utils.py", + "//build/android/gyp/bundletool.py", + ] + + _bundle_target_name = target_name + action(_bundle_target_name) { + script = "//build/android/gyp/create_app_bundle.py" + inputs = _all_module_paths + _all_module_build_configs + + _create_app_bundle_py_imports + outputs = [ + _bundle_path, + ] + deps = _all_module_targets + args = [ + "--out-bundle=$_rebased_bundle_path", + "--module-zips=$_all_rebased_module_paths", + ] + if (_sign_bundle) { + args += [ + "--keystore-path", + _rebased_keystore_path, + "--keystore-password", + _keystore_password, + "--key-name", + _bundle_keystore_name, + ] + } + foreach(build_config, _all_module_build_configs) { + _rebased_build_config = rebase_path(build_config, root_build_dir) + args += [ + "--uncompressed-assets=@FileArg(" + + "$_rebased_build_config:uncompressed_assets)", + "--uncompress-shared-libraries=@FileArg(" + + "$_rebased_build_config:native:uncompress_shared_libraries)", + ] + } + } + + if (_generate_apks) { + _android_aapt2_path = android_sdk_tools_bundle_aapt2 + + _bundle_apks_target = "${target_name}_apks" + _bundle_apks_path = "$target_gen_dir/$target_name.apks" + + # NOTE: Keep this consistent with the imports of app_bundle_to_apks.py + # note that resource_utils.py imports build_utils.py + _app_bundle_to_apks_py_imports = + build_utils_py + [ "//build/android/gyp/bundletool.py" ] + + action(_bundle_apks_target) { + script = "//build/android/gyp/app_bundle_to_apks.py" + inputs = _app_bundle_to_apks_py_imports + [ + _bundle_path, + _android_aapt2_path, + _keystore_path, + ] + outputs = [ + _bundle_apks_path, + ] + deps = [ + ":$_bundle_target_name", + ] + args = [ + "--aapt2", + rebase_path(_android_aapt2_path, root_build_dir), + "--bundle", + _rebased_bundle_path, + "--out-zip", + rebase_path(_bundle_apks_path, root_build_dir), + "--keystore-path", + _rebased_keystore_path, + "--keystore-password", + _keystore_password, + "--key-name", + _keystore_name, + ] + } + } + } } # Compatibility wrapper to toggle android_deps usage for a dependency.
diff --git a/build/whitespace_file.txt b/build/whitespace_file.txt index bd3bd32..0646a9f 100644 --- a/build/whitespace_file.txt +++ b/build/whitespace_file.txt
@@ -117,6 +117,8 @@ I'm here to commit lines and drop rhymes * This is a line to test and try uploading a cl. +* +Yay, another first commit! What a beautiful day! And lo, in the year 2014, there was verily an attempt to upgrade to GCC 4.8 on the Android bots, and it was good. Except on one bot, where it was bad. And
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index e0a43dc..99ad70f 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -228,13 +228,13 @@ "//components/autofill/android:autofill_java", "//components/background_task_scheduler:background_task_scheduler_java", "//components/bookmarks/common/android:bookmarks_java", - "//components/content_view:content_view_java", "//components/crash/android:java", "//components/dom_distiller/content/browser/android:dom_distiller_content_java", "//components/dom_distiller/core/android:dom_distiller_core_java", "//components/download/internal/background_service:internal_java", "//components/download/public/background_service:public_java", "//components/download/public/common:public_java", + "//components/embedder_support/android:content_view_java", "//components/embedder_support/android:media_java", "//components/feature_engagement:feature_engagement_java", "//components/gcm_driver/android:gcm_driver_java", @@ -1460,3 +1460,23 @@ ] } } + +# Generate application bundles if possible. +android_app_bundle("chrome_public_bundle") { + base_apk_target = ":chrome_public_apk" + + # Signing is very slow, only do that for official builds. + sign_bundle = is_official_build + + # To ease local testing, also generate the .apks archive containing split + # APKs for this bundle. + generate_apks = true +} + +android_app_bundle("chrome_modern_public_bundle") { + base_apk_target = ":chrome_modern_public_apk" +} + +android_app_bundle("monochrome_public_bundle") { + base_apk_target = ":monochrome_public_apk" +}
diff --git a/chrome/android/java/DEPS b/chrome/android/java/DEPS index bc3f3c4..088d9da 100644 --- a/chrome/android/java/DEPS +++ b/chrome/android/java/DEPS
@@ -3,7 +3,6 @@ "+components/autofill/android/java/src/org/chromium/components/autofill", "+components/background_task_scheduler/android/java/src/org/chromium/components/background_task_scheduler", "+components/bookmarks/common/android/java/src/org/chromium/components/bookmarks", - "+components/content_view", "+components/crash/android/java", "+components/dom_distiller/content/browser/android/java/src/org/chromium/components/dom_distiller/content", "+components/dom_distiller/core/android/java/src/org/chromium/components/dom_distiller/core",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/BackgroundSyncLauncher.java b/chrome/android/java/src/org/chromium/chrome/browser/BackgroundSyncLauncher.java index 918421961..9622b7f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/BackgroundSyncLauncher.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/BackgroundSyncLauncher.java
@@ -6,13 +6,13 @@ import android.content.Context; import android.content.SharedPreferences; -import android.os.AsyncTask; import android.os.StrictMode; import com.google.android.gms.gcm.GcmNetworkManager; import com.google.android.gms.gcm.OneoffTask; import com.google.android.gms.gcm.Task; +import org.chromium.base.AsyncTask; import org.chromium.base.ContextUtils; import org.chromium.base.Log; import org.chromium.base.VisibleForTesting;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/DefaultBrowserInfo.java b/chrome/android/java/src/org/chromium/chrome/browser/DefaultBrowserInfo.java index dfbe8e9..9e1f921 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/DefaultBrowserInfo.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/DefaultBrowserInfo.java
@@ -10,10 +10,10 @@ import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.net.Uri; -import android.os.AsyncTask; import android.support.annotation.IntDef; import android.text.TextUtils; +import org.chromium.base.AsyncTask; import org.chromium.base.BuildInfo; import org.chromium.base.ContextUtils; import org.chromium.base.library_loader.LibraryProcessType;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/SSLClientCertificateRequest.java b/chrome/android/java/src/org/chromium/chrome/browser/SSLClientCertificateRequest.java index 26e80db..b58d860 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/SSLClientCertificateRequest.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/SSLClientCertificateRequest.java
@@ -9,13 +9,13 @@ import android.content.ActivityNotFoundException; import android.content.Context; import android.content.DialogInterface.OnClickListener; -import android.os.AsyncTask; import android.security.KeyChain; import android.security.KeyChainAliasCallback; import android.security.KeyChainException; import android.support.v7.app.AlertDialog; import android.util.Log; +import org.chromium.base.AsyncTask; import org.chromium.base.ThreadUtils; import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.CalledByNative;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ShortcutHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/ShortcutHelper.java index 3eb9f8b..9e0067a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ShortcutHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ShortcutHelper.java
@@ -24,12 +24,12 @@ import android.graphics.drawable.Drawable; import android.graphics.drawable.Icon; import android.net.Uri; -import android.os.AsyncTask; import android.os.Build; import android.text.TextUtils; import android.util.Base64; import org.chromium.base.ApiCompatibilityUtils; +import org.chromium.base.AsyncTask; import org.chromium.base.CollectionUtil; import org.chromium.base.ContextUtils; import org.chromium.base.Log;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/TtsPlatformImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/TtsPlatformImpl.java index 24f6a47..b40bcb9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/TtsPlatformImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/TtsPlatformImpl.java
@@ -4,11 +4,11 @@ package org.chromium.chrome.browser; -import android.os.AsyncTask; import android.os.Build; import android.speech.tts.TextToSpeech; import android.speech.tts.UtteranceProgressListener; +import org.chromium.base.AsyncTask; import org.chromium.base.ContextUtils; import org.chromium.base.ThreadUtils; import org.chromium.base.TraceEvent;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/WarmupManager.java b/chrome/android/java/src/org/chromium/chrome/browser/WarmupManager.java index 0c068a3..bedaf26 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/WarmupManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/WarmupManager.java
@@ -7,7 +7,6 @@ import android.annotation.SuppressLint; import android.content.Context; import android.net.Uri; -import android.os.AsyncTask; import android.os.SystemClock; import android.view.ContextThemeWrapper; import android.view.InflateException; @@ -17,6 +16,7 @@ import android.view.ViewStub; import android.widget.FrameLayout; +import org.chromium.base.AsyncTask; import org.chromium.base.Log; import org.chromium.base.StrictModeContext; import org.chromium.base.SysUtils;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskPrompt.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskPrompt.java index f1cf7955..aab7d2e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskPrompt.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/CardUnmaskPrompt.java
@@ -10,7 +10,6 @@ import android.graphics.ColorFilter; import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; -import android.os.AsyncTask; import android.os.Build; import android.os.Handler; import android.support.annotation.IntDef; @@ -36,6 +35,7 @@ import android.widget.TextView; import org.chromium.base.ApiCompatibilityUtils; +import org.chromium.base.AsyncTask; import org.chromium.base.VisibleForTesting; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeActivity;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browseractions/BrowserActionsCustomContextMenuItem.java b/chrome/android/java/src/org/chromium/chrome/browser/browseractions/BrowserActionsCustomContextMenuItem.java index 49672ce..612c71b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/browseractions/BrowserActionsCustomContextMenuItem.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/browseractions/BrowserActionsCustomContextMenuItem.java
@@ -9,11 +9,11 @@ import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.net.Uri; -import android.os.AsyncTask; import android.support.annotation.IdRes; import android.support.customtabs.browseractions.BrowserActionItem; import android.support.customtabs.browseractions.BrowserServiceImageReadTask; +import org.chromium.base.AsyncTask; import org.chromium.base.Callback; import org.chromium.base.VisibleForTesting; import org.chromium.chrome.browser.contextmenu.ContextMenuItem;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browseractions/BrowserActionsTabModelSelector.java b/chrome/android/java/src/org/chromium/chrome/browser/browseractions/BrowserActionsTabModelSelector.java index 0008f3c..e8fed5d8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/browseractions/BrowserActionsTabModelSelector.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/browseractions/BrowserActionsTabModelSelector.java
@@ -4,8 +4,7 @@ package org.chromium.chrome.browser.browseractions; -import android.os.AsyncTask; - +import org.chromium.base.AsyncTask; import org.chromium.base.Callback; import org.chromium.base.ThreadUtils; import org.chromium.chrome.browser.ChromeActivity;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelContent.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelContent.java index 520a5db..11af753 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelContent.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelContent.java
@@ -19,7 +19,7 @@ import org.chromium.chrome.browser.contextualsearch.ContextualSearchManager; import org.chromium.chrome.browser.externalnav.ExternalNavigationHandler; import org.chromium.chrome.browser.tab.Tab; -import org.chromium.components.content_view.ContentView; +import org.chromium.components.embedder_support.view.ContentView; import org.chromium.components.navigation_interception.InterceptNavigationDelegate; import org.chromium.components.navigation_interception.NavigationParams; import org.chromium.components.web_contents_delegate_android.WebContentsDelegateAndroid;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/cookies/CookiesFetcher.java b/chrome/android/java/src/org/chromium/chrome/browser/cookies/CookiesFetcher.java index 92338b0f..e07ef5b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/cookies/CookiesFetcher.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/cookies/CookiesFetcher.java
@@ -4,8 +4,7 @@ package org.chromium.chrome.browser.cookies; -import android.os.AsyncTask; - +import org.chromium.base.AsyncTask; import org.chromium.base.ContextUtils; import org.chromium.base.ImportantFileWriterAndroid; import org.chromium.base.Log;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/crypto/CipherFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/crypto/CipherFactory.java index 613cd5cd..1a16c29d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/crypto/CipherFactory.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/crypto/CipherFactory.java
@@ -5,9 +5,9 @@ package org.chromium.chrome.browser.crypto; import android.annotation.SuppressLint; -import android.os.AsyncTask; import android.os.Bundle; +import org.chromium.base.AsyncTask; import org.chromium.base.Log; import org.chromium.base.ObserverList; import org.chromium.base.SecureRandomInitializer;
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 e1cf797..1afd25e 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
@@ -360,11 +360,13 @@ if (!ChromeFeatureList.isEnabled(ChromeFeatureList.CCT_MODULE)) { Log.w(TAG, "The %s feature is disabled.", ChromeFeatureList.CCT_MODULE); + ModuleMetrics.recordLoadResult(ModuleMetrics.LOAD_RESULT_FEATURE_DISABLED); return; } if (!ExternalAuthUtils.getInstance().isGoogleSigned(packageName)) { Log.w(TAG, "The %s package is not Google-signed.", packageName); + ModuleMetrics.recordLoadResult(ModuleMetrics.LOAD_RESULT_NOT_GOOGLE_SIGNED); return; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabTabPersistencePolicy.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabTabPersistencePolicy.java index ef26ebd8..21656f3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabTabPersistencePolicy.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabTabPersistencePolicy.java
@@ -5,13 +5,13 @@ package org.chromium.chrome.browser.customtabs; import android.app.Activity; -import android.os.AsyncTask; import android.os.StrictMode; import android.util.Pair; import android.util.SparseBooleanArray; import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.ApplicationStatus; +import org.chromium.base.AsyncTask; import org.chromium.base.Callback; import org.chromium.base.Log; import org.chromium.base.StreamUtil;
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 8b0fd72..bb22557c 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
@@ -55,6 +55,7 @@ import org.chromium.chrome.browser.browserservices.PostMessageHandler; import org.chromium.chrome.browser.customtabs.dynamicmodule.ModuleEntryPoint; import org.chromium.chrome.browser.customtabs.dynamicmodule.ModuleLoader; +import org.chromium.chrome.browser.customtabs.dynamicmodule.ModuleMetrics; import org.chromium.chrome.browser.device.DeviceClassManager; import org.chromium.chrome.browser.init.ChainedTasks; import org.chromium.chrome.browser.init.ChromeBrowserInitializer; @@ -1434,12 +1435,16 @@ throw new IllegalStateException("Only one module can be loaded at a time."); } mModuleUseCount++; + ModuleMetrics.recordLoadResult(ModuleMetrics.LOAD_RESULT_SUCCESS_CACHED); return mModuleEntryPoint; } mModuleNames = new Pair<>(packageName, className); mModuleEntryPoint = ModuleLoader.loadModule(packageName, className); - if (mModuleEntryPoint != null) mModuleUseCount++; + if (mModuleEntryPoint != null) { + mModuleUseCount++; + ModuleMetrics.recordLoadResult(ModuleMetrics.LOAD_RESULT_SUCCESS_NEW); + } return mModuleEntryPoint; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/RequestThrottler.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/RequestThrottler.java index 9d8f180..7de28a1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/RequestThrottler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/RequestThrottler.java
@@ -7,11 +7,11 @@ import android.annotation.SuppressLint; import android.content.Context; import android.content.SharedPreferences; -import android.os.AsyncTask; import android.os.SystemClock; import android.text.TextUtils; import android.util.SparseArray; +import org.chromium.base.AsyncTask; import org.chromium.base.VisibleForTesting; import java.util.Map;
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 7c4b7de5..04cfcc2f 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
@@ -54,14 +54,20 @@ + "minimum required entry point version %s.", moduleHost.getHostVersion(), entryPoint.getMinimumHostVersion(), entryPoint.getModuleVersion(), moduleHost.getMinimumModuleVersion()); + ModuleMetrics.recordLoadResult(ModuleMetrics.LOAD_RESULT_INCOMPATIBLE_VERSION); return null; } entryPoint.init(moduleHost); return entryPoint; - } catch (Exception e) { // No multi-catch below API level 19 for reflection exceptions. - Log.e(TAG, "Could not create entry point using package name %s and class name %s", - packageName, className, e); + } catch (ClassNotFoundException e) { + Log.e(TAG, "Could not find class %", className, e); + ModuleMetrics.recordLoadResult(ModuleMetrics.LOAD_RESULT_CLASS_NOT_FOUND_EXCEPTION); + } catch (Exception e) { + // No multi-catch below API level 19 for reflection exceptions. + // This catches InstantiationException and IllegalAccessException. + Log.e(TAG, "Could not instantiate class %", className, e); + ModuleMetrics.recordLoadResult(ModuleMetrics.LOAD_RESULT_INSTANTIATION_EXCEPTION); } return null; } @@ -78,6 +84,8 @@ return moduleContext; } catch (PackageManager.NameNotFoundException e) { Log.e(TAG, "Could not create package context for %s", packageName, e); + ModuleMetrics.recordLoadResult( + ModuleMetrics.LOAD_RESULT_PACKAGE_NAME_NOT_FOUND_EXCEPTION); } return null; } @@ -86,4 +94,4 @@ return entryPoint.getModuleVersion() >= moduleHost.getMinimumModuleVersion() && moduleHost.getHostVersion() >= entryPoint.getMinimumHostVersion(); } -} \ No newline at end of file +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ModuleMetrics.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ModuleMetrics.java index 30e8e39..b7a9324 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ModuleMetrics.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/dynamicmodule/ModuleMetrics.java
@@ -5,9 +5,13 @@ package org.chromium.chrome.browser.customtabs.dynamicmodule; import android.os.SystemClock; +import android.support.annotation.IntDef; +import org.chromium.base.Log; import org.chromium.base.metrics.RecordHistogram; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.concurrent.TimeUnit; /** @@ -16,6 +20,61 @@ public final class ModuleMetrics { private ModuleMetrics() {} + private static final String TAG = "ModuleMetrics"; + + /** + * Possible results when loading a dynamic module. Keep in sync with the + * CustomTabs.DynamicModule.LoadResult enum in histograms.xml. Do not remove or change existing + * values other than LOAD_RESULT_BOUNDARY. + */ + @IntDef({LOAD_RESULT_SUCCESS_NEW, LOAD_RESULT_SUCCESS_CACHED, LOAD_RESULT_FEATURE_DISABLED, + LOAD_RESULT_NOT_GOOGLE_SIGNED, LOAD_RESULT_PACKAGE_NAME_NOT_FOUND_EXCEPTION, + LOAD_RESULT_CLASS_NOT_FOUND_EXCEPTION, LOAD_RESULT_INSTANTIATION_EXCEPTION, + LOAD_RESULT_INCOMPATIBLE_VERSION}) + @Retention(RetentionPolicy.SOURCE) + public @interface LoadResult {} + + /** A new instance of the module was loaded successfully. */ + public static final int LOAD_RESULT_SUCCESS_NEW = 0; + + /** A cached instance of the module was used. */ + public static final int LOAD_RESULT_SUCCESS_CACHED = 1; + + /** The module could not be loaded because the feature is disabled. */ + public static final int LOAD_RESULT_FEATURE_DISABLED = 2; + + /** The module could not be loaded because the package is not Google-signed. */ + public static final int LOAD_RESULT_NOT_GOOGLE_SIGNED = 3; + + /** The module could not be loaded because the package name could not be found. */ + public static final int LOAD_RESULT_PACKAGE_NAME_NOT_FOUND_EXCEPTION = 4; + + /** The module could not be loaded because the entry point class could not be found. */ + public static final int LOAD_RESULT_CLASS_NOT_FOUND_EXCEPTION = 5; + + /** The module could not be loaded because the entry point class could not be instantiated. */ + public static final int LOAD_RESULT_INSTANTIATION_EXCEPTION = 6; + + /** The module was loaded but the host and module versions are incompatible. */ + public static final int LOAD_RESULT_INCOMPATIBLE_VERSION = 7; + + /** Upper bound for legal sample values - all sample values have to be strictly lower. */ + private static final int LOAD_RESULT_BOUNDARY = 8; + + /** + * Records the result of attempting to load a dynamic module. + * @param result result key, one of {@link LoadResult}'s values. + */ + public static void recordLoadResult(@LoadResult int result) { + assert result >= 0; + assert result < LOAD_RESULT_BOUNDARY; + RecordHistogram.recordEnumeratedHistogram( + "CustomTabs.DynamicModule.LoadResult", result, LOAD_RESULT_BOUNDARY); + if (result != LOAD_RESULT_SUCCESS_NEW && result != LOAD_RESULT_SUCCESS_CACHED) { + Log.w(TAG, "Did not load module, result: %s", result); + } + } + /** * SystemClock.uptimeMillis() is used here as it uses the same system call as all the native * side of Chrome, and this is the same clock used for page load metrics.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/ChromeDownloadDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/download/ChromeDownloadDelegate.java index 1297948..2179184 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/ChromeDownloadDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/ChromeDownloadDelegate.java
@@ -9,13 +9,13 @@ import android.content.Context; import android.content.pm.PackageManager; import android.net.Uri; -import android.os.AsyncTask; import android.os.Environment; import android.text.TextUtils; import android.util.Pair; import android.webkit.MimeTypeMap; import android.webkit.URLUtil; +import org.chromium.base.AsyncTask; import org.chromium.base.Log; import org.chromium.base.ThreadUtils; import org.chromium.base.annotations.CalledByNative;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerDelegate.java index f623f65..aa15cee 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerDelegate.java
@@ -9,12 +9,12 @@ import android.content.SharedPreferences; import android.database.Cursor; import android.net.Uri; -import android.os.AsyncTask; import android.os.Build; import android.os.Environment; import android.support.v4.app.NotificationManagerCompat; import android.text.TextUtils; +import org.chromium.base.AsyncTask; import org.chromium.base.ContextUtils; import org.chromium.base.Log; import org.chromium.base.StrictModeContext;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java index 35556cad..e83f185 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadManagerService.java
@@ -13,13 +13,13 @@ import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.Uri; -import android.os.AsyncTask; import android.os.Handler; import android.support.annotation.Nullable; import android.text.TextUtils; import android.util.Pair; import org.chromium.base.ApiCompatibilityUtils; +import org.chromium.base.AsyncTask; import org.chromium.base.Callback; import org.chromium.base.ContextUtils; import org.chromium.base.Log;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/OMADownloadHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/download/OMADownloadHandler.java index cc758de..84aa906 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/OMADownloadHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/OMADownloadHandler.java
@@ -15,7 +15,6 @@ import android.content.pm.PackageManager; import android.database.Cursor; import android.net.Uri; -import android.os.AsyncTask; import android.os.Environment; import android.os.ParcelFileDescriptor; import android.provider.Browser; @@ -34,6 +33,7 @@ import org.xmlpull.v1.XmlPullParserFactory; import org.chromium.base.ApplicationStatus; +import org.chromium.base.AsyncTask; import org.chromium.base.ContextUtils; import org.chromium.base.VisibleForTesting; import org.chromium.chrome.R;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/glue/FileDeletionQueue.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/glue/FileDeletionQueue.java index 0f429e8..3afdd20 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/glue/FileDeletionQueue.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/glue/FileDeletionQueue.java
@@ -4,9 +4,9 @@ package org.chromium.chrome.browser.download.home.glue; -import android.os.AsyncTask; import android.support.annotation.VisibleForTesting; +import org.chromium.base.AsyncTask; import org.chromium.base.Callback; import org.chromium.base.FileUtils; @@ -93,4 +93,4 @@ private static final FileDeletionQueue INSTANCE = new FileDeletionQueue(file -> FileUtils.recursivelyDeleteFile(file)); } -} \ No newline at end of file +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/CalendarFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/CalendarFactory.java index 10a4bb7..4b3d984 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/CalendarFactory.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/CalendarFactory.java
@@ -4,7 +4,7 @@ package org.chromium.chrome.browser.download.home.list; -import android.os.AsyncTask; +import org.chromium.base.AsyncTask; import java.util.Calendar; import java.util.concurrent.ExecutionException;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadManagerUi.java b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadManagerUi.java index 59739ddc..e3866ff 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadManagerUi.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadManagerUi.java
@@ -7,7 +7,6 @@ import android.app.Activity; import android.content.ComponentName; import android.content.Intent; -import android.os.AsyncTask; import android.os.Handler; import android.support.annotation.IntDef; import android.support.graphics.drawable.VectorDrawableCompat; @@ -19,6 +18,7 @@ import android.view.View; import android.view.ViewGroup; +import org.chromium.base.AsyncTask; import org.chromium.base.Callback; import org.chromium.base.CollectionUtil; import org.chromium.base.DiscardableReferencePool;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/SpaceDisplay.java b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/SpaceDisplay.java index cfa0156..fb3ab96b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/SpaceDisplay.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/SpaceDisplay.java
@@ -5,7 +5,6 @@ package org.chromium.chrome.browser.download.ui; import android.content.Context; -import android.os.AsyncTask; import android.os.Environment; import android.os.StatFs; import android.support.v7.widget.RecyclerView; @@ -15,6 +14,7 @@ import android.widget.TextView; import org.chromium.base.ApiCompatibilityUtils; +import org.chromium.base.AsyncTask; import org.chromium.base.Callback; import org.chromium.base.ContextUtils; import org.chromium.base.Log;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/StorageSummary.java b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/StorageSummary.java index 513023a..2a55518 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/StorageSummary.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/StorageSummary.java
@@ -5,11 +5,11 @@ package org.chromium.chrome.browser.download.ui; import android.content.Context; -import android.os.AsyncTask; import android.os.Environment; import android.view.View; import android.widget.TextView; +import org.chromium.base.AsyncTask; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.download.DirectoryOption;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/externalnav/IntentWithGesturesHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/externalnav/IntentWithGesturesHandler.java index 983e38a..60e13c8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/externalnav/IntentWithGesturesHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/externalnav/IntentWithGesturesHandler.java
@@ -6,8 +6,8 @@ import android.annotation.SuppressLint; import android.content.Intent; -import android.os.AsyncTask; +import org.chromium.base.AsyncTask; import org.chromium.base.Log; import org.chromium.base.SecureRandomInitializer; import org.chromium.chrome.browser.IntentHandler;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/feedback/AsyncFeedbackSourceAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/feedback/AsyncFeedbackSourceAdapter.java index 171ea66..dae4a74d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/feedback/AsyncFeedbackSourceAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/feedback/AsyncFeedbackSourceAdapter.java
@@ -5,9 +5,9 @@ package org.chromium.chrome.browser.feedback; import android.content.Context; -import android.os.AsyncTask; -import android.os.AsyncTask.Status; +import org.chromium.base.AsyncTask; +import org.chromium.base.AsyncTask.Status; import org.chromium.base.ContextUtils; import java.util.concurrent.ExecutionException;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/feedback/ConnectivityChecker.java b/chrome/android/java/src/org/chromium/chrome/browser/feedback/ConnectivityChecker.java index 8685496..d4dd0ee4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/feedback/ConnectivityChecker.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/feedback/ConnectivityChecker.java
@@ -4,8 +4,7 @@ package org.chromium.chrome.browser.feedback; -import android.os.AsyncTask; - +import org.chromium.base.AsyncTask; import org.chromium.base.Log; import org.chromium.base.ThreadUtils; import org.chromium.base.VisibleForTesting;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/DuplicateDownloadInfoBar.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/DuplicateDownloadInfoBar.java index ecbc217..fe6d61e7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/DuplicateDownloadInfoBar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/DuplicateDownloadInfoBar.java
@@ -8,7 +8,6 @@ import android.content.Intent; import android.graphics.Typeface; import android.net.Uri; -import android.os.AsyncTask; import android.text.Spannable; import android.text.SpannableString; import android.text.TextUtils; @@ -17,6 +16,7 @@ import android.view.View; import android.webkit.MimeTypeMap; +import org.chromium.base.AsyncTask; import org.chromium.base.ContextUtils; import org.chromium.base.annotations.CalledByNative; import org.chromium.chrome.R;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/AsyncInitTaskRunner.java b/chrome/android/java/src/org/chromium/chrome/browser/init/AsyncInitTaskRunner.java index d4fdc260..42fdd55 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/init/AsyncInitTaskRunner.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/init/AsyncInitTaskRunner.java
@@ -4,8 +4,7 @@ package org.chromium.chrome.browser.init; -import android.os.AsyncTask; - +import org.chromium.base.AsyncTask; import org.chromium.base.Callback; import org.chromium.base.ContextUtils; import org.chromium.base.ThreadUtils;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java b/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java index be7cc4b..d9455e1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java
@@ -6,7 +6,6 @@ import android.app.Activity; import android.content.Context; -import android.os.AsyncTask; import android.os.Build; import android.os.Handler; import android.os.Looper; @@ -18,6 +17,7 @@ import org.chromium.base.ActivityState; import org.chromium.base.ApplicationStatus; import org.chromium.base.ApplicationStatus.ActivityStateListener; +import org.chromium.base.AsyncTask; import org.chromium.base.CommandLine; import org.chromium.base.ContentUriUtils; import org.chromium.base.ContextUtils;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java index 9c27aa6..7d215fb3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java
@@ -8,7 +8,6 @@ import android.app.Activity; import android.content.Context; import android.content.SharedPreferences; -import android.os.AsyncTask; import android.os.Build; import android.os.SystemClock; import android.support.annotation.WorkerThread; @@ -20,6 +19,7 @@ import com.google.ipc.invalidation.external.client.android.service.AndroidLogger; import org.chromium.base.ApiCompatibilityUtils; +import org.chromium.base.AsyncTask; import org.chromium.base.CommandLine; import org.chromium.base.ContextUtils; import org.chromium.base.Log;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/installedapp/InstalledAppProviderImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/installedapp/InstalledAppProviderImpl.java index 7f911e5..48c6d3d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/installedapp/InstalledAppProviderImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/installedapp/InstalledAppProviderImpl.java
@@ -9,13 +9,13 @@ import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Resources; -import android.os.AsyncTask; import android.util.Pair; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import org.chromium.base.AsyncTask; import org.chromium.base.Log; import org.chromium.base.ThreadUtils; import org.chromium.base.VisibleForTesting;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/invalidation/DelayedInvalidationsController.java b/chrome/android/java/src/org/chromium/chrome/browser/invalidation/DelayedInvalidationsController.java index 55068e4..f246903 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/invalidation/DelayedInvalidationsController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/invalidation/DelayedInvalidationsController.java
@@ -8,11 +8,11 @@ import android.content.ContentResolver; import android.content.Context; import android.content.SharedPreferences; -import android.os.AsyncTask; import android.os.Bundle; import android.support.v4.util.ObjectsCompat; import org.chromium.base.ApplicationStatus; +import org.chromium.base.AsyncTask; import org.chromium.base.ContextUtils; import org.chromium.base.Log; import org.chromium.base.VisibleForTesting;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/invalidation/InvalidationController.java b/chrome/android/java/src/org/chromium/chrome/browser/invalidation/InvalidationController.java index 58ce859..bcb574c5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/invalidation/InvalidationController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/invalidation/InvalidationController.java
@@ -7,7 +7,6 @@ import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; -import android.os.AsyncTask; import android.os.Build; import android.os.Handler; import android.os.SystemClock; @@ -16,6 +15,7 @@ import org.chromium.base.ApplicationState; import org.chromium.base.ApplicationStatus; +import org.chromium.base.AsyncTask; import org.chromium.base.Log; import org.chromium.base.VisibleForTesting; import org.chromium.chrome.browser.ChromeFeatureList;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/remote/MediaUrlResolver.java b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/MediaUrlResolver.java index 4124011..5e4f112 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/media/remote/MediaUrlResolver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/remote/MediaUrlResolver.java
@@ -5,9 +5,9 @@ package org.chromium.chrome.browser.media.remote; import android.net.Uri; -import android.os.AsyncTask; import android.text.TextUtils; +import org.chromium.base.AsyncTask; import org.chromium.base.Log; import org.chromium.base.VisibleForTesting; import org.chromium.base.metrics.RecordHistogram;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/metrics/UmaSessionStats.java b/chrome/android/java/src/org/chromium/chrome/browser/metrics/UmaSessionStats.java index b3f0105..bc39e47 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/metrics/UmaSessionStats.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/metrics/UmaSessionStats.java
@@ -7,9 +7,9 @@ import android.content.ComponentCallbacks; import android.content.Context; import android.content.res.Configuration; -import android.os.AsyncTask; import android.text.TextUtils; +import org.chromium.base.AsyncTask; import org.chromium.base.metrics.RecordHistogram; import org.chromium.chrome.browser.DefaultBrowserInfo; import org.chromium.chrome.browser.instantapps.InstantAppsHandler;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/metrics/WebApkUma.java b/chrome/android/java/src/org/chromium/chrome/browser/metrics/WebApkUma.java index 53735571..6d7a91f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/metrics/WebApkUma.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/metrics/WebApkUma.java
@@ -6,13 +6,13 @@ import android.Manifest; import android.content.ContentResolver; -import android.os.AsyncTask; import android.os.Build; import android.os.Environment; import android.os.StatFs; import android.provider.Settings; import android.text.TextUtils; +import org.chromium.base.AsyncTask; import org.chromium.base.ContextUtils; import org.chromium.base.metrics.RecordHistogram; import org.chromium.chrome.browser.preferences.website.SiteSettingsCategory;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java index 4f2163d..e83f1fe 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java
@@ -7,13 +7,13 @@ import android.app.Activity; import android.content.Context; import android.net.Uri; -import android.os.AsyncTask; import android.os.Environment; import android.support.annotation.IntDef; import android.text.TextUtils; import org.chromium.base.ActivityState; import org.chromium.base.ApplicationStatus; +import org.chromium.base.AsyncTask; import org.chromium.base.Callback; import org.chromium.base.Log; import org.chromium.base.VisibleForTesting;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/evaluation/OfflinePageEvaluationBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/evaluation/OfflinePageEvaluationBridge.java index 217d04bd..bb9aafb4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/evaluation/OfflinePageEvaluationBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/evaluation/OfflinePageEvaluationBridge.java
@@ -4,8 +4,7 @@ package org.chromium.chrome.browser.offlinepages.evaluation; -import android.os.AsyncTask; - +import org.chromium.base.AsyncTask; import org.chromium.base.Callback; import org.chromium.base.Log; import org.chromium.base.ObserverList;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omaha/OmahaService.java b/chrome/android/java/src/org/chromium/chrome/browser/omaha/OmahaService.java index 06e9324..7d9f65e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omaha/OmahaService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omaha/OmahaService.java
@@ -8,10 +8,10 @@ import android.app.IntentService; import android.app.job.JobService; import android.content.Context; -import android.os.AsyncTask; import android.os.Build; import android.support.annotation.Nullable; +import org.chromium.base.AsyncTask; import org.chromium.base.ContextUtils; import org.chromium.base.Log; import org.chromium.base.ThreadUtils; @@ -88,6 +88,9 @@ } } + // Incorrectly infers that this is called on a worker thread because of AsyncTask doInBackground + // overriding. + @SuppressWarnings("WrongThread") @Override @TargetApi(Build.VERSION_CODES.M) public boolean onStartTask(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omaha/UpdateMenuItemHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/omaha/UpdateMenuItemHelper.java index c7415e5..663dea3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omaha/UpdateMenuItemHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omaha/UpdateMenuItemHelper.java
@@ -14,7 +14,6 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; -import android.os.AsyncTask; import android.os.Build; import android.os.Environment; import android.os.StatFs; @@ -24,6 +23,7 @@ import com.google.android.gms.common.GooglePlayServicesUtil; +import org.chromium.base.AsyncTask; import org.chromium.base.CommandLine; import org.chromium.base.Log; import org.chromium.base.ThreadUtils;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/geo/VisibleNetworksTracker.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/geo/VisibleNetworksTracker.java index 127422d..03726313 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/geo/VisibleNetworksTracker.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/geo/VisibleNetworksTracker.java
@@ -5,9 +5,9 @@ package org.chromium.chrome.browser.omnibox.geo; import android.content.Context; -import android.os.AsyncTask; import android.os.SystemClock; +import org.chromium.base.AsyncTask; import org.chromium.base.Log; import org.chromium.base.ThreadUtils; import org.chromium.base.VisibleForTesting;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/partnerbookmarks/PartnerBookmarksReader.java b/chrome/android/java/src/org/chromium/chrome/browser/partnerbookmarks/PartnerBookmarksReader.java index 6c7acfe6..a14b992 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/partnerbookmarks/PartnerBookmarksReader.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/partnerbookmarks/PartnerBookmarksReader.java
@@ -5,8 +5,8 @@ package org.chromium.chrome.browser.partnerbookmarks; import android.content.Context; -import android.os.AsyncTask; +import org.chromium.base.AsyncTask; import org.chromium.base.Log; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.metrics.RecordHistogram;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/partnercustomizations/PartnerBrowserCustomizations.java b/chrome/android/java/src/org/chromium/chrome/browser/partnercustomizations/PartnerBrowserCustomizations.java index 2c40749f..7569d505 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/partnercustomizations/PartnerBrowserCustomizations.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/partnercustomizations/PartnerBrowserCustomizations.java
@@ -9,10 +9,10 @@ import android.content.pm.ProviderInfo; import android.database.Cursor; import android.net.Uri; -import android.os.AsyncTask; import android.support.annotation.Nullable; import android.text.TextUtils; +import org.chromium.base.AsyncTask; import org.chromium.base.CommandLine; import org.chromium.base.ContextUtils; import org.chromium.base.Log;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/CardEditor.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/CardEditor.java index a7cef76e..1cca271 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/CardEditor.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/CardEditor.java
@@ -4,7 +4,6 @@ package org.chromium.chrome.browser.payments; -import android.os.AsyncTask; import android.os.Handler; import android.text.SpannableStringBuilder; import android.text.TextUtils; @@ -13,6 +12,7 @@ import android.util.Pair; import org.chromium.base.ApiCompatibilityUtils; +import org.chromium.base.AsyncTask; import org.chromium.base.Callback; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeActivity;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/BitmapScalerTask.java b/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/BitmapScalerTask.java index 99878e4..123f0d3b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/BitmapScalerTask.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/BitmapScalerTask.java
@@ -5,10 +5,10 @@ package org.chromium.chrome.browser.photo_picker; import android.graphics.Bitmap; -import android.os.AsyncTask; import android.os.SystemClock; import android.util.LruCache; +import org.chromium.base.AsyncTask; import org.chromium.base.ThreadUtils; import org.chromium.base.metrics.RecordHistogram;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/FileEnumWorkerTask.java b/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/FileEnumWorkerTask.java index b984ca55..80ea023 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/FileEnumWorkerTask.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/FileEnumWorkerTask.java
@@ -6,10 +6,10 @@ import android.Manifest; import android.content.Intent; -import android.os.AsyncTask; import android.os.Environment; import android.provider.MediaStore; +import org.chromium.base.AsyncTask; import org.chromium.base.ThreadUtils; import org.chromium.ui.base.WindowAndroid;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PickerBitmapViewHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PickerBitmapViewHolder.java index bcd8e34..85c9d92 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PickerBitmapViewHolder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/photo_picker/PickerBitmapViewHolder.java
@@ -6,11 +6,11 @@ import android.content.res.Resources; import android.graphics.Bitmap; -import android.os.AsyncTask; import android.os.SystemClock; import android.support.v7.widget.RecyclerView.ViewHolder; import android.text.TextUtils; +import org.chromium.base.AsyncTask; import org.chromium.base.metrics.RecordHistogram; import org.chromium.chrome.R;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/services/AccountsChangedReceiver.java b/chrome/android/java/src/org/chromium/chrome/browser/services/AccountsChangedReceiver.java index 8437d34..d65355f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/services/AccountsChangedReceiver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/services/AccountsChangedReceiver.java
@@ -8,9 +8,9 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; -import android.os.AsyncTask; import org.chromium.base.ApplicationStatus; +import org.chromium.base.AsyncTask; import org.chromium.base.Log; import org.chromium.base.ThreadUtils; import org.chromium.base.library_loader.ProcessInitException;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/InvalidationGcmUpstreamSender.java b/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/InvalidationGcmUpstreamSender.java index af3f831..64e0ce4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/InvalidationGcmUpstreamSender.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/services/gcm/InvalidationGcmUpstreamSender.java
@@ -7,7 +7,6 @@ import android.accounts.Account; import android.annotation.SuppressLint; import android.content.Context; -import android.os.AsyncTask; import android.os.Bundle; import android.os.Parcel; import android.support.annotation.MainThread; @@ -16,6 +15,7 @@ import com.google.android.gms.gcm.GoogleCloudMessaging; import com.google.ipc.invalidation.ticl.android2.channel.GcmUpstreamSenderService; +import org.chromium.base.AsyncTask; import org.chromium.base.ContextUtils; import org.chromium.base.ThreadUtils; import org.chromium.chrome.browser.init.ProcessInitializationHandler; @@ -50,6 +50,9 @@ }); } + // Incorrectly infers that this is called on a worker thread because of AsyncTask doInBackground + // overriding. + @SuppressWarnings("WrongThread") @MainThread private void doDeliverMessage( final Context applicationContext, final String to, final Bundle data) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/share/OptionalShareTargetsManager.java b/chrome/android/java/src/org/chromium/chrome/browser/share/OptionalShareTargetsManager.java index 4db3745..be9203f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/share/OptionalShareTargetsManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/share/OptionalShareTargetsManager.java
@@ -7,12 +7,12 @@ import android.app.Activity; import android.content.ComponentName; import android.content.pm.PackageManager; -import android.os.AsyncTask; import android.os.StrictMode; import org.chromium.base.ActivityState; import org.chromium.base.ApplicationStatus; import org.chromium.base.ApplicationStatus.ActivityStateListener; +import org.chromium.base.AsyncTask; import org.chromium.base.Log; import org.chromium.base.ThreadUtils;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/share/ShareHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/share/ShareHelper.java index 477eeca..abbb3420 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/share/ShareHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/share/ShareHelper.java
@@ -24,7 +24,6 @@ import android.graphics.Bitmap; import android.graphics.drawable.Drawable; import android.net.Uri; -import android.os.AsyncTask; import android.os.Build; import android.support.annotation.Nullable; import android.support.v7.app.AlertDialog; @@ -38,6 +37,7 @@ import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.ApplicationState; import org.chromium.base.ApplicationStatus; +import org.chromium.base.AsyncTask; import org.chromium.base.Callback; import org.chromium.base.ContextUtils; import org.chromium.base.Log;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountSigninView.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountSigninView.java index 26739473..89ac57c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountSigninView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountSigninView.java
@@ -6,7 +6,6 @@ import android.app.Activity; import android.content.Context; -import android.os.AsyncTask; import android.os.Bundle; import android.os.SystemClock; import android.support.annotation.IntDef; @@ -22,6 +21,7 @@ import android.widget.ImageView; import android.widget.TextView; +import org.chromium.base.AsyncTask; import org.chromium.base.Log; import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.metrics.RecordUserAction;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountTrackerService.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountTrackerService.java index 584da678..f805af8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountTrackerService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountTrackerService.java
@@ -4,9 +4,9 @@ package org.chromium.chrome.browser.signin; -import android.os.AsyncTask; import android.support.annotation.IntDef; +import org.chromium.base.AsyncTask; import org.chromium.base.Log; import org.chromium.base.ObserverList; import org.chromium.base.ThreadUtils;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragmentBase.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragmentBase.java index d8a05a7d..9f9604f2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragmentBase.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFragmentBase.java
@@ -11,7 +11,6 @@ import android.graphics.BitmapFactory; import android.graphics.Point; import android.graphics.drawable.Drawable; -import android.os.AsyncTask; import android.os.Bundle; import android.os.SystemClock; import android.support.annotation.IntDef; @@ -27,6 +26,7 @@ import android.view.ViewGroup; import android.widget.TextView; +import org.chromium.base.AsyncTask; import org.chromium.base.Log; import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.metrics.RecordUserAction;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninHelper.java index b7e2127..03fbca0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninHelper.java
@@ -7,12 +7,12 @@ import android.accounts.Account; import android.annotation.SuppressLint; import android.content.Context; -import android.os.AsyncTask; import com.google.android.gms.auth.AccountChangeEvent; import com.google.android.gms.auth.GoogleAuthException; import com.google.android.gms.auth.GoogleAuthUtil; +import org.chromium.base.AsyncTask; import org.chromium.base.ContextUtils; import org.chromium.base.Log; import org.chromium.base.VisibleForTesting;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/TileRenderer.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/TileRenderer.java index ff670c9..28f2a7a87 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/TileRenderer.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/TileRenderer.java
@@ -10,13 +10,13 @@ import android.graphics.BitmapFactory; import android.graphics.Color; import android.graphics.drawable.BitmapDrawable; -import android.os.AsyncTask; import android.support.annotation.LayoutRes; import android.support.v4.graphics.drawable.RoundedBitmapDrawable; import android.view.LayoutInflater; import android.view.ViewGroup; import org.chromium.base.ApiCompatibilityUtils; +import org.chromium.base.AsyncTask; import org.chromium.base.Log; import org.chromium.base.VisibleForTesting; import org.chromium.chrome.R;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/survey/ChromeSurveyController.java b/chrome/android/java/src/org/chromium/chrome/browser/survey/ChromeSurveyController.java index 324adee..871721aa 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/survey/ChromeSurveyController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/survey/ChromeSurveyController.java
@@ -6,12 +6,12 @@ import android.content.Context; import android.content.SharedPreferences; -import android.os.AsyncTask; import android.os.Handler; import android.support.annotation.IntDef; import android.support.annotation.VisibleForTesting; import android.text.TextUtils; +import org.chromium.base.AsyncTask; import org.chromium.base.CommandLine; import org.chromium.base.ContextUtils; import org.chromium.base.ThreadUtils;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java index 128d935..885bc2e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
@@ -95,8 +95,8 @@ import org.chromium.chrome.browser.vr_shell.VrShellDelegate; import org.chromium.chrome.browser.widget.PulseDrawable; import org.chromium.chrome.browser.widget.textbubble.TextBubble; -import org.chromium.components.content_view.ContentView; import org.chromium.components.dom_distiller.core.DomDistillerUrlUtils; +import org.chromium.components.embedder_support.view.ContentView; import org.chromium.components.feature_engagement.EventConstants; import org.chromium.components.feature_engagement.FeatureConstants; import org.chromium.components.feature_engagement.Tracker;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/DocumentModeAssassin.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/DocumentModeAssassin.java index d948cef..2637a719 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/DocumentModeAssassin.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/DocumentModeAssassin.java
@@ -7,11 +7,11 @@ import android.annotation.TargetApi; import android.content.Context; import android.content.SharedPreferences; -import android.os.AsyncTask; import android.os.Build; import android.os.StrictMode; import android.util.Pair; +import org.chromium.base.AsyncTask; import org.chromium.base.ContextUtils; import org.chromium.base.FileUtils; import org.chromium.base.Log;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java index 599d73dc..350c511 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java
@@ -6,7 +6,6 @@ import android.content.Context; import android.content.SharedPreferences; -import android.os.AsyncTask; import android.os.StrictMode; import android.os.SystemClock; import android.support.annotation.Nullable; @@ -16,6 +15,7 @@ import android.util.SparseBooleanArray; import android.util.SparseIntArray; +import org.chromium.base.AsyncTask; import org.chromium.base.Callback; import org.chromium.base.ContextUtils; import org.chromium.base.Log;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabbedModeTabPersistencePolicy.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabbedModeTabPersistencePolicy.java index 17e244b..61d5ad6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabbedModeTabPersistencePolicy.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabbedModeTabPersistencePolicy.java
@@ -5,12 +5,12 @@ package org.chromium.chrome.browser.tabmodel; import android.content.SharedPreferences; -import android.os.AsyncTask; import android.os.StrictMode; import android.support.annotation.WorkerThread; import android.util.Pair; import android.util.SparseBooleanArray; +import org.chromium.base.AsyncTask; import org.chromium.base.Callback; import org.chromium.base.ContextUtils; import org.chromium.base.Log;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/document/StorageDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/document/StorageDelegate.java index e639105..21b0770 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/document/StorageDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/document/StorageDelegate.java
@@ -5,9 +5,9 @@ package org.chromium.chrome.browser.tabmodel.document; import android.content.Context; -import android.os.AsyncTask; import android.util.SparseArray; +import org.chromium.base.AsyncTask; import org.chromium.base.ContextUtils; import org.chromium.base.Log; import org.chromium.base.StreamUtil;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/upgrade/PackageReplacedBroadcastReceiver.java b/chrome/android/java/src/org/chromium/chrome/browser/upgrade/PackageReplacedBroadcastReceiver.java index 6b6a930..48f4a83 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/upgrade/PackageReplacedBroadcastReceiver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/upgrade/PackageReplacedBroadcastReceiver.java
@@ -7,9 +7,9 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; -import android.os.AsyncTask; import android.os.Build; +import org.chromium.base.AsyncTask; import org.chromium.chrome.browser.notifications.channels.ChannelsUpdater; /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java index bc20149..f16ed6b7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
@@ -17,7 +17,6 @@ import android.graphics.Color; import android.graphics.PointF; import android.net.Uri; -import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.os.Handler; @@ -35,6 +34,7 @@ import org.chromium.base.ActivityState; import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.ApplicationStatus; +import org.chromium.base.AsyncTask; import org.chromium.base.CollectionUtil; import org.chromium.base.ContextUtils; import org.chromium.base.Log;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java index 383ba3d..73cbb3d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java
@@ -827,9 +827,9 @@ @Override public void setDialogLocation(int x, int y) { if (getWebVrModeEnabled()) return; - DisplayAndroid primaryDisplay = DisplayAndroid.getNonMultiDisplay(mActivity); - float w = mLastContentWidth * primaryDisplay.getDipScale(); - float h = mLastContentHeight * primaryDisplay.getDipScale(); + float dipScale = DisplayAndroid.getNonMultiDisplay(mActivity).getDipScale(); + float w = mLastContentWidth * dipScale; + float h = mLastContentHeight * dipScale; float scale = mContentVrWindowAndroid.getDisplay().getAndroidUIScaling(); nativeSetDialogLocation(mNativeVrShell, x * scale / w, y * scale / h); } @@ -1283,7 +1283,7 @@ private native void nativeOnTabRemoved(long nativeVrShell, boolean incognito, int id); private native void nativeCloseAlertDialog(long nativeVrShell); private native void nativeSetAlertDialog(long nativeVrShell, float width, float height); - private native void nativeSetDialogBufferSize(long nativeVrShell, float width, float height); + private native void nativeSetDialogBufferSize(long nativeVrShell, int width, int height); private native void nativeSetAlertDialogSize(long nativeVrShell, float width, float height); private native void nativeSetDialogLocation(long nativeVrShell, float x, float y); private native void nativeSetDialogFloating(long nativeVrShell, boolean floating);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInstaller.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInstaller.java index a0a7d32..1b6fc459 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInstaller.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInstaller.java
@@ -6,8 +6,8 @@ import android.content.pm.PackageManager; import android.graphics.Bitmap; -import android.os.AsyncTask; +import org.chromium.base.AsyncTask; import org.chromium.base.Callback; import org.chromium.base.ContextUtils; import org.chromium.base.annotations.CalledByNative;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappAuthenticator.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappAuthenticator.java index cda1e42..7b73386 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappAuthenticator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappAuthenticator.java
@@ -6,12 +6,12 @@ import android.annotation.SuppressLint; import android.content.Context; -import android.os.AsyncTask; import android.os.StrictMode; import android.os.SystemClock; import android.util.Log; import org.chromium.base.ApiCompatibilityUtils; +import org.chromium.base.AsyncTask; import org.chromium.base.SecureRandomInitializer; import org.chromium.base.metrics.CachedMetrics.TimesHistogramSample;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappDataStorage.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappDataStorage.java index 8af8584e..41212e35 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappDataStorage.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappDataStorage.java
@@ -8,10 +8,10 @@ import android.content.Intent; import android.content.SharedPreferences; import android.graphics.Bitmap; -import android.os.AsyncTask; import android.support.annotation.Nullable; import android.text.TextUtils; +import org.chromium.base.AsyncTask; import org.chromium.base.ContextUtils; import org.chromium.base.Log; import org.chromium.base.VisibleForTesting;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappDirectoryManager.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappDirectoryManager.java index c915453..48e51a1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappDirectoryManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappDirectoryManager.java
@@ -10,12 +10,12 @@ import android.content.Context; import android.content.Intent; import android.net.Uri; -import android.os.AsyncTask; import android.os.Build; import android.os.StrictMode; import android.os.SystemClock; import android.text.TextUtils; +import org.chromium.base.AsyncTask; import org.chromium.base.ContextUtils; import org.chromium.base.FileUtils; import org.chromium.base.Log;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappRegistry.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappRegistry.java index f820fa5..621eeaee 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappRegistry.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappRegistry.java
@@ -7,9 +7,9 @@ import android.content.Context; import android.content.SharedPreferences; import android.content.pm.PackageManager; -import android.os.AsyncTask; import android.text.TextUtils; +import org.chromium.base.AsyncTask; import org.chromium.base.ContextUtils; import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.CalledByNative;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/DateDividedAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/DateDividedAdapter.java index bc120ab..9e4cbc7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/DateDividedAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/DateDividedAdapter.java
@@ -4,7 +4,6 @@ package org.chromium.chrome.browser.widget; -import android.os.AsyncTask; import android.support.annotation.IntDef; import android.support.annotation.Nullable; import android.support.v7.widget.RecyclerView; @@ -16,11 +15,11 @@ import android.view.ViewGroup; import android.widget.TextView; +import org.chromium.base.AsyncTask; import org.chromium.base.Log; import org.chromium.chrome.R; import org.chromium.chrome.browser.download.DownloadUtils; import org.chromium.chrome.browser.download.home.list.UiUtils; -import org.chromium.chrome.browser.widget.DateDividedAdapter.ItemGroup; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/ThumbnailDiskStorage.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/ThumbnailDiskStorage.java index c20aa5c..be2ce8a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/ThumbnailDiskStorage.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/ThumbnailDiskStorage.java
@@ -7,7 +7,6 @@ import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; -import android.os.AsyncTask; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v4.util.AtomicFile; @@ -16,6 +15,7 @@ import com.google.protobuf.ByteString; +import org.chromium.base.AsyncTask; import org.chromium.base.ContextUtils; import org.chromium.base.Log; import org.chromium.base.StreamUtil;
diff --git a/chrome/android/javatests/DEPS b/chrome/android/javatests/DEPS index b6bf766..f9d89b2 100644 --- a/chrome/android/javatests/DEPS +++ b/chrome/android/javatests/DEPS
@@ -2,7 +2,7 @@ "+components/autofill/android/java/src/org/chromium/components/autofill", "+components/background_task_scheduler/android/java", "+components/bookmarks/common/android/java/src/org/chromium/components/bookmarks", - "+components/content_view", + "+components/embedder_support/android", "+components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement", "+components/dom_distiller/core/android/java/src/org/chromium/components/dom_distiller/core", "+components/gcm_driver/android/java/src/org/chromium/components/gcm_driver",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ShareIntentTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ShareIntentTest.java index 9bc2d9c..afad630 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ShareIntentTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ShareIntentTest.java
@@ -8,7 +8,6 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; -import android.os.AsyncTask; import android.os.ParcelFileDescriptor; import android.support.test.filters.LargeTest; @@ -18,6 +17,7 @@ import org.junit.Test; import org.junit.runner.RunWith; +import org.chromium.base.AsyncTask; import org.chromium.base.ThreadUtils; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.RetryOnFailure;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabTabPersistencePolicyTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabTabPersistencePolicyTest.java index c4e8628..92b8e79f 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabTabPersistencePolicyTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabTabPersistencePolicyTest.java
@@ -5,7 +5,6 @@ package org.chromium.chrome.browser.customtabs; import android.app.Activity; -import android.os.AsyncTask; import android.support.test.InstrumentationRegistry; import android.support.test.filters.MediumTest; import android.support.test.filters.SmallTest; @@ -21,6 +20,7 @@ import org.chromium.base.ActivityState; import org.chromium.base.ApplicationStatus; +import org.chromium.base.AsyncTask; import org.chromium.base.Callback; import org.chromium.base.ContextUtils; import org.chromium.base.StreamUtil;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/input/SelectPopupOtherContentViewTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/input/SelectPopupOtherContentViewTest.java index 6cb5d100..bdeb5f9 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/input/SelectPopupOtherContentViewTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/input/SelectPopupOtherContentViewTest.java
@@ -22,7 +22,7 @@ import org.chromium.chrome.browser.WebContentsFactory; import org.chromium.chrome.test.ChromeActivityTestRule; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; -import org.chromium.components.content_view.ContentView; +import org.chromium.components.embedder_support.view.ContentView; import org.chromium.content.browser.test.util.Criteria; import org.chromium.content.browser.test.util.CriteriaHelper; import org.chromium.content.browser.test.util.DOMUtils;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreTest.java index 3493c29..d5448efc 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreTest.java
@@ -6,7 +6,6 @@ import android.app.Activity; import android.content.SharedPreferences; -import android.os.AsyncTask; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; import android.util.Pair; @@ -20,6 +19,7 @@ import org.junit.runner.RunWith; import org.chromium.base.ActivityState; +import org.chromium.base.AsyncTask; import org.chromium.base.ContextUtils; import org.chromium.base.ThreadUtils; import org.chromium.base.test.BaseJUnit4ClassRunner;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/util/ChromeFileProviderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/util/ChromeFileProviderTest.java index d411a1d..746925d 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/util/ChromeFileProviderTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/util/ChromeFileProviderTest.java
@@ -6,7 +6,6 @@ import android.content.Context; import android.net.Uri; -import android.os.AsyncTask; import android.os.ParcelFileDescriptor; import android.support.test.InstrumentationRegistry; import android.support.test.filters.LargeTest; @@ -17,6 +16,7 @@ import org.junit.Test; import org.junit.runner.RunWith; +import org.chromium.base.AsyncTask; import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.content.browser.test.NativeLibraryTestRule;
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/init/AsyncInitTaskRunnerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/init/AsyncInitTaskRunnerTest.java index da95f5e..1e3313ffe 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/init/AsyncInitTaskRunnerTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/init/AsyncInitTaskRunnerTest.java
@@ -26,6 +26,7 @@ import org.chromium.base.library_loader.LoaderErrors; import org.chromium.base.library_loader.ProcessInitException; import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.base.test.asynctask.ShadowAsyncTask; import org.chromium.components.variations.firstrun.VariationsSeedFetcher; import java.util.concurrent.CountDownLatch; @@ -37,7 +38,7 @@ * Tests for {@link AsyncInitTaskRunner} */ @RunWith(BaseRobolectricTestRunner.class) -@Config(manifest = Config.NONE) +@Config(manifest = Config.NONE, shadows = {ShadowAsyncTask.class}) public class AsyncInitTaskRunnerTest { private static final int THREAD_WAIT_TIME_MS = 1000;
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/installedapp/InstalledAppProviderTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/installedapp/InstalledAppProviderTest.java index 31c93b9..b15861f 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/installedapp/InstalledAppProviderTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/installedapp/InstalledAppProviderTest.java
@@ -24,11 +24,11 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.base.test.asynctask.CustomShadowAsyncTask; import org.chromium.base.test.util.Feature; import org.chromium.chrome.browser.instantapps.InstantAppsHandler; import org.chromium.installedapp.mojom.InstalledAppProvider; import org.chromium.installedapp.mojom.RelatedApplication; -import org.chromium.testing.local.CustomShadowAsyncTask; import java.net.URI; import java.net.URISyntaxException;
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/invalidation/InvalidationControllerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/invalidation/InvalidationControllerTest.java index cd2c92dd..37379b7 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/invalidation/InvalidationControllerTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/invalidation/InvalidationControllerTest.java
@@ -28,6 +28,7 @@ import org.chromium.base.ApplicationStatus; import org.chromium.base.CollectionUtil; import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.base.test.asynctask.CustomShadowAsyncTask; import org.chromium.base.test.util.Feature; import org.chromium.chrome.browser.sync.ProfileSyncService; import org.chromium.components.signin.AccountManagerFacade; @@ -38,7 +39,6 @@ import org.chromium.components.sync.ModelTypeHelper; import org.chromium.components.sync.notifier.InvalidationIntentProtocol; import org.chromium.components.sync.test.util.MockSyncContentResolverDelegate; -import org.chromium.testing.local.CustomShadowAsyncTask; import java.util.HashSet; import java.util.Set;
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/media/remote/MediaUrlResolverTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/media/remote/MediaUrlResolverTest.java index d0610c2c..bb7e240d 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/media/remote/MediaUrlResolverTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/media/remote/MediaUrlResolverTest.java
@@ -20,6 +20,7 @@ import org.chromium.base.CommandLine; import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.base.test.asynctask.ShadowAsyncTask; import java.io.IOException; import java.net.HttpURLConnection; @@ -35,7 +36,7 @@ * Unit tests (run on host) for {@link org.chromium.chrome.browser.media.remote.MediaUrlResolver}. */ @RunWith(BaseRobolectricTestRunner.class) -@Config(manifest = Config.NONE) +@Config(manifest = Config.NONE, shadows = {ShadowAsyncTask.class}) public class MediaUrlResolverTest { // Constants copied from MediaUrlResolver. Don't use the copies in MediaUrlResolver // since we want the tests to detect if these are changed or corrupted.
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java index 8e684af..2d0be7f4 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java
@@ -50,6 +50,7 @@ import org.chromium.base.Callback; import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.base.test.asynctask.CustomShadowAsyncTask; import org.chromium.base.test.util.Feature; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeFeatureList; @@ -80,7 +81,6 @@ import org.chromium.components.signin.test.util.AccountHolder; import org.chromium.components.signin.test.util.FakeAccountManagerDelegate; import org.chromium.net.NetworkChangeNotifier; -import org.chromium.testing.local.CustomShadowAsyncTask; import java.util.ArrayList; import java.util.Collection;
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/omnibox/geo/VisibleNetworksTrackerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/omnibox/geo/VisibleNetworksTrackerTest.java index e18442e1..2270ee63 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/omnibox/geo/VisibleNetworksTrackerTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/omnibox/geo/VisibleNetworksTrackerTest.java
@@ -21,10 +21,10 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.base.test.asynctask.CustomShadowAsyncTask; import org.chromium.chrome.browser.omnibox.geo.VisibleNetworks.VisibleCell; import org.chromium.chrome.browser.omnibox.geo.VisibleNetworks.VisibleWifi; import org.chromium.chrome.browser.omnibox.geo.VisibleNetworksTrackerTest.ShadowPlatformNetworksManager; -import org.chromium.testing.local.CustomShadowAsyncTask; import java.util.Arrays; import java.util.HashSet; @@ -214,4 +214,4 @@ : sOnlyConnectedNetworks.remove(0); } } -} \ No newline at end of file +}
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkUpdateManagerUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkUpdateManagerUnitTest.java index 56f851e..2fa8f69 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkUpdateManagerUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebApkUpdateManagerUnitTest.java
@@ -31,13 +31,13 @@ import org.chromium.base.CommandLine; import org.chromium.base.PathUtils; import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.base.test.asynctask.CustomShadowAsyncTask; import org.chromium.blink_public.platform.WebDisplayMode; import org.chromium.chrome.browser.ShortcutHelper; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.util.test.ShadowUrlUtilities; import org.chromium.chrome.test.support.DisableHistogramsRule; import org.chromium.content_public.common.ScreenOrientationValues; -import org.chromium.testing.local.CustomShadowAsyncTask; import org.chromium.webapk.lib.common.WebApkConstants; import org.chromium.webapk.lib.common.WebApkMetaDataKeys; import org.chromium.webapk.test.WebApkTestHelper;
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebappDataStorageTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebappDataStorageTest.java index 3630096..9306c80 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebappDataStorageTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebappDataStorageTest.java
@@ -23,10 +23,10 @@ import org.chromium.base.ContextUtils; import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.base.test.asynctask.BackgroundShadowAsyncTask; import org.chromium.base.test.util.Feature; import org.chromium.blink_public.platform.WebDisplayMode; import org.chromium.chrome.browser.ShortcutHelper; -import org.chromium.testing.local.BackgroundShadowAsyncTask; import java.util.concurrent.TimeUnit;
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebappDirectoryManagerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebappDirectoryManagerTest.java index 580e146..0882f66 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebappDirectoryManagerTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebappDirectoryManagerTest.java
@@ -26,8 +26,8 @@ import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.metrics.test.ShadowRecordHistogram; import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.base.test.asynctask.CustomShadowAsyncTask; import org.chromium.base.test.util.Feature; -import org.chromium.testing.local.CustomShadowAsyncTask; import org.chromium.webapk.lib.common.WebApkConstants; import java.io.File;
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebappRegistryTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebappRegistryTest.java index ef5bbeb7..51343e06 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebappRegistryTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebappRegistryTest.java
@@ -24,10 +24,10 @@ import org.chromium.base.ContextUtils; import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.base.test.asynctask.BackgroundShadowAsyncTask; import org.chromium.base.test.util.Feature; import org.chromium.chrome.browser.ShortcutHelper; import org.chromium.chrome.browser.browsing_data.UrlFilters; -import org.chromium.testing.local.BackgroundShadowAsyncTask; import org.chromium.webapk.lib.common.WebApkConstants; import java.util.Arrays;
diff --git a/chrome/android/profiles/chrome-profile-3309-text.prof b/chrome/android/profiles/chrome-profile-3309-text.prof new file mode 120000 index 0000000..c3b5d37 --- /dev/null +++ b/chrome/android/profiles/chrome-profile-3309-text.prof
@@ -0,0 +1 @@ +../../../../.cipd/pkgs/0/_current/chrome-profile-3309-text.prof \ No newline at end of file
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt index 7733693..71b562d3 100644 --- a/chrome/android/profiles/newest.txt +++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-69.0.3481.0_rc-r1.afdo.bz2 \ No newline at end of file +chromeos-chrome-amd64-69.0.3482.0_rc-r1.afdo.bz2 \ No newline at end of file
diff --git a/chrome/android/webapk/libs/client/BUILD.gn b/chrome/android/webapk/libs/client/BUILD.gn index 2b23e0f..105fc0d 100644 --- a/chrome/android/webapk/libs/client/BUILD.gn +++ b/chrome/android/webapk/libs/client/BUILD.gn
@@ -47,6 +47,7 @@ ] deps = [ ":client_java", + "//base:base_junit_test_support", "//chrome/android/webapk/libs/common:common_java", "//chrome/android/webapk/libs/runtime_library:webapk_service_aidl_java", "//chrome/android/webapk/test:junit_test_support",
diff --git a/chrome/android/webapk/libs/client/DEPS b/chrome/android/webapk/libs/client/DEPS index 0596914..01ebe73e 100644 --- a/chrome/android/webapk/libs/client/DEPS +++ b/chrome/android/webapk/libs/client/DEPS
@@ -1,4 +1,5 @@ include_rules = [ "+base/android/java/src/org/chromium/base/annotations", + "+base/test/android/junit/src/org/chromium/base/test/asynctask", "+chrome/android/webapk/libs/common", ]
diff --git a/chrome/android/webapk/libs/client/junit/src/org/chromium/webapk/lib/client/WebApkIdentityServiceClientTest.java b/chrome/android/webapk/libs/client/junit/src/org/chromium/webapk/lib/client/WebApkIdentityServiceClientTest.java index cd2aef1..778c7560 100644 --- a/chrome/android/webapk/libs/client/junit/src/org/chromium/webapk/lib/client/WebApkIdentityServiceClientTest.java +++ b/chrome/android/webapk/libs/client/junit/src/org/chromium/webapk/lib/client/WebApkIdentityServiceClientTest.java
@@ -19,7 +19,7 @@ import org.robolectric.shadows.ShadowApplication; import org.robolectric.shadows.ShadowLooper; -import org.chromium.testing.local.CustomShadowAsyncTask; +import org.chromium.base.test.asynctask.CustomShadowAsyncTask; import org.chromium.testing.local.LocalRobolectricTestRunner; import org.chromium.webapk.lib.common.WebApkMetaDataKeys; import org.chromium.webapk.lib.common.identity_service.IIdentityService;
diff --git a/chrome/android/webapk/libs/client/junit/src/org/chromium/webapk/lib/client/WebApkServiceConnectionManagerTest.java b/chrome/android/webapk/libs/client/junit/src/org/chromium/webapk/lib/client/WebApkServiceConnectionManagerTest.java index fdb39337..893690a7 100644 --- a/chrome/android/webapk/libs/client/junit/src/org/chromium/webapk/lib/client/WebApkServiceConnectionManagerTest.java +++ b/chrome/android/webapk/libs/client/junit/src/org/chromium/webapk/lib/client/WebApkServiceConnectionManagerTest.java
@@ -21,7 +21,7 @@ import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowApplication; -import org.chromium.testing.local.CustomShadowAsyncTask; +import org.chromium.base.test.asynctask.CustomShadowAsyncTask; import org.chromium.testing.local.LocalRobolectricTestRunner; /**
diff --git a/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkServiceConnectionManager.java b/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkServiceConnectionManager.java index 6d8e314..2193f09 100644 --- a/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkServiceConnectionManager.java +++ b/chrome/android/webapk/libs/client/src/org/chromium/webapk/lib/client/WebApkServiceConnectionManager.java
@@ -9,10 +9,11 @@ import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; -import android.os.AsyncTask; import android.os.IBinder; import android.util.Log; +import org.chromium.base.AsyncTask; + import java.util.ArrayList; import java.util.HashMap;
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 57654fac..e56441a 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -3184,11 +3184,6 @@ <message name="IDS_UTILITY_PROCESS_FILE_UTILITY_NAME" desc="The name of the utility process used for various Chrome specific file operations."> Chrome File Utilities </message> - <if expr="is_linux"> - <message name="IDS_UTILITY_PROCESS_FONT_SERVICE_UTILITY_NAME" desc="The name of the utility process used for FontConfig operations for Chrome on Linux."> - Linux Font Service - </message> - </if> <if expr="not is_android"> <message name="IDS_UTILITY_PROCESS_PROFILE_IMPORTER_NAME" desc="The name of the utility process used for importing profiles."> Profile Importer
diff --git a/chrome/browser/android/vr/vr_controller.cc b/chrome/browser/android/vr/vr_controller.cc index 247dfb2..a26de05 100644 --- a/chrome/browser/android/vr/vr_controller.cc +++ b/chrome/browser/android/vr/vr_controller.cc
@@ -143,7 +143,8 @@ state->description = device::mojom::XRInputSourceDescription::New(); // It's a handheld pointing device. - state->description->pointer_origin = device::mojom::XRPointerOrigin::HAND; + state->description->target_ray_mode = + device::mojom::XRTargetRayMode::POINTING; // Controller uses an arm model. state->description->emulated_position = true;
diff --git a/chrome/browser/android/vr/vr_shell.cc b/chrome/browser/android/vr/vr_shell.cc index 590d3e0..18dbc2c 100644 --- a/chrome/browser/android/vr/vr_shell.cc +++ b/chrome/browser/android/vr/vr_shell.cc
@@ -657,14 +657,10 @@ void VrShell::SetDialogBufferSize( JNIEnv* env, const base::android::JavaParamRef<jobject>& obj, - float width, - float height) { + int width, + int height) { if (ui_surface_texture_) ui_surface_texture_->SetDefaultBufferSize(width, height); - PostToGlThread( - FROM_HERE, - base::BindOnce(&VrShellGl::DialogBufferBoundsChanged, - gl_thread_->GetVrShellGl(), gfx::Size(width, height))); } void VrShell::SetAlertDialogSize(
diff --git a/chrome/browser/android/vr/vr_shell.h b/chrome/browser/android/vr/vr_shell.h index 929274f..0ff7b61 100644 --- a/chrome/browser/android/vr/vr_shell.h +++ b/chrome/browser/android/vr/vr_shell.h
@@ -224,8 +224,8 @@ const base::android::JavaParamRef<jobject>& obj); void SetDialogBufferSize(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj, - float width, - float height); + int width, + int height); void SetAlertDialogSize(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj, float width,
diff --git a/chrome/browser/android/vr/vr_shell_gl.cc b/chrome/browser/android/vr/vr_shell_gl.cc index 785d0bf..8a78653 100644 --- a/chrome/browser/android/vr/vr_shell_gl.cc +++ b/chrome/browser/android/vr/vr_shell_gl.cc
@@ -440,8 +440,6 @@ content_tex_buffer_size_.width(), content_tex_buffer_size_.height()); content_overlay_surface_texture_->SetDefaultBufferSize( content_tex_buffer_size_.width(), content_tex_buffer_size_.height()); - ui_surface_texture_->SetDefaultBufferSize(dialog_tex_buffer_size_.width(), - dialog_tex_buffer_size_.height()); webvr_vsync_align_ = base::FeatureList::IsEnabled(features::kWebVrVsyncAlign); @@ -889,9 +887,8 @@ showing_vr_dialog_ = true; vr_dialog_input_delegate_.reset(new PlatformUiInputDelegate(input_handler)); vr_dialog_input_delegate_->SetSize(width, height); - ui_->SetAlertDialogEnabled(true, vr_dialog_input_delegate_.get(), - width / dialog_tex_buffer_size_.width(), - height / dialog_tex_buffer_size_.width()); + ui_->SetAlertDialogEnabled(true, vr_dialog_input_delegate_.get(), width, + height); ScheduleOrCancelWebVrFrameTimeout(); } @@ -905,8 +902,14 @@ void VrShellGl::SetAlertDialogSize(float width, float height) { if (vr_dialog_input_delegate_) vr_dialog_input_delegate_->SetSize(width, height); - ui_->SetAlertDialogSize(width / dialog_tex_buffer_size_.width(), - height / dialog_tex_buffer_size_.width()); + // If not floating, dialogs are rendered with a fixed width, so that only the + // ratio matters. But, if they are floating, its size should be relative to + // the contents. During a WebXR presentation, the contents might not have been + // initialized but, in this case, the dialogs are never floating. + float scale = content_tex_buffer_size_.IsEmpty() + ? 1.0f + : content_tex_buffer_size_.width(); + ui_->SetAlertDialogSize(width / scale, height / scale); } void VrShellGl::SetDialogLocation(float x, float y) { @@ -2156,10 +2159,6 @@ content_tex_buffer_size_ = content_buffer_size; } -void VrShellGl::DialogBufferBoundsChanged(const gfx::Size& size) { - dialog_tex_buffer_size_ = size; -} - base::WeakPtr<VrShellGl> VrShellGl::GetWeakPtr() { return weak_ptr_factory_.GetWeakPtr(); } @@ -2558,7 +2557,7 @@ state->description = device::mojom::XRInputSourceDescription::New(); // It's a gaze-cursor-based device. - state->description->pointer_origin = device::mojom::XRPointerOrigin::HEAD; + state->description->target_ray_mode = device::mojom::XRTargetRayMode::GAZING; state->description->emulated_position = true; // No implicit handedness
diff --git a/chrome/browser/android/vr/vr_shell_gl.h b/chrome/browser/android/vr/vr_shell_gl.h index e41015d..3d93bc2 100644 --- a/chrome/browser/android/vr/vr_shell_gl.h +++ b/chrome/browser/android/vr/vr_shell_gl.h
@@ -300,7 +300,6 @@ void ContentBoundsChanged(int width, int height); void BufferBoundsChanged(const gfx::Size& content_buffer_size, const gfx::Size& overlay_buffer_size); - void DialogBufferBoundsChanged(const gfx::Size& size); void UIBoundsChanged(int width, int height); void ResumeContentRendering(); @@ -520,9 +519,8 @@ bool cardboard_ = false; gfx::Quaternion controller_quat_; - gfx::Size content_tex_buffer_size_; - gfx::Size webvr_surface_size_; - gfx::Size dialog_tex_buffer_size_; + gfx::Size content_tex_buffer_size_ = {0, 0}; + gfx::Size webvr_surface_size_ = {0, 0}; std::unique_ptr<WebXrPresentationState> webxr_ = nullptr;
diff --git a/chrome/browser/autofill/autofill_interactive_uitest.cc b/chrome/browser/autofill/autofill_interactive_uitest.cc index f386e6d..b4ee135 100644 --- a/chrome/browser/autofill/autofill_interactive_uitest.cc +++ b/chrome/browser/autofill/autofill_interactive_uitest.cc
@@ -303,9 +303,12 @@ std::string js("document.getElementById('" + field_id + "').focus();"); ASSERT_TRUE(content::ExecuteScript(GetWebContents(), js)); - SendKeyToPageAndWait(ui::DomKey::ARROW_DOWN); - SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN); - SendKeyToPopupAndWait(ui::DomKey::ENTER); + SendKeyToPageAndWait(ui::DomKey::ARROW_DOWN, + {ObservedUiEvents::kSuggestionShown}); + SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN, + {ObservedUiEvents::kPreviewFormData}); + SendKeyToPopupAndWait(ui::DomKey::ENTER, + {ObservedUiEvents::kFormDataFilled}); } void ExpectFieldValue(const std::string& field_name, @@ -494,11 +497,12 @@ // Start filling the first name field with "M" and wait for the popup to be // shown. SendKeyToPageAndWait(ui::DomKey::FromCharacter('M'), ui::DomCode::US_M, - ui::VKEY_M); + ui::VKEY_M, {ObservedUiEvents::kSuggestionShown}); // Press the down arrow to select the suggestion and preview the autofilled // form. - SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN); + SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN, + {ObservedUiEvents::kPreviewFormData}); // The previewed values should not be accessible to JavaScript. ExpectFieldValue("firstname", "M"); @@ -514,15 +518,18 @@ // displayed: http://crbug.com/57220 // Press Enter to accept the autofill suggestions. - SendKeyToPopupAndWait(ui::DomKey::ENTER); + SendKeyToPopupAndWait(ui::DomKey::ENTER, + {ObservedUiEvents::kFormDataFilled}); // The form should be filled. ExpectFilledTestForm(); } void TryClearForm() { - SendKeyToPageAndWait(ui::DomKey::ARROW_DOWN); - SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN); + SendKeyToPageAndWait(ui::DomKey::ARROW_DOWN, + {ObservedUiEvents::kSuggestionShown}); + SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN, + {ObservedUiEvents::kPreviewFormData}); SendKeyToDataListPopup(ui::DomKey::ARROW_DOWN); // clear SendKeyToDataListPopup(ui::DomKey::ENTER); @@ -535,14 +542,33 @@ // Start filling the first name field with "M" and wait for the popup to be // shown. SendKeyToPageAndWait(ui::DomKey::FromCharacter('M'), ui::DomCode::US_M, - ui::VKEY_M); + ui::VKEY_M, {ObservedUiEvents::kSuggestionShown}); // Press the down arrow to select the suggestion and preview the autofilled // form. - SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN); + SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN, + {ObservedUiEvents::kPreviewFormData}); // Press Enter to accept the autofill suggestions. - SendKeyToPopupAndWait(ui::DomKey::ENTER); + SendKeyToPopupAndWait(ui::DomKey::ENTER, + {ObservedUiEvents::kFormDataFilled}); + } + + void SelectSuggestionUsingArrowDown(int suggestion_position = 0) { + // Press the down arrow to initiate Autofill and wait for the popup to be + // shown. + SendKeyToPageAndWait(ui::DomKey::ARROW_DOWN, + {ObservedUiEvents::kSuggestionShown}); + // Press the down arrow repeatedly to select the suggestion at + // |suggestion_position| and preview the autofilled form. + for (int i = 0; i <= suggestion_position; ++i) { + SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN, + {ObservedUiEvents::kPreviewFormData}); + } + + // Press Enter to accept the autofill suggestions. + SendKeyToPopupAndWait(ui::DomKey::ENTER, + {ObservedUiEvents::kFormDataFilled}); } net::EmbeddedTestServer* https_server() { return &https_server_; } @@ -628,13 +654,13 @@ // Fill second section. FocusFieldByName("firstname_billing"); - SendKeyToPageAndWait(ui::DomKey::ARROW_DOWN); - SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN); - SendKeyToPopupAndWait(ui::DomKey::ENTER); + SelectSuggestionUsingArrowDown(); // Clear second section. - SendKeyToPageAndWait(ui::DomKey::ARROW_DOWN); - SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN); + SendKeyToPageAndWait(ui::DomKey::ARROW_DOWN, + {ObservedUiEvents::kSuggestionShown}); + SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN, + {ObservedUiEvents::kPreviewFormData}); SendKeyToDataListPopup(ui::DomKey::ARROW_DOWN); // clear SendKeyToDataListPopup(ui::DomKey::ENTER); @@ -666,9 +692,7 @@ // Fill FocusFirstNameField(); - SendKeyToPageAndWait(ui::DomKey::ARROW_DOWN); - SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN); - SendKeyToPopupAndWait(ui::DomKey::ENTER); + SelectSuggestionUsingArrowDown(); ExpectFieldValue("firstname", "Milton"); ExpectFieldValue("lastname", "Waddams"); // Modified by the user. @@ -705,9 +729,7 @@ FocusFirstNameField(); DeleteElementValue("firstname"); - SendKeyToPageAndWait(ui::DomKey::ARROW_DOWN); - SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN); - SendKeyToPopupAndWait(ui::DomKey::ENTER); + SelectSuggestionUsingArrowDown(); ExpectFilledTestForm(); } @@ -724,8 +746,10 @@ // Change the last name. FocusFieldByName("lastname"); - SendKeyToPageAndWait(ui::DomKey::BACKSPACE); - SendKeyToPageAndWait(ui::DomKey::BACKSPACE); + SendKeyToPageAndWait(ui::DomKey::BACKSPACE, + {ObservedUiEvents::kSuggestionShown}); + SendKeyToPageAndWait(ui::DomKey::BACKSPACE, + {ObservedUiEvents::kSuggestionShown}); ExpectFieldValue("firstname", "Milton"); ExpectFieldValue("lastname", "Wadda"); // Modified by the user. @@ -739,9 +763,7 @@ // Fill again by focusing on the first field. FocusFirstNameField(); - SendKeyToPageAndWait(ui::DomKey::ARROW_DOWN); - SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN); - SendKeyToPopupAndWait(ui::DomKey::ENTER); + SelectSuggestionUsingArrowDown(); ExpectFieldValue("firstname", "Milton"); ExpectFieldValue("lastname", @@ -755,8 +777,10 @@ ExpectFieldValue("phone", "15125551234"); // Clear everything except last name by selecting 'clear' on the first field. - SendKeyToPageAndWait(ui::DomKey::ARROW_DOWN); - SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN); + SendKeyToPageAndWait(ui::DomKey::ARROW_DOWN, + {ObservedUiEvents::kSuggestionShown}); + SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN, + {ObservedUiEvents::kPreviewFormData}); SendKeyToDataListPopup(ui::DomKey::ARROW_DOWN); // clear SendKeyToDataListPopup(ui::DomKey::ENTER); @@ -785,8 +809,10 @@ // Change the last name. FocusFieldByName("lastname"); - SendKeyToPageAndWait(ui::DomKey::BACKSPACE); - SendKeyToPageAndWait(ui::DomKey::BACKSPACE); + SendKeyToPageAndWait(ui::DomKey::BACKSPACE, + {ObservedUiEvents::kSuggestionShown}); + SendKeyToPageAndWait(ui::DomKey::BACKSPACE, + {ObservedUiEvents::kSuggestionShown}); ExpectFieldValue("firstname", "Milton"); ExpectFieldValue("lastname", "Wadda"); // Modified by the user. @@ -799,9 +825,7 @@ ExpectFieldValue("phone", "15125551234"); // Autofill the last name. - SendKeyToPageAndWait(ui::DomKey::ARROW_DOWN); - SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN); - SendKeyToPopupAndWait(ui::DomKey::ENTER); + SelectSuggestionUsingArrowDown(); ExpectFilledTestForm(); @@ -821,8 +845,10 @@ // Change the last name. FocusFieldByName("lastname"); - SendKeyToPageAndWait(ui::DomKey::BACKSPACE); - SendKeyToPageAndWait(ui::DomKey::BACKSPACE); + SendKeyToPageAndWait(ui::DomKey::BACKSPACE, + {ObservedUiEvents::kSuggestionShown}); + SendKeyToPageAndWait(ui::DomKey::BACKSPACE, + {ObservedUiEvents::kSuggestionShown}); ExpectFieldValue("firstname", "Milton"); ExpectFieldValue("lastname", "Wadda"); // Modified by the user. @@ -835,9 +861,7 @@ ExpectFieldValue("phone", "15125551234"); // Autofill the last name. - SendKeyToPageAndWait(ui::DomKey::ARROW_DOWN); - SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN); - SendKeyToPopupAndWait(ui::DomKey::ENTER); + SelectSuggestionUsingArrowDown(); ExpectFilledTestForm(); @@ -864,10 +888,7 @@ FocusFieldByName("address1"); DeleteElementValue("address1"); - SendKeyToPageAndWait(ui::DomKey::ARROW_DOWN); - SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN); - SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN); // second profile - SendKeyToPopupAndWait(ui::DomKey::ENTER); + SelectSuggestionUsingArrowDown(/*suggestion_position=*/1); ExpectFieldValue("firstname", "Milton"); ExpectFieldValue("lastname", "Waddams"); @@ -895,16 +916,7 @@ // Focus a fillable field. FocusFirstNameField(); - // Press the down arrow to initiate Autofill and wait for the popup to be - // shown. - SendKeyToPageAndWait(ui::DomKey::ARROW_DOWN); - - // Press the down arrow to select the suggestion and preview the autofilled - // form. - SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN); - - // Press Enter to accept the autofill suggestions. - SendKeyToPopupAndWait(ui::DomKey::ENTER); + SelectSuggestionUsingArrowDown(); // The form should be filled. ExpectFilledTestForm(); @@ -920,16 +932,7 @@ // Focus a fillable field. FocusFirstNameField(); - // Press the down arrow to initiate Autofill and wait for the popup to be - // shown. - SendKeyToPageAndWait(ui::DomKey::ARROW_DOWN); - - // Press the down arrow to select the suggestion and preview the autofilled - // form. - SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN); - - // Press tab to accept the autofill suggestions. - SendKeyToPopupAndWait(ui::DomKey::TAB); + SelectSuggestionUsingArrowDown(); // The form should be filled. ExpectFilledTestForm(); @@ -947,14 +950,15 @@ // Now click it. test_delegate()->Reset(); ASSERT_NO_FATAL_FAILURE(ClickFirstNameField()); - test_delegate()->Wait(); + test_delegate()->Wait({ObservedUiEvents::kSuggestionShown}); // Press the down arrow to select the suggestion and preview the autofilled // form. - SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN); + SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN, + {ObservedUiEvents::kPreviewFormData}); // Press Enter to accept the autofill suggestions. - SendKeyToPopupAndWait(ui::DomKey::ENTER); + SendKeyToPopupAndWait(ui::DomKey::ENTER, {ObservedUiEvents::kFormDataFilled}); // The form should be filled. ExpectFilledTestForm(); @@ -1008,14 +1012,15 @@ // This click should activate the autofill popup. test_delegate()->Reset(); ASSERT_NO_FATAL_FAILURE(ClickFirstNameField()); - test_delegate()->Wait(); + test_delegate()->Wait({ObservedUiEvents::kSuggestionShown}); // Press the down arrow to select the suggestion and preview the autofilled // form. - SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN); + SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN, + {ObservedUiEvents::kPreviewFormData}); // Press Enter to accept the autofill suggestions. - SendKeyToPopupAndWait(ui::DomKey::ENTER); + SendKeyToPopupAndWait(ui::DomKey::ENTER, {ObservedUiEvents::kFormDataFilled}); // The form should be filled. ExpectFilledTestForm(); @@ -1042,7 +1047,7 @@ test_delegate()->Reset(); ASSERT_NO_FATAL_FAILURE(ClickFirstNameField()); - test_delegate()->Wait(); + test_delegate()->Wait({ObservedUiEvents::kSuggestionShown}); } // Test that a field is still autofillable after the previously autofilled @@ -1057,9 +1062,10 @@ // Invoke and accept the Autofill popup and verify the form was filled. FocusFirstNameField(); SendKeyToPageAndWait(ui::DomKey::FromCharacter('M'), ui::DomCode::US_M, - ui::VKEY_M); - SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN); - SendKeyToPopupAndWait(ui::DomKey::ENTER); + ui::VKEY_M, {ObservedUiEvents::kSuggestionShown}); + SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN, + {ObservedUiEvents::kPreviewFormData}); + SendKeyToPopupAndWait(ui::DomKey::ENTER, {ObservedUiEvents::kFormDataFilled}); ExpectFilledTestForm(); // Delete the value of a filled field. @@ -1069,9 +1075,10 @@ // Invoke and accept the Autofill popup and verify the field was filled. SendKeyToPageAndWait(ui::DomKey::FromCharacter('M'), ui::DomCode::US_M, - ui::VKEY_M); - SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN); - SendKeyToPopupAndWait(ui::DomKey::ENTER); + ui::VKEY_M, {ObservedUiEvents::kSuggestionShown}); + SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN, + {ObservedUiEvents::kPreviewFormData}); + SendKeyToPopupAndWait(ui::DomKey::ENTER, {ObservedUiEvents::kFormDataFilled}); ExpectFieldValue("firstname", "Milton"); } @@ -1105,7 +1112,8 @@ GetFieldBackgroundColor("firstname", &orginalcolor); FocusFirstNameField(); - SendKeyToPageAndWait(ui::DomKey::ARROW_DOWN); + SendKeyToPageAndWait(ui::DomKey::ARROW_DOWN, + {ObservedUiEvents::kSuggestionShown}); SendKeyToDataListPopup(ui::DomKey::ARROW_DOWN); SendKeyToDataListPopup(ui::DomKey::ENTER); ExpectFieldValue("firstname", "Adam"); @@ -1150,14 +1158,15 @@ // Start filling the first name field with "M" and wait for the popup to be // shown. SendKeyToPageAndWait(ui::DomKey::FromCharacter('M'), ui::DomCode::US_M, - ui::VKEY_M); + ui::VKEY_M, {ObservedUiEvents::kSuggestionShown}); // Press the down arrow to select the suggestion and preview the autofilled // form. - SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN); + SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN, + {ObservedUiEvents::kPreviewFormData}); // Press Enter to accept the autofill suggestions. - SendKeyToPopupAndWait(ui::DomKey::ENTER); + SendKeyToPopupAndWait(ui::DomKey::ENTER, {ObservedUiEvents::kFormDataFilled}); // The form should be filled. ExpectFilledTestForm(); @@ -1220,14 +1229,15 @@ // Start filling the first name field with "M" and wait for the popup to be // shown. SendKeyToPageAndWait(ui::DomKey::FromCharacter('M'), ui::DomCode::US_M, - ui::VKEY_M); + ui::VKEY_M, {ObservedUiEvents::kSuggestionShown}); // Press the down arrow to select the suggestion and preview the autofilled // form. - SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN); + SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN, + {ObservedUiEvents::kPreviewFormData}); // Press Enter to accept the autofill suggestions. - SendKeyToPopupAndWait(ui::DomKey::ENTER); + SendKeyToPopupAndWait(ui::DomKey::ENTER, {ObservedUiEvents::kFormDataFilled}); // The form should be filled. ExpectFilledTestForm(); @@ -1283,9 +1293,10 @@ // Invoke and accept the Autofill popup and verify the form was filled. FocusFirstNameField(); SendKeyToPageAndWait(ui::DomKey::FromCharacter('M'), ui::DomCode::US_M, - ui::VKEY_M); - SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN); - SendKeyToPopupAndWait(ui::DomKey::ENTER); + ui::VKEY_M, {ObservedUiEvents::kSuggestionShown}); + SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN, + {ObservedUiEvents::kPreviewFormData}); + SendKeyToPopupAndWait(ui::DomKey::ENTER, {ObservedUiEvents::kFormDataFilled}); ExpectFilledTestForm(); int num_input_element_events = -1; @@ -1945,7 +1956,7 @@ // the popup to be shown. FocusFirstNameField(); SendKeyToPageAndWait(ui::DomKey::FromCharacter('M'), ui::DomCode::US_M, - ui::VKEY_M); + ui::VKEY_M, {ObservedUiEvents::kSuggestionShown}); // Now that the popup with suggestions is showing, disable autocomplete for // the active field. @@ -1955,7 +1966,8 @@ // Press the down arrow to select the suggestion and attempt to preview the // autofilled form. - SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN); + SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN, + {ObservedUiEvents::kPreviewFormData}); } // Test that dynamic forms don't get filled when the feature is disabled. @@ -2058,9 +2070,7 @@ // Trigger the autofill. FocusFieldByName("CREDIT_CARD_NAME_FULL"); - SendKeyToPageAndWait(ui::DomKey::ARROW_DOWN); - SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN); - SendKeyToPopupAndWait(ui::DomKey::ENTER); + SelectSuggestionUsingArrowDown(); ExpectFieldValue("CREDIT_CARD_NAME_FULL", "Milton Waddams"); ExpectFieldValue("CREDIT_CARD_NUMBER", "4111111111111111"); @@ -2273,11 +2283,12 @@ ~AutofillInteractiveIsolationTest() override = default; void SendKeyToPopupAndWait(ui::DomKey key, + std::list<ObservedUiEvents> expected_events, content::RenderWidgetHost* widget) { ui::KeyboardCode key_code = ui::NonPrintableDomKeyToKeyboardCode(key); ui::DomCode code = ui::UsLayoutKeyboardCodeToDomCode(key_code); - AutofillInteractiveTestBase::SendKeyToPopupAndWait(key, code, key_code, - widget); + AutofillInteractiveTestBase::SendKeyToPopupAndWait( + key, code, key_code, std::move(expected_events), widget); } bool IsPopupShown() { @@ -2323,11 +2334,14 @@ // keyboard. std::string script_focus("document.getElementById('NAME_FIRST').focus();"); ASSERT_TRUE(content::ExecuteScript(cross_frame, script_focus)); - SendKeyToPageAndWait(ui::DomKey::ARROW_DOWN); + SendKeyToPageAndWait(ui::DomKey::ARROW_DOWN, + {ObservedUiEvents::kSuggestionShown}); content::RenderWidgetHost* widget = cross_frame->GetView()->GetRenderWidgetHost(); - SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN, widget); - SendKeyToPopupAndWait(ui::DomKey::ENTER, widget); + SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN, + {ObservedUiEvents::kPreviewFormData}, widget); + SendKeyToPopupAndWait(ui::DomKey::ENTER, {ObservedUiEvents::kFormDataFilled}, + widget); // Check that the suggestion was filled. std::string value; @@ -2376,7 +2390,8 @@ ASSERT_TRUE(content::ExecuteScript(cross_frame, script_focus)); // Send an arrow dow keypress in order to trigger the autofill popup. - SendKeyToPageAndWait(ui::DomKey::ARROW_DOWN); + SendKeyToPageAndWait(ui::DomKey::ARROW_DOWN, + {ObservedUiEvents::kSuggestionShown}); } IN_PROC_BROWSER_TEST_P(AutofillInteractiveIsolationTest, @@ -2406,10 +2421,12 @@ // keyboard. std::string script_focus("document.getElementById('NAME_FIRST').focus();"); ASSERT_TRUE(content::ExecuteScript(cross_frame, script_focus)); - SendKeyToPageAndWait(ui::DomKey::ARROW_DOWN); + SendKeyToPageAndWait(ui::DomKey::ARROW_DOWN, + {ObservedUiEvents::kSuggestionShown}); content::RenderWidgetHost* widget = cross_frame->GetView()->GetRenderWidgetHost(); - SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN, widget); + SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN, + {ObservedUiEvents::kPreviewFormData}, widget); // Do not accept the suggestion yet, to keep the pop-up shown. EXPECT_TRUE(IsPopupShown()); @@ -2633,9 +2650,10 @@ // Trigger the initial fill. FocusFieldByName("cc-name"); SendKeyToPageAndWait(ui::DomKey::FromCharacter('M'), ui::DomCode::US_M, - ui::VKEY_M); - SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN); - SendKeyToPopupAndWait(ui::DomKey::ENTER); + ui::VKEY_M, {ObservedUiEvents::kSuggestionShown}); + SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN, + {ObservedUiEvents::kPreviewFormData}); + SendKeyToPopupAndWait(ui::DomKey::ENTER, {ObservedUiEvents::kFormDataFilled}); // Wait for the dynamic change to happen. bool has_refilled = false;
diff --git a/chrome/browser/autofill/autofill_uitest.cc b/chrome/browser/autofill/autofill_uitest.cc index 1639716b..2768e54 100644 --- a/chrome/browser/autofill/autofill_uitest.cc +++ b/chrome/browser/autofill/autofill_uitest.cc
@@ -27,119 +27,37 @@ // AutofillManagerTestDelegateImpl -------------------------------------------- AutofillManagerTestDelegateImpl::AutofillManagerTestDelegateImpl() - : run_loop_(nullptr), - is_expecting_dynamic_refill_(false), - waiting_for_preview_form_data_(false), - waiting_for_fill_form_data_(false), - waiting_for_show_suggestion_(false), - waiting_for_text_change_(false) {} + : is_expecting_dynamic_refill_(false) {} AutofillManagerTestDelegateImpl::~AutofillManagerTestDelegateImpl() {} void AutofillManagerTestDelegateImpl::DidPreviewFormData() { - if (!waiting_for_preview_form_data_) - return; - waiting_for_preview_form_data_ = false; - run_loop_->Quit(); + DCHECK(event_waiter_); + event_waiter_->OnEvent(ObservedUiEvents::kPreviewFormData); } void AutofillManagerTestDelegateImpl::DidFillFormData() { - if (!is_expecting_dynamic_refill_) - ASSERT_TRUE(run_loop_->running()); - if (!waiting_for_fill_form_data_) - return; - waiting_for_fill_form_data_ = false; - run_loop_->Quit(); + DCHECK(event_waiter_); + event_waiter_->OnEvent(ObservedUiEvents::kFormDataFilled); } void AutofillManagerTestDelegateImpl::DidShowSuggestions() { - if (!waiting_for_show_suggestion_) - return; - waiting_for_show_suggestion_ = false; - run_loop_->Quit(); + DCHECK(event_waiter_); + event_waiter_->OnEvent(ObservedUiEvents::kSuggestionShown); } -void AutofillManagerTestDelegateImpl::OnTextFieldChanged() { - if (!waiting_for_text_change_) - return; - waiting_for_text_change_ = false; - run_loop_->Quit(); -} +void AutofillManagerTestDelegateImpl::OnTextFieldChanged() {} void AutofillManagerTestDelegateImpl::Reset() { - base::AutoReset<base::RunLoop*> auto_reset(&run_loop_, nullptr); - waiting_for_preview_form_data_ = false; - waiting_for_fill_form_data_ = false; - waiting_for_show_suggestion_ = false; - waiting_for_text_change_ = false; + event_waiter_.reset(); } -void AutofillManagerTestDelegateImpl::Wait() { - waiting_for_preview_form_data_ = true; - waiting_for_fill_form_data_ = true; - waiting_for_show_suggestion_ = true; - base::RunLoop run_loop; - base::AutoReset<base::RunLoop*> auto_reset(&run_loop_, &run_loop); - run_loop_->Run(); -} - -void AutofillManagerTestDelegateImpl::WaitForTextChange() { - waiting_for_text_change_ = true; - base::RunLoop run_loop; - base::AutoReset<base::RunLoop*> auto_reset(&run_loop_, &run_loop); - run_loop_->Run(); -} - -bool AutofillManagerTestDelegateImpl::WaitForPreviewFormData( - base::TimeDelta timeout = base::TimeDelta::FromSeconds(0)) { - waiting_for_preview_form_data_ = true; - base::RunLoop run_loop; - base::AutoReset<base::RunLoop*> auto_reset(&run_loop_, &run_loop); - if (!timeout.is_zero()) { - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, run_loop_->QuitClosure(), timeout); - } - run_loop_->Run(); - return !waiting_for_preview_form_data_; -} - -bool AutofillManagerTestDelegateImpl::WaitForFormDataFilled( - base::TimeDelta timeout = base::TimeDelta::FromSeconds(0)) { - waiting_for_fill_form_data_ = true; - base::RunLoop run_loop; - base::AutoReset<base::RunLoop*> auto_reset(&run_loop_, &run_loop); - if (!timeout.is_zero()) { - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, run_loop_->QuitClosure(), timeout); - } - run_loop_->Run(); - return !waiting_for_fill_form_data_; -} - -bool AutofillManagerTestDelegateImpl::WaitForSuggestionShown( - base::TimeDelta timeout = base::TimeDelta::FromSeconds(0)) { - waiting_for_show_suggestion_ = true; - base::RunLoop run_loop; - base::AutoReset<base::RunLoop*> auto_reset(&run_loop_, &run_loop); - if (!timeout.is_zero()) { - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, run_loop_->QuitClosure(), timeout); - } - run_loop_->Run(); - return !waiting_for_show_suggestion_; -} - -bool AutofillManagerTestDelegateImpl::WaitForTextChange( - base::TimeDelta timeout = base::TimeDelta::FromSeconds(0)) { - waiting_for_text_change_ = true; - base::RunLoop run_loop; - base::AutoReset<base::RunLoop*> auto_reset(&run_loop_, &run_loop); - if (!timeout.is_zero()) { - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, run_loop_->QuitClosure(), timeout); - } - run_loop_->Run(); - return !waiting_for_text_change_; +bool AutofillManagerTestDelegateImpl::Wait( + std::list<ObservedUiEvents> expected_events, + base::TimeDelta timeout) { + event_waiter_ = + std::make_unique<EventWaiter<ObservedUiEvents>>(expected_events, timeout); + return event_waiter_->Wait(); } // AutofillUiTest ---------------------------------------------------- @@ -193,8 +111,8 @@ // suggestion drop down. test_delegate()->Reset(); SendKeyToPopup(ui::DomKey::ARROW_DOWN); - if (!test_delegate()->WaitForPreviewFormData( - base::TimeDelta::FromSeconds(5))) { + if (!test_delegate()->Wait({ObservedUiEvents::kPreviewFormData}, + base::TimeDelta::FromSeconds(5))) { LOG(WARNING) << "Failed to select an option from the" << " autofill suggestion drop down."; continue; @@ -203,8 +121,8 @@ // Press the enter key to invoke autofill using the first suggestion. test_delegate()->Reset(); SendKeyToPopup(ui::DomKey::ENTER); - if (!test_delegate()->WaitForFormDataFilled( - base::TimeDelta::FromSeconds(5))) { + if (!test_delegate()->Wait({ObservedUiEvents::kFormDataFilled}, + base::TimeDelta::FromSeconds(5))) { LOG(WARNING) << "Failed to fill the form."; continue; } @@ -229,8 +147,8 @@ if (content::ExecuteScript(GetWebContents(), js)) { test_delegate()->Reset(); SendKeyToPage(ui::DomKey::ARROW_DOWN); - return test_delegate()->WaitForSuggestionShown( - base::TimeDelta::FromSeconds(5)); + return test_delegate()->Wait({ObservedUiEvents::kSuggestionShown}, + base::TimeDelta::FromSeconds(5)); } return false; } @@ -242,19 +160,23 @@ false, false); } -void AutofillUiTest::SendKeyToPageAndWait(ui::DomKey key) { +void AutofillUiTest::SendKeyToPageAndWait( + ui::DomKey key, + std::list<ObservedUiEvents> expected_events) { ui::KeyboardCode key_code = ui::NonPrintableDomKeyToKeyboardCode(key); ui::DomCode code = ui::UsLayoutKeyboardCodeToDomCode(key_code); - SendKeyToPageAndWait(key, code, key_code); + SendKeyToPageAndWait(key, code, key_code, std::move(expected_events)); } -void AutofillUiTest::SendKeyToPageAndWait(ui::DomKey key, - ui::DomCode code, - ui::KeyboardCode key_code) { +void AutofillUiTest::SendKeyToPageAndWait( + ui::DomKey key, + ui::DomCode code, + ui::KeyboardCode key_code, + std::list<ObservedUiEvents> expected_events) { test_delegate()->Reset(); content::SimulateKeyPress(GetWebContents(), key, code, key_code, false, false, false, false); - test_delegate()->Wait(); + test_delegate()->Wait(std::move(expected_events)); } void AutofillUiTest::SendKeyToPopup(ui::DomKey key) { @@ -276,16 +198,21 @@ widget->RemoveKeyPressEventCallback(key_press_event_sink_); } -void AutofillUiTest::SendKeyToPopupAndWait(ui::DomKey key) { +void AutofillUiTest::SendKeyToPopupAndWait( + ui::DomKey key, + std::list<ObservedUiEvents> expected_events) { ui::KeyboardCode key_code = ui::NonPrintableDomKeyToKeyboardCode(key); ui::DomCode code = ui::UsLayoutKeyboardCodeToDomCode(key_code); - SendKeyToPopupAndWait(key, code, key_code, GetRenderViewHost()->GetWidget()); + SendKeyToPopupAndWait(key, code, key_code, std::move(expected_events), + GetRenderViewHost()->GetWidget()); } -void AutofillUiTest::SendKeyToPopupAndWait(ui::DomKey key, - ui::DomCode code, - ui::KeyboardCode key_code, - content::RenderWidgetHost* widget) { +void AutofillUiTest::SendKeyToPopupAndWait( + ui::DomKey key, + ui::DomCode code, + ui::KeyboardCode key_code, + std::list<ObservedUiEvents> expected_events, + content::RenderWidgetHost* widget) { // Route popup-targeted key presses via the render view host. content::NativeWebKeyboardEvent event(blink::WebKeyboardEvent::kRawKeyDown, blink::WebInputEvent::kNoModifiers, @@ -298,7 +225,7 @@ // handled by the installed callbacks do not end up crashing the test. widget->AddKeyPressEventCallback(key_press_event_sink_); widget->ForwardKeyboardEvent(event); - test_delegate()->Wait(); + test_delegate()->Wait(std::move(expected_events)); widget->RemoveKeyPressEventCallback(key_press_event_sink_); }
diff --git a/chrome/browser/autofill/autofill_uitest.h b/chrome/browser/autofill/autofill_uitest.h index 66de854..252d56f6 100644 --- a/chrome/browser/autofill/autofill_uitest.h +++ b/chrome/browser/autofill/autofill_uitest.h
@@ -11,6 +11,7 @@ #include "chrome/test/base/interactive_test_utils.h" #include "components/autofill/core/browser/autofill_manager.h" #include "components/autofill/core/browser/autofill_manager_test_delegate.h" +#include "components/autofill/core/browser/test_event_waiter.h" #include "content/public/browser/render_widget_host.h" #include "content/public/test/test_utils.h" #include "testing/gtest/include/gtest/gtest.h" @@ -20,6 +21,12 @@ namespace autofill { +enum class ObservedUiEvents { + kPreviewFormData, + kFormDataFilled, + kSuggestionShown, +}; + class AutofillManagerTestDelegateImpl : public autofill::AutofillManagerTestDelegate { public: @@ -33,23 +40,17 @@ void OnTextFieldChanged() override; void Reset(); - void Wait(); - void WaitForTextChange(); - bool WaitForPreviewFormData(base::TimeDelta timeout); - bool WaitForFormDataFilled(base::TimeDelta timeout); - bool WaitForSuggestionShown(base::TimeDelta timeout); - bool WaitForTextChange(base::TimeDelta timeout); + + bool Wait(std::list<ObservedUiEvents> expected_events, + base::TimeDelta timeout = base::TimeDelta::FromSeconds(0)); + void SetIsExpectingDynamicRefill(bool expect_refill) { is_expecting_dynamic_refill_ = expect_refill; } private: - base::RunLoop* run_loop_; bool is_expecting_dynamic_refill_; - bool waiting_for_preview_form_data_; - bool waiting_for_fill_form_data_; - bool waiting_for_show_suggestion_; - bool waiting_for_text_change_; + std::unique_ptr<EventWaiter<ObservedUiEvents>> event_waiter_; DISALLOW_COPY_AND_ASSIGN(AutofillManagerTestDelegateImpl); }; @@ -67,14 +68,18 @@ const int attempts = 1); bool ShowAutofillSuggestion(const std::string& focus_element_xpath); - void SendKeyToPageAndWait(ui::DomKey key); + void SendKeyToPageAndWait(ui::DomKey key, + std::list<ObservedUiEvents> expected_events); void SendKeyToPageAndWait(ui::DomKey key, ui::DomCode code, - ui::KeyboardCode key_code); - void SendKeyToPopupAndWait(ui::DomKey key); + ui::KeyboardCode key_code, + std::list<ObservedUiEvents> expected_events); + void SendKeyToPopupAndWait(ui::DomKey key, + std::list<ObservedUiEvents> expected_events); void SendKeyToPopupAndWait(ui::DomKey key, ui::DomCode code, ui::KeyboardCode key_code, + std::list<ObservedUiEvents> expected_events, content::RenderWidgetHost* widget); void SendKeyToDataListPopup(ui::DomKey key); void SendKeyToDataListPopup(ui::DomKey key,
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 0d167f1..cbd9ffa 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -497,10 +497,6 @@ #include "chrome/browser/offline_pages/offline_page_url_loader_request_interceptor.h" #endif -#if defined(OS_LINUX) -#include "components/services/font/public/interfaces/constants.mojom.h" -#endif - using base::FileDescriptor; using content::BrowserThread; using content::BrowserURLHandler; @@ -3060,10 +3056,8 @@ tab_android->GetWebappManifestScope(); } - if (base::FeatureList::IsEnabled(media::kUseSurfaceLayerForVideo)) { - web_prefs->picture_in_picture_enabled = - tab_android->IsPictureInPictureEnabled(); - } + web_prefs->picture_in_picture_enabled = + tab_android->IsPictureInPictureEnabled(); } #endif // defined(OS_ANDROID) @@ -3644,12 +3638,6 @@ &l10n_util::GetStringUTF16, IDS_UTILITY_PROCESS_FILE_UTILITY_NAME); #endif -#if defined(OS_LINUX) - (*services)[font_service::mojom::kServiceName] = - base::BindRepeating(&l10n_util::GetStringUTF16, - IDS_UTILITY_PROCESS_FONT_SERVICE_UTILITY_NAME); -#endif - (*services)[patch::mojom::kServiceName] = base::BindRepeating( &l10n_util::GetStringUTF16, IDS_UTILITY_PROCESS_PATCH_NAME);
diff --git a/chrome/browser/chromeos/arc/arc_play_store_enabled_preference_handler_unittest.cc b/chrome/browser/chromeos/arc/arc_play_store_enabled_preference_handler_unittest.cc index fd6a36d1..5d6412d2 100644 --- a/chrome/browser/chromeos/arc/arc_play_store_enabled_preference_handler_unittest.cc +++ b/chrome/browser/chromeos/arc/arc_play_store_enabled_preference_handler_unittest.cc
@@ -180,18 +180,20 @@ SetArcPlayStoreEnabledForProfile(profile(), false); - // Make sure consent auditig is recording the expected revocation of consent. + // Make sure consent auditing is recording the expected revocation of consent. const std::vector<int> tos_consent = { - IDS_SETTINGS_ANDROID_APPS_DISABLE_DIALOG_MESSAGE, + IDS_SETTINGS_ANDROID_APPS_DISABLE_DIALOG_MESSAGE}; + const std::vector<std::vector<int>> description_ids = {tos_consent}; + const std::vector<int> confirmation_ids = { IDS_SETTINGS_ANDROID_APPS_DISABLE_DIALOG_REMOVE}; - const std::vector<std::vector<int>> consent_ids = {tos_consent}; const std::vector<consent_auditor::Feature> features = { consent_auditor::Feature::PLAY_STORE}; const std::vector<consent_auditor::ConsentStatus> statuses = { consent_auditor::ConsentStatus::NOT_GIVEN}; EXPECT_EQ(consent_auditor()->account_id(), GetAuthenticatedAccountId()); - EXPECT_EQ(consent_auditor()->recorded_id_vectors(), consent_ids); + EXPECT_EQ(consent_auditor()->recorded_confirmation_ids(), confirmation_ids); + EXPECT_EQ(consent_auditor()->recorded_id_vectors(), description_ids); EXPECT_EQ(consent_auditor()->recorded_features(), features); EXPECT_EQ(consent_auditor()->recorded_statuses(), statuses); }
diff --git a/chrome/browser/chromeos/arc/optin/arc_terms_of_service_default_negotiator_unittest.cc b/chrome/browser/chromeos/arc/optin/arc_terms_of_service_default_negotiator_unittest.cc index 18a5b5eb..8b83c80 100644 --- a/chrome/browser/chromeos/arc/optin/arc_terms_of_service_default_negotiator_unittest.cc +++ b/chrome/browser/chromeos/arc/optin/arc_terms_of_service_default_negotiator_unittest.cc
@@ -186,13 +186,14 @@ // Make sure consent auditing records expected consents. std::vector<int> tos_consent = ArcSupportHost::ComputePlayToSConsentIds(tos_content); - tos_consent.push_back(IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE); - const std::vector<int> backup_consent = {IDS_ARC_OPT_IN_DIALOG_BACKUP_RESTORE, - IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE}; - const std::vector<int> location_consent = { - IDS_ARC_OPT_IN_LOCATION_SETTING, IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE}; + const std::vector<int> backup_consent = { + IDS_ARC_OPT_IN_DIALOG_BACKUP_RESTORE}; + const std::vector<int> location_consent = {IDS_ARC_OPT_IN_LOCATION_SETTING}; const std::vector<std::vector<int>> consent_ids = { tos_consent, backup_consent, location_consent}; + const std::vector<int> confirmation_ids = { + IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE, IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE, + IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE}; const std::vector<consent_auditor::Feature> features = { consent_auditor::Feature::PLAY_STORE, consent_auditor::Feature::BACKUP_AND_RESTORE, @@ -204,6 +205,7 @@ EXPECT_EQ(consent_auditor()->account_id(), GetAuthenticatedAccountId()); EXPECT_EQ(consent_auditor()->recorded_id_vectors(), consent_ids); + EXPECT_EQ(consent_auditor()->recorded_confirmation_ids(), confirmation_ids); EXPECT_EQ(consent_auditor()->recorded_features(), features); EXPECT_EQ(consent_auditor()->recorded_statuses(), statuses); } @@ -251,13 +253,14 @@ // consents as NOT_GIVEN. std::vector<int> tos_consent = ArcSupportHost::ComputePlayToSConsentIds(tos_content); - tos_consent.push_back(IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE); - const std::vector<int> backup_consent = {IDS_ARC_OPT_IN_DIALOG_BACKUP_RESTORE, - IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE}; - const std::vector<int> location_consent = { - IDS_ARC_OPT_IN_LOCATION_SETTING, IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE}; + const std::vector<int> backup_consent = { + IDS_ARC_OPT_IN_DIALOG_BACKUP_RESTORE}; + const std::vector<int> location_consent = {IDS_ARC_OPT_IN_LOCATION_SETTING}; const std::vector<std::vector<int>> consent_ids = { tos_consent, backup_consent, location_consent}; + const std::vector<int> confirmation_ids = { + IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE, IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE, + IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE}; const std::vector<consent_auditor::Feature> features = { consent_auditor::Feature::PLAY_STORE, consent_auditor::Feature::BACKUP_AND_RESTORE, @@ -269,6 +272,7 @@ EXPECT_EQ(consent_auditor()->account_id(), GetAuthenticatedAccountId()); EXPECT_EQ(consent_auditor()->recorded_id_vectors(), consent_ids); + EXPECT_EQ(consent_auditor()->recorded_confirmation_ids(), confirmation_ids); EXPECT_EQ(consent_auditor()->recorded_features(), features); EXPECT_EQ(consent_auditor()->recorded_statuses(), statuses); } @@ -308,11 +312,12 @@ // Make sure consent auditing records expected consents. std::vector<int> tos_consent = ArcSupportHost::ComputePlayToSConsentIds(""); - tos_consent.push_back(IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE); - const std::vector<int> location_consent = { - IDS_ARC_OPT_IN_LOCATION_SETTING, IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE}; + + const std::vector<int> location_consent = {IDS_ARC_OPT_IN_LOCATION_SETTING}; const std::vector<std::vector<int>> consent_ids = {tos_consent, location_consent}; + const std::vector<int> confirmation_ids = { + IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE, IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE}; const std::vector<consent_auditor::Feature> features = { consent_auditor::Feature::PLAY_STORE, consent_auditor::Feature::GOOGLE_LOCATION_SERVICE}; @@ -322,6 +327,7 @@ EXPECT_EQ(consent_auditor()->account_id(), GetAuthenticatedAccountId()); EXPECT_EQ(consent_auditor()->recorded_id_vectors(), consent_ids); + EXPECT_EQ(consent_auditor()->recorded_confirmation_ids(), confirmation_ids); EXPECT_EQ(consent_auditor()->recorded_features(), features); EXPECT_EQ(consent_auditor()->recorded_statuses(), statuses); } @@ -364,13 +370,16 @@ // Make sure consent auditing is recording all consents as NOT_GIVEN. std::vector<int> tos_consent = ArcSupportHost::ComputePlayToSConsentIds(tos_content); - tos_consent.push_back(IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE); - const std::vector<int> backup_consent = {IDS_ARC_OPT_IN_DIALOG_BACKUP_RESTORE, - IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE}; - const std::vector<int> location_consent = { - IDS_ARC_OPT_IN_LOCATION_SETTING, IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE}; + const std::vector<int> backup_consent = { + IDS_ARC_OPT_IN_DIALOG_BACKUP_RESTORE}; + const std::vector<int> location_consent = {IDS_ARC_OPT_IN_LOCATION_SETTING}; const std::vector<std::vector<int>> consent_ids = { tos_consent, backup_consent, location_consent}; + + const std::vector<int> confirmation_ids = { + IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE, IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE, + IDS_ARC_OPT_IN_DIALOG_BUTTON_AGREE}; + const std::vector<consent_auditor::Feature> features = { consent_auditor::Feature::PLAY_STORE, consent_auditor::Feature::BACKUP_AND_RESTORE, @@ -382,6 +391,7 @@ EXPECT_EQ(consent_auditor()->account_id(), GetAuthenticatedAccountId()); EXPECT_EQ(consent_auditor()->recorded_id_vectors(), consent_ids); + EXPECT_EQ(consent_auditor()->recorded_confirmation_ids(), confirmation_ids); EXPECT_EQ(consent_auditor()->recorded_features(), features); EXPECT_EQ(consent_auditor()->recorded_statuses(), statuses); }
diff --git a/chrome/browser/chromeos/arc/policy/arc_policy_bridge.cc b/chrome/browser/chromeos/arc/policy/arc_policy_bridge.cc index a70ebde2..fef0d83a 100644 --- a/chrome/browser/chromeos/arc/policy/arc_policy_bridge.cc +++ b/chrome/browser/chromeos/arc/policy/arc_policy_bridge.cc
@@ -242,7 +242,7 @@ // Keep them sorted by the ARC policy names. MapBoolToBool("cameraDisabled", policy::key::kVideoCaptureAllowed, policy_map, - true, &filtered_policies); + /* invert_bool_value */ true, &filtered_policies); // Use the pref for "debuggingFeaturesDisabled" to avoid duplicating the logic // of handling DeveloperToolsDisabled / DeveloperToolsAvailability policies. MapManagedIntPrefToBool( @@ -251,15 +251,17 @@ static_cast<int>( policy::DeveloperToolsPolicyHandler::Availability::kDisallowed), &filtered_policies); + MapBoolToBool("printingDisabled", policy::key::kPrintingEnabled, policy_map, + /* invert_bool_value */ true, &filtered_policies); MapBoolToBool("screenCaptureDisabled", policy::key::kDisableScreenshots, policy_map, false, &filtered_policies); MapIntToBool("shareLocationDisabled", policy::key::kDefaultGeolocationSetting, policy_map, 2 /*BlockGeolocation*/, &filtered_policies); MapBoolToBool("unmuteMicrophoneDisabled", policy::key::kAudioCaptureAllowed, - policy_map, true, &filtered_policies); + policy_map, /* invert_bool_value */ true, &filtered_policies); MapBoolToBool("mountPhysicalMediaDisabled", - policy::key::kExternalStorageDisabled, policy_map, false, - &filtered_policies); + policy::key::kExternalStorageDisabled, policy_map, + /* invert_bool_value */ false, &filtered_policies); MapObjectToPresenceBool("setWallpaperDisabled", policy::key::kWallpaperImage, policy_map, &filtered_policies, {"url", "hash"});
diff --git a/chrome/browser/chromeos/arc/policy/arc_policy_bridge_unittest.cc b/chrome/browser/chromeos/arc/policy/arc_policy_bridge_unittest.cc index 83c9acb..3ba3241 100644 --- a/chrome/browser/chromeos/arc/policy/arc_policy_bridge_unittest.cc +++ b/chrome/browser/chromeos/arc/policy/arc_policy_bridge_unittest.cc
@@ -316,6 +316,15 @@ "\",\"screenCaptureDisabled\":true}"); } +TEST_F(ArcPolicyBridgeTest, DisablePrintingTest) { + policy_map().Set(policy::key::kPrintingEnabled, + policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER, + policy::POLICY_SOURCE_CLOUD, + std::make_unique<base::Value>(false), nullptr); + GetPoliciesAndVerifyResult("{\"guid\":\"" + instance_guid() + + "\",\"printingDisabled\":true}"); +} + TEST_F(ArcPolicyBridgeTest, VideoCaptureAllowedTest) { policy_map().Set(policy::key::kVideoCaptureAllowed, policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_USER,
diff --git a/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc b/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc index 75f3308..b37dc2b36 100644 --- a/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc +++ b/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc
@@ -364,10 +364,16 @@ pref_content_settings_provider.SetWebsiteSetting( pattern, pattern, CONTENT_SETTINGS_TYPE_PLUGINS, resource1, new base::Value(CONTENT_SETTING_BLOCK)); - EXPECT_EQ(CONTENT_SETTING_BLOCK, - TestUtils::GetContentSetting(&pref_content_settings_provider, host, - host, CONTENT_SETTINGS_TYPE_PLUGINS, - resource1, false)); + + bool flash_is_ephemeral = + ContentSettingsRegistry::GetInstance() + ->Get(CONTENT_SETTINGS_TYPE_PLUGINS) + ->storage_behavior() == ContentSettingsInfo::EPHEMERAL; + ContentSetting expectation = + flash_is_ephemeral ? CONTENT_SETTING_DEFAULT : CONTENT_SETTING_BLOCK; + EXPECT_EQ(expectation, TestUtils::GetContentSetting( + &pref_content_settings_provider, host, host, + CONTENT_SETTINGS_TYPE_PLUGINS, resource1, false)); EXPECT_EQ(CONTENT_SETTING_DEFAULT, TestUtils::GetContentSetting(&pref_content_settings_provider, host, host, CONTENT_SETTINGS_TYPE_PLUGINS, @@ -603,4 +609,35 @@ provider.ShutdownOnUIThread(); } +// Tests if PrefProvider rejects storing ephemeral types. +TEST_F(PrefProviderTest, RejectEphemeralStorage) { + // Find an ephemeral type. + ContentSettingsType ephemeral_type = CONTENT_SETTINGS_NUM_TYPES; + ContentSettingsRegistry* registry = ContentSettingsRegistry::GetInstance(); + for (const content_settings::ContentSettingsInfo* item : *registry) { + if (item->storage_behavior() == ContentSettingsInfo::EPHEMERAL) { + ephemeral_type = item->website_settings_info()->type(); + break; + } + } + if (ephemeral_type == CONTENT_SETTINGS_NUM_TYPES) + return; + + sync_preferences::TestingPrefServiceSyncable prefs; + PrefProvider::RegisterProfilePrefs(prefs.registry()); + PrefProvider provider(&prefs, true /* regular */, + true /* store_last_modified */); + ContentSettingsPattern site_pattern = + ContentSettingsPattern::FromString("https://example.com"); + + std::unique_ptr<base::Value> value(new base::Value(CONTENT_SETTING_ALLOW)); + EXPECT_FALSE(provider.SetWebsiteSetting( + site_pattern, site_pattern, ephemeral_type, std::string(), value.get())); + std::unique_ptr<RuleIterator> rule_iterator = + provider.GetRuleIterator(ephemeral_type, std::string(), false); + EXPECT_EQ(nullptr, rule_iterator); + + provider.ShutdownOnUIThread(); +} + } // namespace content_settings
diff --git a/chrome/browser/content_settings/host_content_settings_map_unittest.cc b/chrome/browser/content_settings/host_content_settings_map_unittest.cc index 22b92bb..b0ccd22 100644 --- a/chrome/browser/content_settings/host_content_settings_map_unittest.cc +++ b/chrome/browser/content_settings/host_content_settings_map_unittest.cc
@@ -11,8 +11,10 @@ #include "base/json/json_reader.h" #include "base/json/json_writer.h" #include "base/memory/ptr_util.h" +#include "base/test/scoped_feature_list.h" #include "base/test/simple_test_clock.h" #include "base/time/time.h" +#include "build/build_config.h" #include "chrome/browser/content_settings/content_settings_mock_observer.h" #include "chrome/browser/content_settings/cookie_settings_factory.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" @@ -20,12 +22,17 @@ #include "chrome/common/url_constants.h" #include "chrome/test/base/testing_profile.h" #include "components/content_settings/core/browser/content_settings_details.h" +#include "components/content_settings/core/browser/content_settings_ephemeral_provider.h" +#include "components/content_settings/core/browser/content_settings_pref_provider.h" +#include "components/content_settings/core/browser/content_settings_registry.h" #include "components/content_settings/core/browser/cookie_settings.h" #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/content_settings/core/browser/user_modifiable_provider.h" #include "components/content_settings/core/browser/website_settings_info.h" #include "components/content_settings/core/browser/website_settings_registry.h" +#include "components/content_settings/core/common/features.h" #include "components/content_settings/core/common/pref_names.h" +#include "components/content_settings/core/test/content_settings_test_utils.h" #include "components/prefs/pref_service.h" #include "components/prefs/scoped_user_pref_update.h" #include "components/sync_preferences/testing_pref_service_syncable.h" @@ -1765,6 +1772,13 @@ // |CONTENT_SETTINGS_TYPE_PLUGINS_DATA| setting on the creation of a new // |HostContentSettingsMap|. TEST_F(HostContentSettingsMapTest, PluginDataMigration) { + // Avoid the test if Flash permissions are ephemeral. + if (content_settings::ContentSettingsRegistry::GetInstance() + ->Get(CONTENT_SETTINGS_TYPE_PLUGINS) + ->storage_behavior() == + content_settings::ContentSettingsInfo::EPHEMERAL) { + return; + } TestingProfile profile; // Set a website-specific Flash preference and a pattern exception. std::unique_ptr<base::Value> value = base::JSONReader::Read( @@ -1823,4 +1837,65 @@ CONTENT_SETTINGS_TYPE_PLUGINS_DATA, std::string(), nullptr)); } -#endif + +// Creates new instances of PrefProvider and EphemeralProvider and overrides +// them in |host_content_settings_map|. +void ReloadProviders(PrefService* pref_service, + HostContentSettingsMap* host_content_settings_map) { + auto pref_provider = std::make_unique<content_settings::PrefProvider>( + pref_service, false, true); + content_settings::TestUtils::OverrideProvider( + host_content_settings_map, std::move(pref_provider), + HostContentSettingsMap::PREF_PROVIDER); + + auto ephemeral_provider = + std::make_unique<content_settings::EphemeralProvider>(true); + content_settings::TestUtils::OverrideProvider( + host_content_settings_map, std::move(ephemeral_provider), + HostContentSettingsMap::EPHEMERAL_PROVIDER); +} + +// Tests if availability of EnableEphemeralFlashPermission switch results in +// Flash permissions being reset after restarting. +// The flag is not available on Android. +#if !defined(OS_ANDROID) +TEST_F(HostContentSettingsMapTest, FlashEphemeralPermissionSwitch) { + TestingProfile profile; + HostContentSettingsMap* map = + HostContentSettingsMapFactory::GetForProfile(&profile); + const GURL url("https://example.com"); + + map->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_PLUGINS, + CONTENT_SETTING_ASK); + + for (int ephemeral = 0; ephemeral < 2; ephemeral++) { + base::test::ScopedFeatureList feature_list; + if (ephemeral) { + feature_list.InitAndEnableFeature( + content_settings::features::kEnableEphemeralFlashPermission); + } else { + feature_list.InitAndDisableFeature( + content_settings::features::kEnableEphemeralFlashPermission); + } + content_settings::ContentSettingsRegistry::GetInstance()->ResetForTest(); + + ReloadProviders(profile.GetPrefs(), map); + map->SetContentSettingDefaultScope(url, url, CONTENT_SETTINGS_TYPE_PLUGINS, + std::string(), CONTENT_SETTING_ALLOW); + EXPECT_EQ(CONTENT_SETTING_ALLOW, + map->GetContentSetting(url, url, CONTENT_SETTINGS_TYPE_PLUGINS, + std::string())); + + ReloadProviders(profile.GetPrefs(), map); + ContentSetting expectation = + ephemeral ? CONTENT_SETTING_ASK : CONTENT_SETTING_ALLOW; + + EXPECT_EQ(expectation, + map->GetContentSetting(url, url, CONTENT_SETTINGS_TYPE_PLUGINS, + std::string())) + << ephemeral; + } +} +#endif // !defined(OS_ANDROID) + +#endif // BUILDFLAG(ENABLE_PLUGINS)
diff --git a/chrome/browser/extensions/OWNERS b/chrome/browser/extensions/OWNERS index 1919d86..00166a6 100644 --- a/chrome/browser/extensions/OWNERS +++ b/chrome/browser/extensions/OWNERS
@@ -6,6 +6,8 @@ per-file bookmark_app_*=mgiuca@chromium.org per-file bookmark_app_*=ortuno@chromium.org +per-file extension_gcm_app_handler*=file://chrome/browser/extensions/api/gcm/OWNERS + # For adding/renaming files for Chrome OS apps APIs. per-file BUILD.gn=stevenjb@chromium.org per-file BUILD.gn=tbarzic@chromium.org
diff --git a/chrome/browser/media/webrtc/webrtc_event_log_manager.cc b/chrome/browser/media/webrtc/webrtc_event_log_manager.cc index 5841018..5d019ce8 100644 --- a/chrome/browser/media/webrtc/webrtc_event_log_manager.cc +++ b/chrome/browser/media/webrtc/webrtc_event_log_manager.cc
@@ -96,7 +96,8 @@ DCHECK_CURRENTLY_ON(BrowserThread::UI); if (IsRemoteLoggingEnabled()) { - remote_logs_manager_ = std::make_unique<WebRtcRemoteEventLogManager>(this); + remote_logs_manager_ = + std::make_unique<WebRtcRemoteEventLogManager>(this, task_runner_); } DCHECK(!g_webrtc_event_log_manager); @@ -753,6 +754,17 @@ std::move(uploader_factory), std::move(reply))); } +void WebRtcEventLogManager::UploadConditionsHoldForTesting( + base::OnceCallback<void(bool)> callback) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + DCHECK(remote_logs_manager_); + task_runner_->PostTask( + FROM_HERE, + base::BindOnce( + &WebRtcRemoteEventLogManager::UploadConditionsHoldForTesting, + base::Unretained(remote_logs_manager_.get()), std::move(callback))); +} + scoped_refptr<base::SequencedTaskRunner>& WebRtcEventLogManager::GetTaskRunnerForTesting() { DCHECK_CURRENTLY_ON(BrowserThread::UI);
diff --git a/chrome/browser/media/webrtc/webrtc_event_log_manager.h b/chrome/browser/media/webrtc/webrtc_event_log_manager.h index e95fa0a7..74c081d6 100644 --- a/chrome/browser/media/webrtc/webrtc_event_log_manager.h +++ b/chrome/browser/media/webrtc/webrtc_event_log_manager.h
@@ -260,6 +260,12 @@ std::unique_ptr<WebRtcEventLogUploader::Factory> uploader_factory, base::OnceClosure reply); + // It is not always feasible to check in unit tests that uploads do not occur + // at a certain time, because that's (sometimes) racy with the event that + // suppresses the upload. We therefore allow unit tests to glimpse into the + // black box and verify that the box is aware that it should not upload. + void UploadConditionsHoldForTesting(base::OnceCallback<void(bool)> callback); + // This allows unit tests that do not wish to change the task runner to still // check when certain operations are finished. // TODO(crbug.com/775415): Remove this and use PostNullTaskForTesting instead.
diff --git a/chrome/browser/media/webrtc/webrtc_event_log_manager_remote.cc b/chrome/browser/media/webrtc/webrtc_event_log_manager_remote.cc index 3b601ab..bcb86de 100644 --- a/chrome/browser/media/webrtc/webrtc_event_log_manager_remote.cc +++ b/chrome/browser/media/webrtc/webrtc_event_log_manager_remote.cc
@@ -32,6 +32,9 @@ const base::TimeDelta kDefaultProactivePruningDelta = base::TimeDelta::FromMinutes(5); +const base::TimeDelta kDefaultWebRtcRemoteEventLogUploadDelay = + base::TimeDelta::FromSeconds(30); + bool AreLogParametersValid(size_t max_file_size_bytes, std::string* error_message) { if (max_file_size_bytes == kWebRtcEventLogManagerUnlimitedFileSize) { @@ -49,7 +52,7 @@ return true; } -base::Optional<base::TimeDelta> GetProactivePruningDelta() { +base::TimeDelta GetProactivePruningDelta() { if (base::CommandLine::ForCurrentProcess()->HasSwitch( ::switches::kWebRtcRemoteEventLogProactivePruningDelta)) { const std::string delta_seconds_str = @@ -57,11 +60,7 @@ ::switches::kWebRtcRemoteEventLogProactivePruningDelta); int64_t seconds; if (base::StringToInt64(delta_seconds_str, &seconds) && seconds >= 0) { - // A delta of 0 seconds is used to signal the intention of disabling - // proactive pruning altogether. (From the command line. Past the command - // line, we use an unset optional to signal that.) - return (seconds == 0) ? base::Optional<base::TimeDelta>() - : base::TimeDelta::FromSeconds(seconds); + return base::TimeDelta::FromSeconds(seconds); } else { LOG(WARNING) << "Proactive pruning delta could not be parsed."; } @@ -70,6 +69,23 @@ return kDefaultProactivePruningDelta; } +base::TimeDelta GetUploadDelay() { + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + ::switches::kWebRtcRemoteEventLogUploadDelayMs)) { + const std::string delta_seconds_str = + base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( + ::switches::kWebRtcRemoteEventLogUploadDelayMs); + int64_t ms; + if (base::StringToInt64(delta_seconds_str, &ms) && ms >= 0) { + return base::TimeDelta::FromMilliseconds(ms); + } else { + LOG(WARNING) << "Upload delay could not be parsed; using default delay."; + } + } + + return kDefaultWebRtcRemoteEventLogUploadDelay; +} + bool TimePointInRange(const base::Time& time_point, const base::Time& range_begin, const base::Time& range_end) { @@ -121,20 +137,23 @@ FILE_PATH_LITERAL("log"); WebRtcRemoteEventLogManager::WebRtcRemoteEventLogManager( - WebRtcRemoteEventLogsObserver* observer) + WebRtcRemoteEventLogsObserver* observer, + scoped_refptr<base::SequencedTaskRunner> task_runner) : upload_suppression_disabled_( base::CommandLine::ForCurrentProcess()->HasSwitch( ::switches::kWebRtcRemoteEventLogUploadNoSuppression)), proactive_prune_scheduling_delta_(GetProactivePruningDelta()), + upload_delay_(GetUploadDelay()), proactive_prune_scheduling_started_(false), observer_(observer), network_connection_tracker_(nullptr), - uploading_supported_for_connection_type_(false) { + uploading_supported_for_connection_type_(false), + scheduled_upload_tasks_(0), + task_runner_(task_runner) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - DETACH_FROM_SEQUENCE(io_task_sequence_checker_); // Proactive pruning would not do anything at the moment; it will be started // with the first enabled browser context. This will all have the benefit - // of doing so on io_task_sequence_checker_ rather than the UI thread. + // of doing so on |task_runner_| rather than the UI thread. } WebRtcRemoteEventLogManager::~WebRtcRemoteEventLogManager() { @@ -144,20 +163,18 @@ // the same file. // |network_connection_tracker_| might already have posted a task back to us, - // but it will not run, because |io_task_sequence_checker_|'s TaskRunner has - // already been stopped. + // but it will not run, because |task_runner_| has already been stopped. network_connection_tracker_->RemoveNetworkConnectionObserver(this); } void WebRtcRemoteEventLogManager::SetNetworkConnectionTracker( content::NetworkConnectionTracker* network_connection_tracker) { - DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_); + DCHECK(task_runner_->RunsTasksInCurrentSequence()); DCHECK(network_connection_tracker); DCHECK(!network_connection_tracker_); - // |this| is only destroyed (on the UI thread) after the TaskRunner to which - // |io_task_sequence_checker_| is bound stops, so both base::Unretained(this) - // and AddNetworkConnectionObserver() are safe. + // |this| is only destroyed (on the UI thread) after |task_runner_| stops, + // so both base::Unretained(this) and AddNetworkConnectionObserver() are safe. network_connection_tracker_ = network_connection_tracker; network_connection_tracker_->AddNetworkConnectionObserver(this); @@ -180,7 +197,7 @@ void WebRtcRemoteEventLogManager::SetUrlRequestContextGetter( net::URLRequestContextGetter* context_getter) { - DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_); + DCHECK(task_runner_->RunsTasksInCurrentSequence()); DCHECK(context_getter); DCHECK(!uploader_factory_); uploader_factory_ = @@ -190,7 +207,7 @@ void WebRtcRemoteEventLogManager::EnableForBrowserContext( BrowserContextId browser_context_id, const base::FilePath& browser_context_dir) { - DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_); + DCHECK(task_runner_->RunsTasksInCurrentSequence()); DCHECK(uploader_factory_) << "SetUrlRequestContextGetter() not called."; DCHECK(!BrowserContextEnabled(browser_context_id)) << "Already enabled."; @@ -206,7 +223,7 @@ enabled_browser_contexts_.insert(browser_context_id); - if (proactive_prune_scheduling_delta_.has_value() && + if (!proactive_prune_scheduling_delta_.is_zero() && !proactive_prune_scheduling_started_) { proactive_prune_scheduling_started_ = true; RecurringPendingLogsPrune(); @@ -216,7 +233,7 @@ // TODO(crbug.com/775415): Add unit tests. void WebRtcRemoteEventLogManager::DisableForBrowserContext( BrowserContextId browser_context_id) { - DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_); + DCHECK(task_runner_->RunsTasksInCurrentSequence()); if (!BrowserContextEnabled(browser_context_id)) { return; // Enabling may have failed due to lacking permissions. @@ -242,20 +259,31 @@ ++it; } } + + // Active logs may have been removed, which could remove upload suppression, + // or pending logs which were about to be uploaded may have been removed, + // so uploading may no longer be possible. + ManageUploadSchedule(); } bool WebRtcRemoteEventLogManager::PeerConnectionAdded( const PeerConnectionKey& key, const std::string& peer_connection_id) { - DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_); + DCHECK(task_runner_->RunsTasksInCurrentSequence()); + PrunePendingLogs(); // Infrequent event - good opportunity to prune. + const auto result = active_peer_connections_.emplace(key, peer_connection_id); + + // An upload about to start might need to be suppressed. + ManageUploadSchedule(); + return result.second; } bool WebRtcRemoteEventLogManager::PeerConnectionRemoved( const PeerConnectionKey& key) { - DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_); + DCHECK(task_runner_->RunsTasksInCurrentSequence()); PrunePendingLogs(); // Infrequent event - good opportunity to prune. @@ -268,7 +296,7 @@ active_peer_connections_.erase(peer_connection); - MaybeStartUploading(); + ManageUploadSchedule(); // Suppression might have been removed. return true; } @@ -281,7 +309,7 @@ size_t max_file_size_bytes, std::string* log_id, std::string* error_message) { - DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_); + DCHECK(task_runner_->RunsTasksInCurrentSequence()); DCHECK(log_id); DCHECK(log_id->empty()); DCHECK(error_message); @@ -332,7 +360,7 @@ bool WebRtcRemoteEventLogManager::EventLogWrite(const PeerConnectionKey& key, const std::string& message) { - DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_); + DCHECK(task_runner_->RunsTasksInCurrentSequence()); auto it = active_logs_.find(key); if (it == active_logs_.end()) { @@ -343,7 +371,7 @@ if (!write_successful || it->second.MaxSizeReached()) { CloseLogFile(it, /*make_pending=*/true); - MaybeStartUploading(); + ManageUploadSchedule(); } return write_successful; @@ -353,7 +381,7 @@ BrowserContextId browser_context_id, const base::Time& delete_begin, const base::Time& delete_end) { - DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_); + DCHECK(task_runner_->RunsTasksInCurrentSequence()); MaybeCancelActiveLogs(delete_begin, delete_end, browser_context_id); MaybeRemovePendingLogs(delete_begin, delete_end, browser_context_id); MaybeCancelUpload(delete_begin, delete_end, browser_context_id); @@ -361,11 +389,7 @@ void WebRtcRemoteEventLogManager::RenderProcessHostExitedDestroyed( int render_process_id) { - DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_); - - // Closing files will call MaybeStartUploading(). Avoid letting that upload - // any recently expired files. - PrunePendingLogs(); + DCHECK(task_runner_->RunsTasksInCurrentSequence()); // Remove all of the peer connections associated with this render process. // It's important to do this before closing the actual files, because closing @@ -385,59 +409,44 @@ while (log_it != active_logs_.end()) { if (log_it->first.render_process_id == render_process_id) { log_it = CloseLogFile(log_it, /*make_pending=*/true); - MaybeStartUploading(); } else { ++log_it; } } - // It could be that no files were closed, but some active PeerConnections that - // were suppressing uploading are now gone. - MaybeStartUploading(); + ManageUploadSchedule(); } -// TODO(crbug.com/775415): Fix the issue where OnConnectionChanged sometimes -// experiences toggling behavior shortly after a network change, by delaying -// potential uploads until a few seconds of stable connection. void WebRtcRemoteEventLogManager::OnConnectionChanged( network::mojom::ConnectionType type) { - const bool supported_before = uploading_supported_for_connection_type_; + // Even if switching from WiFi to Ethernet, or between to WiFi connections, + // reset the timer (if running) until an upload is permissible due to stable + // upload-supporting conditions. + time_when_upload_conditions_met_ = base::TimeTicks(); uploading_supported_for_connection_type_ = UploadSupportedUsingConnectionType(type); - if (uploading_supported_for_connection_type_ && !supported_before) { - MaybeStartUploading(); - } + ManageUploadSchedule(); // TODO(crbug.com/775415): Support pausing uploads when connection goes down, // or switches to an unsupported connection type. } -void WebRtcRemoteEventLogManager::OnWebRtcEventLogUploadComplete( - const base::FilePath& file_path, - bool upload_successful) { - DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_); - - // Post a task to deallocate the uploader (can't do this directly, - // because this function is a callback from the uploader), potentially - // starting a new upload for the next file. - // |this| is only destroyed (on the UI thread) after the TaskRunner to which - // |io_task_sequence_checker_| is bound stops, so base::Unretained(this) is - // safe. - base::SequencedTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::BindOnce( - &WebRtcRemoteEventLogManager::OnWebRtcEventLogUploadCompleteInternal, - base::Unretained(this))); -} - void WebRtcRemoteEventLogManager::SetWebRtcEventLogUploaderFactoryForTesting( std::unique_ptr<WebRtcEventLogUploader::Factory> uploader_factory) { - DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_); + DCHECK(task_runner_->RunsTasksInCurrentSequence()); uploader_factory_ = std::move(uploader_factory); } +void WebRtcRemoteEventLogManager::UploadConditionsHoldForTesting( + base::OnceCallback<void(bool)> callback) { + DCHECK(task_runner_->RunsTasksInCurrentSequence()); + content::BrowserThread::PostTask( + content::BrowserThread::UI, FROM_HERE, + base::BindOnce(std::move(callback), UploadConditionsHold())); +} + bool WebRtcRemoteEventLogManager::BrowserContextEnabled( BrowserContextId browser_context_id) const { const auto it = enabled_browser_contexts_.find(browser_context_id); @@ -447,7 +456,7 @@ WebRtcRemoteEventLogManager::LogFilesMap::iterator WebRtcRemoteEventLogManager::CloseLogFile(LogFilesMap::iterator it, bool make_pending) { - DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_); + DCHECK(task_runner_->RunsTasksInCurrentSequence()); const PeerConnectionKey peer_connection = it->first; // Copy, not reference. @@ -475,7 +484,7 @@ bool WebRtcRemoteEventLogManager::MaybeCreateLogsDirectory( const base::FilePath& remote_bound_logs_dir) { - DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_); + DCHECK(task_runner_->RunsTasksInCurrentSequence()); if (base::PathExists(remote_bound_logs_dir)) { if (!base::DirectoryExists(remote_bound_logs_dir)) { @@ -495,7 +504,7 @@ void WebRtcRemoteEventLogManager::AddPendingLogs( BrowserContextId browser_context_id, const base::FilePath& remote_bound_logs_dir) { - DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_); + DCHECK(task_runner_->RunsTasksInCurrentSequence()); base::FilePath::StringType pattern = base::FilePath::StringType(FILE_PATH_LITERAL("*")) + @@ -510,7 +519,7 @@ DCHECK(it.second); // No pre-existing entry. } - MaybeStartUploading(); + ManageUploadSchedule(); } bool WebRtcRemoteEventLogManager::StartWritingLog( @@ -519,7 +528,7 @@ size_t max_file_size_bytes, std::string* log_id, std::string* error_message) { - DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_); + DCHECK(task_runner_->RunsTasksInCurrentSequence()); // The log is assigned a universally unique ID (with high probability). const std::string id = CreateLogId(); @@ -560,7 +569,7 @@ void WebRtcRemoteEventLogManager::MaybeStopRemoteLogging( const PeerConnectionKey& key) { - DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_); + DCHECK(task_runner_->RunsTasksInCurrentSequence()); const auto it = active_logs_.find(key); if (it == active_logs_.end()) { @@ -569,39 +578,37 @@ CloseLogFile(it, /*make_pending=*/true); - MaybeStartUploading(); + ManageUploadSchedule(); } void WebRtcRemoteEventLogManager::PrunePendingLogs() { - DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_); + DCHECK(task_runner_->RunsTasksInCurrentSequence()); MaybeRemovePendingLogs( base::Time::Min(), base::Time::Now() - kRemoteBoundWebRtcEventLogsMaxRetention); } void WebRtcRemoteEventLogManager::RecurringPendingLogsPrune() { - DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_); - DCHECK(proactive_prune_scheduling_delta_.has_value()); - DCHECK_GT(*proactive_prune_scheduling_delta_, base::TimeDelta()); + DCHECK(task_runner_->RunsTasksInCurrentSequence()); + DCHECK(!proactive_prune_scheduling_delta_.is_zero()); DCHECK(proactive_prune_scheduling_started_); PrunePendingLogs(); - // |this| is only destroyed (on the UI thread) after the TaskRunner to which - // |io_task_sequence_checker_| is bound stops, so base::Unretained(this) is - // safe. + // |this| is only destroyed (on the UI thread) after |task_runner_| stops, + // so both base::Unretained(this) is safe. base::SequencedTaskRunnerHandle::Get()->PostDelayedTask( FROM_HERE, base::BindOnce(&WebRtcRemoteEventLogManager::RecurringPendingLogsPrune, base::Unretained(this)), - *proactive_prune_scheduling_delta_); + proactive_prune_scheduling_delta_); } void WebRtcRemoteEventLogManager::MaybeRemovePendingLogs( const base::Time& delete_begin, const base::Time& delete_end, base::Optional<BrowserContextId> browser_context_id) { - DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_); + DCHECK(task_runner_->RunsTasksInCurrentSequence()); for (auto it = pending_logs_.begin(); it != pending_logs_.end();) { if (LogFileMatchesFilter(it->browser_context_id, it->last_modified, @@ -616,6 +623,11 @@ ++it; } } + + // The last pending log might have been removed. + if (!UploadConditionsHold()) { + time_when_upload_conditions_met_ = base::TimeTicks(); + } } void WebRtcRemoteEventLogManager::MaybeCancelActiveLogs( @@ -652,7 +664,7 @@ const bool cancelled = uploader_->Cancel(); if (cancelled) { uploader_.reset(); - MaybeStartUploading(); + ManageUploadSchedule(); } } } @@ -674,7 +686,7 @@ bool WebRtcRemoteEventLogManager::AdditionalActiveLogAllowed( BrowserContextId browser_context_id) const { - DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_); + DCHECK(task_runner_->RunsTasksInCurrentSequence()); // Limit over concurrently active logs (across BrowserContext-s). if (active_logs_.size() >= kMaxActiveRemoteBoundWebRtcEventLogs) { @@ -696,55 +708,107 @@ return active_count + pending_count < kMaxPendingRemoteBoundWebRtcEventLogs; } -bool WebRtcRemoteEventLogManager::UploadingAllowed() const { - DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_); - if (!uploading_supported_for_connection_type_) { - return false; - } - return upload_suppression_disabled_ || active_peer_connections_.empty(); +bool WebRtcRemoteEventLogManager::UploadSuppressed() const { + DCHECK(task_runner_->RunsTasksInCurrentSequence()); + return !upload_suppression_disabled_ && !active_peer_connections_.empty(); } -void WebRtcRemoteEventLogManager::MaybeStartUploading() { - DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_); +bool WebRtcRemoteEventLogManager::UploadConditionsHold() const { + return !uploader_ && !pending_logs_.empty() && !UploadSuppressed() && + uploading_supported_for_connection_type_; +} + +void WebRtcRemoteEventLogManager::ManageUploadSchedule() { + DCHECK(task_runner_->RunsTasksInCurrentSequence()); PrunePendingLogs(); // Avoid uploading freshly expired files. - if (uploader_) { - return; // Upload already underway. - } - - if (pending_logs_.empty()) { - return; // Nothing to upload. - } - - if (!UploadingAllowed()) { + if (!UploadConditionsHold()) { + time_when_upload_conditions_met_ = base::TimeTicks(); return; } - // The uploader takes ownership of the file; it's no longer considered to be - // pending. (If the upload fails, the log will be deleted.) - // TODO(crbug.com/775415): Add more refined retry behavior, so that we would - // not delete the log permanently if the network is just down, on the one - // hand, but also would not be uploading unlimited data on endless retries on - // the other hand. - // TODO(crbug.com/814362): Delay the upload's start. - // TODO(crbug.com/775415): Rename the file before uploading, so that we would - // not retry the upload after restarting Chrome, if the upload is interrupted. - uploader_ = uploader_factory_->Create(*pending_logs_.begin(), this); - pending_logs_.erase(pending_logs_.begin()); + if (!time_when_upload_conditions_met_.is_null()) { + // Conditions have been holding for a while; MaybeStartUploading() has + // already been scheduled when |time_when_upload_conditions_met_| was set. + return; + } + + ++scheduled_upload_tasks_; + + time_when_upload_conditions_met_ = base::TimeTicks::Now(); + + task_runner_->PostDelayedTask( + FROM_HERE, + base::BindOnce(&WebRtcRemoteEventLogManager::MaybeStartUploading, + base::Unretained(this)), + upload_delay_); } -void WebRtcRemoteEventLogManager::OnWebRtcEventLogUploadCompleteInternal() { - DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_); +void WebRtcRemoteEventLogManager::MaybeStartUploading() { + DCHECK(task_runner_->RunsTasksInCurrentSequence()); + DCHECK_GT(scheduled_upload_tasks_, 0u); + + // Since MaybeStartUploading() was scheduled, conditions might have stopped + // holding at some point. They may have even stopped and started several times + // while the currently running task was scheduled, meaning several tasks could + // be pending now, only the last of which should really end up uploading. + + if (time_when_upload_conditions_met_.is_null()) { + // Conditions no longer hold; no way to know how many (now irrelevant) other + // similar tasks are pending, if any. + } else if (base::TimeTicks::Now() - time_when_upload_conditions_met_ < + upload_delay_) { + // Conditions have stopped holding, then started holding again; there has + // to be a more recent task scheduled, that will take over later. + DCHECK_GT(scheduled_upload_tasks_, 1u); + } else { + // It's up to the rest of the code to turn |scheduled_upload_tasks_| off + // if the conditions have at some point stopped holding, or it wouldn't + // know to turn it on when they resume. + DCHECK(UploadConditionsHold()); + + // When the upload we're about to start finishes, there will be another + // delay of length |upload_delay_| before the next one starts. + time_when_upload_conditions_met_ = base::TimeTicks(); + + // |this| is only destroyed (on the UI thread) after |task_runner_| stops, + // so base::Unretained(this) is safe. (|uploader_| and |uploader_factory_| + // live on |task_runner_|.) + auto callback = base::BindOnce( + &WebRtcRemoteEventLogManager::OnWebRtcEventLogUploadComplete, + base::Unretained(this)); + + // The uploader takes ownership of the file; it's no longer considered to be + // pending. (If the upload fails, the log will be deleted.) + // TODO(crbug.com/775415): Add more refined retry behavior, so that we would + // not delete the log permanently if the network is just down, on the one + // hand, but also would not be uploading unlimited data on endless retries + // on the other hand. + // TODO(crbug.com/775415): Rename the file before uploading, so that we + // would not retry the upload after restarting Chrome, if the upload is + // interrupted. + uploader_ = + uploader_factory_->Create(*pending_logs_.begin(), std::move(callback)); + pending_logs_.erase(pending_logs_.begin()); + } + + --scheduled_upload_tasks_; +} + +void WebRtcRemoteEventLogManager::OnWebRtcEventLogUploadComplete( + const base::FilePath& log_file, + bool upload_successful) { + DCHECK(task_runner_->RunsTasksInCurrentSequence()); uploader_.reset(); - MaybeStartUploading(); + ManageUploadSchedule(); } bool WebRtcRemoteEventLogManager::FindPeerConnection( int render_process_id, const std::string& peer_connection_id, PeerConnectionKey* key) const { - DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_); + DCHECK(task_runner_->RunsTasksInCurrentSequence()); const auto it = FindNextPeerConnection(active_peer_connections_.cbegin(), render_process_id, peer_connection_id); @@ -768,7 +832,7 @@ std::map<PeerConnectionKey, const std::string>::const_iterator begin, int render_process_id, const std::string& peer_connection_id) const { - DCHECK_CALLED_ON_VALID_SEQUENCE(io_task_sequence_checker_); + DCHECK(task_runner_->RunsTasksInCurrentSequence()); const auto end = active_peer_connections_.cend(); for (auto it = begin; it != end; ++it) { if (it->first.render_process_id == render_process_id &&
diff --git a/chrome/browser/media/webrtc/webrtc_event_log_manager_remote.h b/chrome/browser/media/webrtc/webrtc_event_log_manager_remote.h index 0af448a..4d84049 100644 --- a/chrome/browser/media/webrtc/webrtc_event_log_manager_remote.h +++ b/chrome/browser/media/webrtc/webrtc_event_log_manager_remote.h
@@ -10,7 +10,7 @@ #include <vector> #include "base/optional.h" -#include "base/sequence_checker.h" +#include "base/sequenced_task_runner.h" #include "base/time/time.h" #include "chrome/browser/media/webrtc/webrtc_event_log_manager_common.h" #include "chrome/browser/media/webrtc/webrtc_event_log_uploader.h" @@ -23,14 +23,15 @@ } // namespace net class WebRtcRemoteEventLogManager final - : public content::NetworkConnectionTracker::NetworkConnectionObserver, - public WebRtcEventLogUploaderObserver { + : public content::NetworkConnectionTracker::NetworkConnectionObserver { using BrowserContextId = WebRtcEventLogPeerConnectionKey::BrowserContextId; using LogFilesMap = std::map<WebRtcEventLogPeerConnectionKey, LogFile>; using PeerConnectionKey = WebRtcEventLogPeerConnectionKey; public: - explicit WebRtcRemoteEventLogManager(WebRtcRemoteEventLogsObserver* observer); + WebRtcRemoteEventLogManager( + WebRtcRemoteEventLogsObserver* observer, + scoped_refptr<base::SequencedTaskRunner> task_runner); ~WebRtcRemoteEventLogManager() override; // Sets a content::NetworkConnectionTracker which will be used to track @@ -132,10 +133,6 @@ // content::NetworkConnectionTracker::NetworkConnectionObserver implementation void OnConnectionChanged(network::mojom::ConnectionType type) override; - // WebRtcEventLogUploaderObserver implementation. - void OnWebRtcEventLogUploadComplete(const base::FilePath& file_path, - bool upload_successful) override; - // Unit tests may use this to inject null uploaders, or ones which are // directly controlled by the unit test (succeed or fail according to the // test's needs). @@ -146,6 +143,10 @@ void SetWebRtcEventLogUploaderFactoryForTesting( std::unique_ptr<WebRtcEventLogUploader::Factory> uploader_factory); + // Exposes UploadConditionsHold() to unit tests. See WebRtcEventLogManager's + // documentation for the rationale. + void UploadConditionsHoldForTesting(base::OnceCallback<void(bool)> callback); + private: // Checks whether a browser context has already been enabled via a call to // EnableForBrowserContext(), and not yet disabled using a call to @@ -245,22 +246,35 @@ // to limitations on the numbers active and pending logs). bool AdditionalActiveLogAllowed(BrowserContextId browser_context_id) const; - // Initiating a new upload is only allowed when there are no active peer - // connection which might be adversely affected by the bandwidth consumption - // of the upload. + // Uploading suppressed while active peer connections exist (unless + // suppression) is turned off from the command line. + bool UploadSuppressed() const; - // This can be overridden by a command line flag - see - // kWebRtcRemoteEventLogUploadNoSuppression. - // TODO(crbug.com/775415): Add support for pausing/resuming an upload when - // peer connections are added/removed after an upload was already initiated. - bool UploadingAllowed() const; + // Check whether all the conditions necessary for uploading log files are + // currently satisfied. + // 1. There may be no active peer connections which might be adversely + // affected by the bandwidth consumption of the upload. + // 2. Chrome has a network connection, and that conneciton is either a wired + // one, or WiFi. (That is, not 3G, etc.) + // 3. Naturally, a file pending upload must exist. + bool UploadConditionsHold() const; - // If no upload is in progress, and if uploading is currently permissible, - // start a new upload. + // When the conditions necessary for uploading first hold, schedule a delayed + // task to upload (MaybeStartUploading). If they ever stop holding, void it. + void ManageUploadSchedule(); + + // Posted as a delayed task by ManageUploadSchedule. If not voided until + // executed, will initiate an upload of the next log file. void MaybeStartUploading(); + // Callback for the success/failure of an upload. // When an upload is complete, it might be time to upload the next file. - void OnWebRtcEventLogUploadCompleteInternal(); + // Note: |log_file| and |upload_successful| are ignored in production; they + // are used in unit tests, so we keep them here to make things simpler, so + // that this method would match WebRtcEventLogUploader::UploadResultCallback + // without adaptation. + void OnWebRtcEventLogUploadComplete(const base::FilePath& log_file, + bool upload_successful); // Given a renderer process ID and peer connection ID (a string naming the // peer connection), find the peer connection to which they refer. @@ -278,19 +292,19 @@ int render_process_id, const std::string& peer_connection_id) const; - // This object is expected to be created and destroyed on the UI thread, - // but live on its owner's internal, IO-capable task queue. - SEQUENCE_CHECKER(io_task_sequence_checker_); - // Normally, uploading is suppressed while there are active peer connections. // This may be disabled from the command line. const bool upload_suppression_disabled_; - // Proactive pruning will be done only if this has a value, in which case, + // Proactive pruning will be done only if this is non-zero, in which case, // every |proactive_prune_scheduling_delta_|, pending logs will be pruned. // This avoids them staying around on disk for longer than their expiration // if no event occurs which triggers reactive pruning. - const base::Optional<base::TimeDelta> proactive_prune_scheduling_delta_; + const base::TimeDelta proactive_prune_scheduling_delta_; + + // The conditions for upload must hold for this much time, uninterrupted, + // before an upload may be initiated. + const base::TimeDelta upload_delay_; // Proactive pruning, if enabled, starts with the first enabled browser // context. To avoid unnecessary complexity, if that browser context is @@ -329,11 +343,26 @@ // which we may upload. bool uploading_supported_for_connection_type_; + // If the conditions for initiating an upload do not hold, this will be + // set to an empty base::TimeTicks. + // If the conditions were found to hold, this will record the time when they + // started holding. (It will be set back to 0 if they ever cease holding.) + base::TimeTicks time_when_upload_conditions_met_; + + // This is a vehicle for DCHECKs to ensure code sanity. It counts the number + // of scheduled tasks of MaybeStartUploading(), and proves that we never + // end up with a scheduled upload that never occurs. + size_t scheduled_upload_tasks_; + // Producer of uploader objects. (In unit tests, this would create // null-implementation uploaders, or uploaders whose behavior is controlled // by the unit test.) std::unique_ptr<WebRtcEventLogUploader::Factory> uploader_factory_; + // |this| is created and destroyed on the UI thread, but operates on the + // following IO-capable sequenced task runner. + scoped_refptr<base::SequencedTaskRunner> task_runner_; + DISALLOW_COPY_AND_ASSIGN(WebRtcRemoteEventLogManager); };
diff --git a/chrome/browser/media/webrtc/webrtc_event_log_manager_unittest.cc b/chrome/browser/media/webrtc/webrtc_event_log_manager_unittest.cc index f55f049f..6f3ac11 100644 --- a/chrome/browser/media/webrtc/webrtc_event_log_manager_unittest.cc +++ b/chrome/browser/media/webrtc/webrtc_event_log_manager_unittest.cc
@@ -32,6 +32,7 @@ #include "base/test/scoped_command_line.h" #include "base/test/scoped_feature_list.h" #include "base/test/simple_test_clock.h" +#include "base/threading/sequenced_task_runner_handle.h" #include "base/time/time.h" #include "build/build_config.h" #include "chrome/browser/media/webrtc/webrtc_event_log_manager_common.h" @@ -151,7 +152,7 @@ std::unique_ptr<WebRtcEventLogUploader> Create( const WebRtcLogFileInfo& log_file, - WebRtcEventLogUploaderObserver* observer) override { + UploadResultCallback callback) override { return std::make_unique<NullWebRtcEventLogUploader>( log_file, cancellation_expected_); } @@ -561,6 +562,22 @@ return GetUniqueId(key.render_process_id, key.lid); } + bool UploadConditionsHold() { + base::RunLoop run_loop; + bool result; + + auto callback = [](base::RunLoop* run_loop, bool* result_out, bool result) { + *result_out = result; + run_loop->QuitWhenIdle(); + }; + + event_log_manager_->UploadConditionsHoldForTesting( + base::BindOnce(callback, &run_loop, &result)); + run_loop.Run(); + + return result; + } + // Testing utilities. base::test::ScopedFeatureList scoped_feature_list_; base::test::ScopedCommandLine scoped_command_line_; @@ -643,6 +660,11 @@ public: WebRtcEventLogManagerTest() { scoped_feature_list_.InitAndEnableFeature(features::kWebRtcRemoteEventLog); + + // Use a low delay, or the tests would run for quite a long time. + scoped_command_line_.GetProcessCommandLine()->AppendSwitchASCII( + ::switches::kWebRtcRemoteEventLogUploadDelayMs, "100"); + event_log_manager_ = WebRtcEventLogManager::CreateSingletonInstance(); } @@ -753,8 +775,14 @@ public: WebRtcEventLogManagerTestUploadSuppressionDisablingFlag() { scoped_feature_list_.InitAndEnableFeature(features::kWebRtcRemoteEventLog); + scoped_command_line_.GetProcessCommandLine()->AppendSwitch( ::switches::kWebRtcRemoteEventLogUploadNoSuppression); + + // Use a low delay, or the tests would run for quite a long time. + scoped_command_line_.GetProcessCommandLine()->AppendSwitchASCII( + ::switches::kWebRtcRemoteEventLogUploadDelayMs, "100"); + event_log_manager_ = WebRtcEventLogManager::CreateSingletonInstance(); } @@ -773,6 +801,11 @@ supported_type_(std::get<1>(GetParam())), unsupported_type_(std::get<2>(GetParam())) { scoped_feature_list_.InitAndEnableFeature(features::kWebRtcRemoteEventLog); + + // Use a low delay, or the tests would run for quite a long time. + scoped_command_line_.GetProcessCommandLine()->AppendSwitchASCII( + ::switches::kWebRtcRemoteEventLogUploadDelayMs, "100"); + event_log_manager_ = WebRtcEventLogManager::CreateSingletonInstance(); } @@ -817,6 +850,41 @@ base::File file_; }; +class WebRtcEventLogManagerTestUploadDelay + : public WebRtcEventLogManagerTestBase { + public: + WebRtcEventLogManagerTestUploadDelay() {} + + void SetUp() override { + // Intercept and block the call to SetUp(). The test body will call + // the version that sets an upload delay instead. + } + + void SetUp(size_t upload_delay_ms) { + scoped_feature_list_.InitAndEnableFeature(features::kWebRtcRemoteEventLog); + + scoped_command_line_.GetProcessCommandLine()->AppendSwitchASCII( + ::switches::kWebRtcRemoteEventLogUploadDelayMs, + std::to_string(upload_delay_ms)); + + event_log_manager_ = WebRtcEventLogManager::CreateSingletonInstance(); + + WebRtcEventLogManagerTestBase::SetUp(); + } + + ~WebRtcEventLogManagerTestUploadDelay() override = default; + + // There's a trade-off between the test runtime and the likelihood of a + // false-positive (lowered when the time is increased). + // Since false-positives can be caught handled even if only manifesting + // occasionally, this value should be enough. + static const size_t kDefaultUploadDelayMs = 500; + + // For tests where we don't intend to wait, prevent flakiness by setting + // an unrealistically long delay. + static const size_t kIntentionallyExcessiveDelayMs = 1000 * 1000 * 1000; +}; + namespace { class PeerConnectionTrackerProxyForTesting @@ -872,7 +940,7 @@ std::unique_ptr<WebRtcEventLogUploader> Create( const WebRtcLogFileInfo& log_file, - WebRtcEventLogUploaderObserver* observer) override { + UploadResultCallback callback) override { if (expected_files_.empty()) { EXPECT_FALSE(true); // More files uploaded than expected. } else { @@ -891,7 +959,7 @@ } return std::make_unique<FileListExpectingWebRtcEventLogUploader>( - log_file, result_, observer); + log_file, result_, std::move(callback)); } private: @@ -902,12 +970,12 @@ // The logic is in the factory; the uploader just reports success so that the // next file may become eligible for uploading. - FileListExpectingWebRtcEventLogUploader( - const WebRtcLogFileInfo& log_file, - bool result, - WebRtcEventLogUploaderObserver* observer) + FileListExpectingWebRtcEventLogUploader(const WebRtcLogFileInfo& log_file, + bool result, + UploadResultCallback callback) : log_file_(log_file) { - observer->OnWebRtcEventLogUploadComplete(log_file.path, result); + base::SequencedTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), log_file_.path, result)); } ~FileListExpectingWebRtcEventLogUploader() override = default; @@ -2299,6 +2367,8 @@ // Peer connection removal triggers next upload. ASSERT_TRUE(PeerConnectionRemoved(key.render_process_id, key.lid)); + WaitForPendingTasks(&run_loop); + EXPECT_TRUE(base::IsDirectoryEmpty(RemoteBoundLogsDir(browser_context_))); } @@ -3407,6 +3477,117 @@ ::testing::Values(network::mojom::ConnectionType::CONNECTION_NONE, network::mojom::ConnectionType::CONNECTION_4G))); +TEST_F(WebRtcEventLogManagerTestUploadDelay, DoNotInitiateUploadBeforeDelay) { + SetUp(kIntentionallyExcessiveDelayMs); + + const auto key = GetPeerConnectionKey(rph_.get(), 1); + ASSERT_TRUE(PeerConnectionAdded(key.render_process_id, key.lid)); + ASSERT_TRUE(StartRemoteLogging(key.render_process_id, GetUniqueId(key))); + + std::list<WebRtcLogFileInfo> empty_list; + base::RunLoop run_loop; + SetWebRtcEventLogUploaderFactoryForTesting( + std::make_unique<FileListExpectingWebRtcEventLogUploader::Factory>( + &empty_list, true, &run_loop)); + + // Change log file from ACTIVE to PENDING. + ASSERT_TRUE(PeerConnectionRemoved(key.render_process_id, key.lid)); + + // Wait a bit and see that the upload was not initiated. (Due to technical + // constraints, we cannot wait forever.) + base::WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL, + base::WaitableEvent::InitialState::NOT_SIGNALED); + event.TimedWait(base::TimeDelta::FromMilliseconds(500)); + + WaitForPendingTasks(&run_loop); +} + +// WhenPeerConnectionRemovedFinishedRemoteLogUploadedAndFileDeleted has some +// overlap with this, but we still include this test for explicitness and +// clarity. +TEST_F(WebRtcEventLogManagerTestUploadDelay, InitiateUploadAfterDelay) { + SetUp(kDefaultUploadDelayMs); + + const auto key = GetPeerConnectionKey(rph_.get(), 1); + base::Optional<base::FilePath> log_file; + ON_CALL(remote_observer_, OnRemoteLogStarted(key, _)) + .WillByDefault(Invoke(SaveFilePathTo(&log_file))); + ASSERT_TRUE(PeerConnectionAdded(key.render_process_id, key.lid)); + ASSERT_TRUE(StartRemoteLogging(key.render_process_id, GetUniqueId(key))); + ASSERT_TRUE(log_file); + + base::RunLoop run_loop; + std::list<WebRtcLogFileInfo> expected_files = {WebRtcLogFileInfo( + browser_context_id_, *log_file, GetLastModificationTime(*log_file))}; + SetWebRtcEventLogUploaderFactoryForTesting( + std::make_unique<FileListExpectingWebRtcEventLogUploader::Factory>( + &expected_files, true, &run_loop)); + + // Change log file from ACTIVE to PENDING. + ASSERT_TRUE(PeerConnectionRemoved(key.render_process_id, key.lid)); + + WaitForPendingTasks(&run_loop); +} + +TEST_F(WebRtcEventLogManagerTestUploadDelay, + PeerConnectionAddedDuringDelaySuppressesUpload) { + SetUp(kIntentionallyExcessiveDelayMs); + + const auto key1 = GetPeerConnectionKey(rph_.get(), 1); + const auto key2 = GetPeerConnectionKey(rph_.get(), 2); + + ASSERT_TRUE(PeerConnectionAdded(key1.render_process_id, key1.lid)); + ASSERT_TRUE(StartRemoteLogging(key1.render_process_id, GetUniqueId(key1))); + + std::list<WebRtcLogFileInfo> empty_list; + base::RunLoop run_loop; + SetWebRtcEventLogUploaderFactoryForTesting( + std::make_unique<FileListExpectingWebRtcEventLogUploader::Factory>( + &empty_list, true, &run_loop)); + + // Change log file from ACTIVE to PENDING. + ASSERT_TRUE(PeerConnectionRemoved(key1.render_process_id, key1.lid)); + + // Test focus - after adding a peer connection, the conditions for the upload + // are no longer considered to hold. + // (Test implemented with a glimpse into the black box due to technical + // limitations and the desire to avoid flakiness.) + ASSERT_TRUE(PeerConnectionAdded(key2.render_process_id, key2.lid)); + EXPECT_FALSE(UploadConditionsHold()); + + WaitForPendingTasks(&run_loop); +} + +TEST_F(WebRtcEventLogManagerTestUploadDelay, + ClearCacheForBrowserContextDuringDelayCancelsItsUpload) { + SetUp(kIntentionallyExcessiveDelayMs); + + const auto key = GetPeerConnectionKey(rph_.get(), 1); + + ASSERT_TRUE(PeerConnectionAdded(key.render_process_id, key.lid)); + ASSERT_TRUE(StartRemoteLogging(key.render_process_id, GetUniqueId(key))); + + std::list<WebRtcLogFileInfo> empty_list; + base::RunLoop run_loop; + SetWebRtcEventLogUploaderFactoryForTesting( + std::make_unique<FileListExpectingWebRtcEventLogUploader::Factory>( + &empty_list, true, &run_loop)); + + // Change log file from ACTIVE to PENDING. + ASSERT_TRUE(PeerConnectionRemoved(key.render_process_id, key.lid)); + + // Test focus - after clearing browser cache, the conditions for the upload + // are no longer considered to hold, because the file about to be uploaded + // was deleted. + // (Test implemented with a glimpse into the black box due to technical + // limitations and the desire to avoid flakiness.) + ClearCacheForBrowserContext(browser_context_, base::Time::Min(), + base::Time::Max()); + EXPECT_FALSE(UploadConditionsHold()); + + WaitForPendingTasks(&run_loop); +} + #else // defined(OS_ANDROID) class WebRtcEventLogManagerTestOnMobileDevices
diff --git a/chrome/browser/media/webrtc/webrtc_event_log_uploader.cc b/chrome/browser/media/webrtc/webrtc_event_log_uploader.cc index 79192fb..f683e4b 100644 --- a/chrome/browser/media/webrtc/webrtc_event_log_uploader.cc +++ b/chrome/browser/media/webrtc/webrtc_event_log_uploader.cc
@@ -104,22 +104,21 @@ : request_context_getter_(request_context_getter) {} std::unique_ptr<WebRtcEventLogUploader> -WebRtcEventLogUploaderImpl::Factory::Create( - const WebRtcLogFileInfo& log_file, - WebRtcEventLogUploaderObserver* observer) { - DCHECK(observer); +WebRtcEventLogUploaderImpl::Factory::Create(const WebRtcLogFileInfo& log_file, + UploadResultCallback callback) { return std::make_unique<WebRtcEventLogUploaderImpl>( - request_context_getter_, log_file, observer, kMaxRemoteLogFileSizeBytes); + request_context_getter_, log_file, std::move(callback), + kMaxRemoteLogFileSizeBytes); } std::unique_ptr<WebRtcEventLogUploader> WebRtcEventLogUploaderImpl::Factory::CreateWithCustomMaxSizeForTesting( const WebRtcLogFileInfo& log_file, - WebRtcEventLogUploaderObserver* observer, + UploadResultCallback callback, size_t max_log_file_size_bytes) { - DCHECK(observer); return std::make_unique<WebRtcEventLogUploaderImpl>( - request_context_getter_, log_file, observer, max_log_file_size_bytes); + request_context_getter_, log_file, std::move(callback), + max_log_file_size_bytes); } WebRtcEventLogUploaderImpl::Delegate::Delegate( @@ -156,16 +155,14 @@ WebRtcEventLogUploaderImpl::WebRtcEventLogUploaderImpl( net::URLRequestContextGetter* request_context_getter, const WebRtcLogFileInfo& log_file, - WebRtcEventLogUploaderObserver* observer, + UploadResultCallback callback, size_t max_log_file_size_bytes) : delegate_(this), request_context_getter_(request_context_getter), log_file_(log_file), - observer_(observer), + callback_(std::move(callback)), max_log_file_size_bytes_(max_log_file_size_bytes), io_task_runner_(base::SequencedTaskRunnerHandle::Get()) { - DCHECK(observer); - std::string upload_data; if (!PrepareUploadData(&upload_data)) { @@ -305,7 +302,8 @@ // TODO(crbug.com/775415): Provide refined retrial behavior. DeleteLogFile(); - observer_->OnWebRtcEventLogUploadComplete(log_file_.path, result); + io_task_runner_->PostTask( + FROM_HERE, base::BindOnce(std::move(callback_), log_file_.path, result)); } void WebRtcEventLogUploaderImpl::DeleteLogFile() {
diff --git a/chrome/browser/media/webrtc/webrtc_event_log_uploader.h b/chrome/browser/media/webrtc/webrtc_event_log_uploader.h index 70213bf5..61b3288 100644 --- a/chrome/browser/media/webrtc/webrtc_event_log_uploader.h +++ b/chrome/browser/media/webrtc/webrtc_event_log_uploader.h
@@ -18,24 +18,16 @@ class URLRequestContextGetter; } // namespace net -// A class implementing this interace can register for notification of an -// upload's eventual result (success/failure). -class WebRtcEventLogUploaderObserver { - public: - virtual void OnWebRtcEventLogUploadComplete(const base::FilePath& log_file, - bool upload_successful) = 0; - - protected: - virtual ~WebRtcEventLogUploaderObserver() = default; -}; - -// A sublcass of this interface would take ownership of a file, and either -// upload it to a remote server (actual implementation), or pretend to do -// so (in unit tests). It will typically take on an observer of type -// WebRtcEventLogUploaderObserver, and inform it of the success or failure -// of the upload. +// A sublcass of this interface will take ownership of a file, and either +// upload it to a remote server (actual implementation), or pretend to do so +// (in unit tests). Upon completion, success/failure will be reported by posting +// an UploadResultCallback task to the task queue on which this object lives. class WebRtcEventLogUploader { public: + using UploadResultCallback = + base::OnceCallback<void(const base::FilePath& log_file, + bool upload_successful)>; + // Since we'll need more than one instance of the abstract // WebRtcEventLogUploader, we'll need an abstract factory for it. class Factory { @@ -50,7 +42,7 @@ // the file after invoking Create(). virtual std::unique_ptr<WebRtcEventLogUploader> Create( const WebRtcLogFileInfo& log_file, - WebRtcEventLogUploaderObserver* observer) = 0; + UploadResultCallback callback) = 0; }; virtual ~WebRtcEventLogUploader() = default; @@ -77,14 +69,14 @@ std::unique_ptr<WebRtcEventLogUploader> Create( const WebRtcLogFileInfo& log_file, - WebRtcEventLogUploaderObserver* observer) override; + UploadResultCallback callback) override; protected: friend class WebRtcEventLogUploaderImplTest; std::unique_ptr<WebRtcEventLogUploader> CreateWithCustomMaxSizeForTesting( const WebRtcLogFileInfo& log_file, - WebRtcEventLogUploaderObserver* observer, + UploadResultCallback callback, size_t max_remote_log_file_size_bytes); private: @@ -94,7 +86,7 @@ WebRtcEventLogUploaderImpl( net::URLRequestContextGetter* request_context_getter, const WebRtcLogFileInfo& log_file, - WebRtcEventLogUploaderObserver* observer, + UploadResultCallback callback, size_t max_remote_log_file_size_bytes); ~WebRtcEventLogUploaderImpl() override; @@ -119,7 +111,7 @@ // permissible afterwards. void OnURLFetchComplete(const net::URLFetcher* source); - // Cleanup and reporting to |observer_|. + // Cleanup and posting of the result callback. void ReportResult(bool result); // Remove the log file which is owned by |this|. @@ -157,8 +149,8 @@ // modification, associated BrowserContext). const WebRtcLogFileInfo log_file_; - // The observer to be notified when this upload succeeds or fails. - WebRtcEventLogUploaderObserver* const observer_; + // Callback posted back to signal success or failure. + UploadResultCallback callback_; // Maximum allowed file size. In production code, this is a hard-coded, // but unit tests may set other values.
diff --git a/chrome/browser/media/webrtc/webrtc_event_log_uploader_impl_unittest.cc b/chrome/browser/media/webrtc/webrtc_event_log_uploader_impl_unittest.cc index d91cb59..b819f8f 100644 --- a/chrome/browser/media/webrtc/webrtc_event_log_uploader_impl_unittest.cc +++ b/chrome/browser/media/webrtc/webrtc_event_log_uploader_impl_unittest.cc
@@ -7,6 +7,7 @@ #include <memory> #include <string> +#include "base/bind.h" #include "base/callback_forward.h" #include "base/files/file_path.h" #include "base/files/file_util.h" @@ -29,27 +30,23 @@ using BrowserContextId = WebRtcEventLogPeerConnectionKey::BrowserContextId; namespace { -class MockWebRtcEventLogUploaderObserver - : public WebRtcEventLogUploaderObserver { +class UploadObserver { public: - explicit MockWebRtcEventLogUploaderObserver( - base::OnceClosure completion_closure) - : completion_closure_(std::move(completion_closure)) {} + explicit UploadObserver(base::OnceClosure on_complete_callback) + : on_complete_callback_(std::move(on_complete_callback)) {} - ~MockWebRtcEventLogUploaderObserver() override = default; - - // Combines the mock functionality via a helper (CompletionCallback), as well - // as calls the completion closure. + // Combines the mock functionality via a helper (CompletionCallback), + // as well as unblocks its owner through |on_complete_callback_|. void OnWebRtcEventLogUploadComplete(const base::FilePath& log_file, - bool upload_successful) override { + bool upload_successful) { CompletionCallback(log_file, upload_successful); - std::move(completion_closure_).Run(); + std::move(on_complete_callback_).Run(); } MOCK_METHOD2(CompletionCallback, void(const base::FilePath&, bool)); private: - base::OnceClosure completion_closure_; + base::OnceClosure on_complete_callback_; }; #if defined(OS_POSIX) && !defined(OS_FUCHSIA) @@ -158,7 +155,7 @@ const WebRtcLogFileInfo log_file_info(browser_context_id, log_file_, last_modified_time); - uploader_ = uploader_factory_->Create(log_file_info, &observer_); + uploader_ = uploader_factory_->Create(log_file_info, ResultCallback()); observer_run_loop_.Run(); // Observer was given quit-closure by ctor. } @@ -173,7 +170,7 @@ last_modified_time); uploader_ = uploader_factory_->CreateWithCustomMaxSizeForTesting( - log_file_info, &observer_, max_log_size_bytes); + log_file_info, ResultCallback(), max_log_size_bytes); observer_run_loop_.Run(); // Observer was given quit-closure by ctor. } @@ -186,7 +183,12 @@ const WebRtcLogFileInfo log_file_info(browser_context_id, log_file_, last_modified_time); - uploader_ = uploader_factory_->Create(log_file_info, &observer_); + uploader_ = uploader_factory_->Create(log_file_info, ResultCallback()); + } + + WebRtcEventLogUploader::UploadResultCallback ResultCallback() { + return base::BindOnce(&UploadObserver::OnWebRtcEventLogUploadComplete, + base::Unretained(&observer_)); } content::TestBrowserThreadBundle test_browser_thread_bundle_; @@ -203,7 +205,7 @@ std::unique_ptr<net::FakeURLFetcherFactory> fake_url_fetcher_factory_; std::unique_ptr<net::TestURLFetcherFactory> test_url_fetcher_factory_; - StrictMock<MockWebRtcEventLogUploaderObserver> observer_; + StrictMock<UploadObserver> observer_; // These (uploader-factory and uploader) are the units under test. std::unique_ptr<WebRtcEventLogUploaderImpl::Factory> uploader_factory_;
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.cc b/chrome/browser/password_manager/chrome_password_manager_client.cc index efa63ee..6f0ae32 100644 --- a/chrome/browser/password_manager/chrome_password_manager_client.cc +++ b/chrome/browser/password_manager/chrome_password_manager_client.cc
@@ -848,6 +848,10 @@ Profile::FromBrowserContext(web_contents()->GetBrowserContext())); } +void ChromePasswordManagerClient::UpdateFormManagers() { + password_manager_.UpdateFormManagers(); +} + // static void ChromePasswordManagerClient::BindCredentialManager( password_manager::mojom::CredentialManagerRequest request,
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.h b/chrome/browser/password_manager/chrome_password_manager_client.h index 3941e94..2ff1c0e 100644 --- a/chrome/browser/password_manager/chrome_password_manager_client.h +++ b/chrome/browser/password_manager/chrome_password_manager_client.h
@@ -110,6 +110,7 @@ const password_manager::LogManager* GetLogManager() const override; password_manager::PasswordRequirementsService* GetPasswordRequirementsService() override; + void UpdateFormManagers() override; // autofill::mojom::PasswordManagerClient overrides. void AutomaticGenerationStatusChanged(
diff --git a/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc b/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc index 9722482..3ead59d 100644 --- a/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc +++ b/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc
@@ -22,6 +22,7 @@ #if !defined(OS_ANDROID) #include "chrome/browser/ui/views/overlay/overlay_window_views.h" +#include "ui/views/widget/widget_observer.h" #endif class PictureInPictureWindowControllerBrowserTest @@ -73,6 +74,33 @@ EXPECT_TRUE(result); } +#if !defined(OS_ANDROID) + class WidgetBoundsChangeWaiter : public views::WidgetObserver { + public: + explicit WidgetBoundsChangeWaiter(views::Widget* widget) + : widget_(widget), initial_bounds_(widget->GetWindowBoundsInScreen()) { + widget_->AddObserver(this); + } + + ~WidgetBoundsChangeWaiter() final { widget_->RemoveObserver(this); } + + void OnWidgetBoundsChanged(views::Widget* widget, const gfx::Rect&) final { + run_loop_.Quit(); + } + + void Wait() { + if (widget_->GetWindowBoundsInScreen() != initial_bounds_) + return; + run_loop_.Run(); + } + + private: + views::Widget* widget_; + gfx::Rect initial_bounds_; + base::RunLoop run_loop_; + }; +#endif // !defined(OS_ANDROID) + private: content::PictureInPictureWindowController* pip_window_controller_ = nullptr; base::test::ScopedFeatureList feature_list_; @@ -597,8 +625,16 @@ EXPECT_FALSE(window_controller()->GetWindowForTesting()->IsVisible()); } +// Flaky on Linux: crbug/860513 +#if defined(OS_LINUX) +#define MAYBE_CrossOriginFrameEnterLeaveCloseWindow \ + DISABLED_CrossOriginFrameEnterLeaveCloseWindow +#else +#define MAYBE_CrossOriginFrameEnterLeaveCloseWindow \ + CrossOriginFrameEnterLeaveCloseWindow +#endif IN_PROC_BROWSER_TEST_F(PictureInPictureWindowControllerBrowserTest, - CrossOriginFrameEnterLeaveCloseWindow) { + MAYBE_CrossOriginFrameEnterLeaveCloseWindow) { GURL embed_url = embedded_test_server()->GetURL( "a.com", "/media/picture-in-picture/iframe-content.html"); GURL main_url = embedded_test_server()->GetURL( @@ -713,3 +749,62 @@ EXPECT_FALSE(active_web_contents->IsFullscreenForCurrentTab()); EXPECT_TRUE(window_controller()->GetWindowForTesting()->IsVisible()); } + +#if !defined(OS_ANDROID) + +// TODO(mlamouri): enable this tests on other platforms when aspect ratio is +// implemented. +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) + +// Tests that when a new surface id is sent to the Picture-in-Picture window, it +// doesn't move back to its default position. +IN_PROC_BROWSER_TEST_F(PictureInPictureWindowControllerBrowserTest, + SurfaceIdChangeDoesNotMoveWindow) { + LoadTabAndEnterPictureInPicture(browser()); + + content::WebContents* active_web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + + OverlayWindowViews* overlay_window = static_cast<OverlayWindowViews*>( + window_controller()->GetWindowForTesting()); + ASSERT_TRUE(overlay_window); + ASSERT_TRUE(overlay_window->IsVisible()); + + // Move and resize the window to the top left corner and wait for ack. + { + WidgetBoundsChangeWaiter waiter(overlay_window); + + overlay_window->SetBounds(gfx::Rect(0, 0, 400, 400)); + + waiter.Wait(); + } + + // Wait for signal that the window was resized. + base::string16 expected_title = base::ASCIIToUTF16("resized"); + EXPECT_EQ(expected_title, + content::TitleWatcher(active_web_contents, expected_title) + .WaitAndGetTitle()); + + // Simulate a new surface layer and a change in aspect ratio and wait for ack. + { + WidgetBoundsChangeWaiter waiter(overlay_window); + + window_controller()->EmbedSurface( + viz::SurfaceId( + viz::FrameSinkId(1, 1), + viz::LocalSurfaceId(9, base::UnguessableToken::Create())), + gfx::Size(200, 100)); + + waiter.Wait(); + } + + // The position should be closer to the (0, 0) than the default one (bottom + // right corner). This will be reflected by checking that the position is + // below (100, 100). + EXPECT_LT(overlay_window->GetBounds().x(), 100); + EXPECT_LT(overlay_window->GetBounds().y(), 100); +} + +#endif // defined(OS_LINUX) && !defined(OS_CHROMEOS) + +#endif // !defined(OS_ANDROID)
diff --git a/chrome/browser/predictors/autocomplete_action_predictor.cc b/chrome/browser/predictors/autocomplete_action_predictor.cc index 1a909141..6eb7d64 100644 --- a/chrome/browser/predictors/autocomplete_action_predictor.cc +++ b/chrome/browser/predictors/autocomplete_action_predictor.cc
@@ -47,8 +47,8 @@ predictors::AutocompleteActionPredictor::LAST_PREDICT_ACTION, "kConfidenceCutoff count should match LAST_PREDICT_ACTION"); -const size_t kMinimumUserTextLength = 1; const int kMinimumNumberOfHits = 3; +const size_t kMaximumTransitionalMatchesSize = 1024 * 1024; // 1 MB. enum DatabaseAction { DATABASE_ACTION_ADD, @@ -63,6 +63,8 @@ namespace predictors { const int AutocompleteActionPredictor::kMaximumDaysToKeepEntry = 14; +const size_t AutocompleteActionPredictor::kMinimumUserTextLength = 1; +const size_t AutocompleteActionPredictor::kMaximumStringLength = 1024; AutocompleteActionPredictor::AutocompleteActionPredictor(Profile* profile) : profile_(profile), @@ -110,8 +112,10 @@ void AutocompleteActionPredictor::RegisterTransitionalMatches( const base::string16& user_text, const AutocompleteResult& result) { - if (user_text.length() < kMinimumUserTextLength) + if (user_text.length() < kMinimumUserTextLength || + user_text.length() > kMaximumStringLength) { return; + } const base::string16 lower_user_text(base::i18n::ToLower(user_text)); // Merge this in to an existing match if we already saw |user_text| @@ -120,20 +124,30 @@ lower_user_text); if (match_it == transitional_matches_.end()) { - TransitionalMatch transitional_match; - transitional_match.user_text = lower_user_text; - match_it = transitional_matches_.insert(transitional_matches_.end(), - transitional_match); + if (transitional_matches_size_ + lower_user_text.length() > + kMaximumTransitionalMatchesSize) { + return; + } + transitional_matches_.emplace_back(lower_user_text); + transitional_matches_size_ += lower_user_text.length(); + match_it = transitional_matches_.end() - 1; } - for (const auto& i : result) { - if (!base::ContainsValue(match_it->urls, i.destination_url)) - match_it->urls.push_back(i.destination_url); + for (const auto& match : result) { + const GURL& url = match.destination_url; + const size_t size = url.spec().size(); + if (!base::ContainsValue(match_it->urls, url) && + size <= kMaximumStringLength && + transitional_matches_size_ + size <= kMaximumTransitionalMatchesSize) { + match_it->urls.push_back(url); + transitional_matches_size_ += size; + } } } void AutocompleteActionPredictor::ClearTransitionalMatches() { transitional_matches_.clear(); + transitional_matches_size_ = 0; } void AutocompleteActionPredictor::CancelPrerender() { @@ -218,8 +232,10 @@ // TODO(dominich): The body of this method doesn't need to be run // synchronously. Investigate posting it as a task to be run later. - if (log.text.length() < kMinimumUserTextLength) + if (log.text.length() < kMinimumUserTextLength || + log.text.length() > kMaximumStringLength) { return; + } // Do not attempt to learn from omnibox interactions where the omnibox // dropdown is closed. In these cases the user text (|log.text|) that we @@ -251,19 +267,19 @@ std::vector<AutocompleteActionPredictorTable::Row> rows_to_add; std::vector<AutocompleteActionPredictorTable::Row> rows_to_update; - for (std::vector<TransitionalMatch>::const_iterator it = - transitional_matches_.begin(); it != transitional_matches_.end(); - ++it) { - if (!base::StartsWith(lower_user_text, it->user_text, + for (const TransitionalMatch& match : transitional_matches_) { + if (!base::StartsWith(lower_user_text, match.user_text, base::CompareCase::SENSITIVE)) continue; + DCHECK_GE(match.user_text.length(), kMinimumUserTextLength); + DCHECK_LE(match.user_text.length(), kMaximumStringLength); // Add entries to the database for those matches. - for (std::vector<GURL>::const_iterator url_it = it->urls.begin(); - url_it != it->urls.end(); ++url_it) { - DCHECK(it->user_text.length() >= kMinimumUserTextLength); - const DBCacheKey key = { it->user_text, *url_it }; - const bool is_hit = (*url_it == opened_url); + for (const GURL& url : match.urls) { + DCHECK_LE(url.spec().length(), kMaximumStringLength); + + const DBCacheKey key = {match.user_text, url}; + const bool is_hit = (url == opened_url); AutocompleteActionPredictorTable::Row row; row.user_text = key.user_text; @@ -293,12 +309,10 @@ // Check against tracked urls and log accuracy for the confidence we // predicted. - for (std::vector<std::pair<GURL, double> >::const_iterator it = - tracked_urls_.begin(); it != tracked_urls_.end(); - ++it) { - if (opened_url == it->first) { + for (const auto& url_and_confidence : tracked_urls_) { + if (opened_url == url_and_confidence.first) { UMA_HISTOGRAM_COUNTS_100("AutocompleteActionPredictor.AccurateCount", - it->second * 100); + url_and_confidence.second * 100); } } tracked_urls_.clear(); @@ -583,6 +597,10 @@ } AutocompleteActionPredictor::TransitionalMatch::TransitionalMatch( + const base::string16 in_user_text) + : user_text(in_user_text) {} + +AutocompleteActionPredictor::TransitionalMatch::TransitionalMatch( const TransitionalMatch& other) = default; AutocompleteActionPredictor::TransitionalMatch::~TransitionalMatch() {
diff --git a/chrome/browser/predictors/autocomplete_action_predictor.h b/chrome/browser/predictors/autocomplete_action_predictor.h index 5380272..ab22d97 100644 --- a/chrome/browser/predictors/autocomplete_action_predictor.h +++ b/chrome/browser/predictors/autocomplete_action_predictor.h
@@ -127,6 +127,7 @@ struct TransitionalMatch { TransitionalMatch(); + explicit TransitionalMatch(const base::string16 in_user_text); TransitionalMatch(const TransitionalMatch& other); ~TransitionalMatch(); @@ -161,6 +162,8 @@ DBIdCacheMap; static const int kMaximumDaysToKeepEntry; + static const size_t kMinimumUserTextLength; + static const size_t kMaximumStringLength; // NotificationObserver void Observe(int type, @@ -253,6 +256,10 @@ // This is cleared after every Omnibox navigation. std::vector<TransitionalMatch> transitional_matches_; + // The aggregated size of all user text and GURLs in |transitional_matches_|. + // This is used to limit the maximum size of |transitional_matches_|. + size_t transitional_matches_size_ = 0; + std::unique_ptr<prerender::PrerenderHandle> prerender_handle_; // This allows us to predict the effect of confidence threshold changes on
diff --git a/chrome/browser/predictors/autocomplete_action_predictor_unittest.cc b/chrome/browser/predictors/autocomplete_action_predictor_unittest.cc index 0cf0e91e..3ef2758 100644 --- a/chrome/browser/predictors/autocomplete_action_predictor_unittest.cc +++ b/chrome/browser/predictors/autocomplete_action_predictor_unittest.cc
@@ -29,8 +29,10 @@ #include "components/history/core/browser/in_memory_database.h" #include "components/history/core/browser/url_database.h" #include "components/omnibox/browser/autocomplete_match.h" +#include "components/omnibox/browser/autocomplete_result.h" #include "content/public/test/test_browser_thread_bundle.h" #include "content/public/test/test_utils.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" using base::ASCIIToUTF16; @@ -85,6 +87,17 @@ AutocompleteActionPredictor::ACTION_NONE } }; +GURL GenerateTestURL(size_t size) { + std::string prefix = "http://b/"; + // Cannot generate an URL shorter than |prefix|. + DCHECK_GE(size, prefix.size()); + size_t suffix_len = size - prefix.size(); + std::string suffix(suffix_len, 'c'); + GURL url(prefix + suffix); + DCHECK_EQ(url.spec().size(), size); + return url; +} + } // end namespace namespace predictors { @@ -251,11 +264,23 @@ DBCacheMap* db_cache() { return &predictor_->db_cache_; } DBIdCacheMap* db_id_cache() { return &predictor_->db_id_cache_; } + std::vector<AutocompleteActionPredictor::TransitionalMatch>* + transitional_matches() { + return &predictor_->transitional_matches_; + } static int maximum_days_to_keep_entry() { return AutocompleteActionPredictor::kMaximumDaysToKeepEntry; } + static size_t minimum_user_text_length() { + return AutocompleteActionPredictor::kMinimumUserTextLength; + } + + static size_t maximum_string_length() { + return AutocompleteActionPredictor::kMaximumStringLength; + } + private: content::TestBrowserThreadBundle test_browser_thread_bundle_; std::unique_ptr<TestingProfile> profile_; @@ -440,4 +465,53 @@ } } +TEST_F(AutocompleteActionPredictorTest, + RegisterTransitionalMatchesUserTextSizeLimits) { + auto test = [this](const base::string16& user_text, + bool should_be_registered) { + predictor()->RegisterTransitionalMatches(user_text, AutocompleteResult()); + bool registered = (std::find(transitional_matches()->begin(), + transitional_matches()->end(), + user_text) != transitional_matches()->end()); + EXPECT_EQ(registered, should_be_registered); + }; + + base::string16 short_text = + ASCIIToUTF16(std::string(minimum_user_text_length(), 'g')); + test(short_text, true); + + base::string16 too_short_text = + ASCIIToUTF16(std::string(minimum_user_text_length() - 1, 'g')); + test(too_short_text, false); + + base::string16 long_text = + ASCIIToUTF16(std::string(maximum_string_length(), 'g')); + test(long_text, true); + + base::string16 too_long_text = + ASCIIToUTF16(std::string(maximum_string_length() + 1, 'g')); + test(too_long_text, false); +} + +TEST_F(AutocompleteActionPredictorTest, + RegisterTransitionalMatchesURLSizeLimits) { + GURL urls[] = {GenerateTestURL(10), GenerateTestURL(maximum_string_length()), + GenerateTestURL(maximum_string_length() + 1), + GenerateTestURL(maximum_string_length() * 10)}; + ACMatches matches; + for (const auto& url : urls) { + AutocompleteMatch match; + match.destination_url = url; + matches.push_back(match); + } + AutocompleteResult result; + result.AppendMatches(AutocompleteInput(), matches); + base::string16 user_text = ASCIIToUTF16("google"); + predictor()->RegisterTransitionalMatches(user_text, result); + auto it = std::find(transitional_matches()->begin(), + transitional_matches()->end(), user_text); + ASSERT_NE(it, transitional_matches()->end()); + EXPECT_THAT(it->urls, ::testing::ElementsAre(urls[0], urls[1])); +} + } // namespace predictors
diff --git a/chrome/browser/resources/chromeos/select_to_speak/select_to_speak_e2e_test_base.js b/chrome/browser/resources/chromeos/select_to_speak/select_to_speak_e2e_test_base.js index 909da1f..0dfcdda 100644 --- a/chrome/browser/resources/chromeos/select_to_speak/select_to_speak_e2e_test_base.js +++ b/chrome/browser/resources/chromeos/select_to_speak/select_to_speak_e2e_test_base.js
@@ -81,7 +81,8 @@ /** * From chromevox_next_e2e_test_base.js * Gets the desktop from the automation API and Launches a new tab with - * the given document, and runs |callback| when a load complete fires. + * the given document, and runs |callback| with the desktop when a load + * complete fires on the created tab. * Arranges to call |testDone()| after |callback| returns. * NOTE: Callbacks created inside |callback| must be wrapped with * |this.newCallback| if passed to asynchonous calls. Otherwise, the test @@ -92,20 +93,20 @@ */ runWithLoadedTree: function(url, callback) { callback = this.newCallback(callback); - chrome.automation.getDesktop(function(r) { - var listener = function(evt) { - if (evt.target.root.url != url) - return; - - r.removeEventListener('focus', listener, true); - r.removeEventListener('loadComplete', listener, true); - callback && callback(r); - callback = null; - }; - r.addEventListener('focus', listener, true); - r.addEventListener('loadComplete', listener, true); + chrome.automation.getDesktop(function(desktopRootNode) { var createParams = {active: true, url: url}; - chrome.tabs.create(createParams); + chrome.tabs.create(createParams, function(unused_tab) { + chrome.automation.getTree(function(returnedRootNode) { + rootNode = returnedRootNode; + if (rootNode.docLoaded) { + callback(desktopRootNode); + return; + } + rootNode.addEventListener('loadComplete', function() { + callback(desktopRootNode); + }); + }); + }); }.bind(this)); },
diff --git a/chrome/browser/resources/settings/privacy_page/personalization_options.html b/chrome/browser/resources/settings/privacy_page/personalization_options.html index 38f6139..344da18 100644 --- a/chrome/browser/resources/settings/privacy_page/personalization_options.html +++ b/chrome/browser/resources/settings/privacy_page/personalization_options.html
@@ -75,6 +75,14 @@ </template> </settings-toggle-button> </if><!-- not chromeos --> +</if><!-- _google_chrome --> + <settings-toggle-button + pref="{{prefs.url_keyed_anonymized_data_collection.enabled}}" + label="$i18n{urlKeyedAnonymizedDataCollection}" + sub-label="$i18n{urlKeyedAnonymizedDataCollectionDesc}" + disabled="[[unifiedConsentGiven]]"> + </settings-toggle-button> +<if expr="_google_chrome"> <template is="dom-if" if="[[!unifiedConsentEnabled]]"> <settings-toggle-button id="spellCheckControl" pref="{{prefs.spellcheck.use_spelling_service}}" @@ -97,12 +105,6 @@ </div> </template> </if><!-- _google_chrome --> - <settings-toggle-button - pref="{{prefs.url_keyed_anonymized_data_collection.enabled}}" - label="$i18n{urlKeyedAnonymizedDataCollection}" - sub-label="$i18n{urlKeyedAnonymizedDataCollectionDesc}" - disabled="[[unifiedConsentGiven]]"> - </settings-toggle-button> </template> <script src="personalization_options.js"></script> </dom-module>
diff --git a/chrome/browser/signin/dice_tab_helper.cc b/chrome/browser/signin/dice_tab_helper.cc index c0e15108..661f97b 100644 --- a/chrome/browser/signin/dice_tab_helper.cc +++ b/chrome/browser/signin/dice_tab_helper.cc
@@ -10,6 +10,8 @@ #include "chrome/browser/signin/signin_util.h" #include "chrome/browser/ui/browser_finder.h" #include "components/signin/core/browser/profile_management_switches.h" +#include "content/public/browser/navigation_controller.h" +#include "content/public/browser/navigation_entry.h" #include "content/public/browser/navigation_handle.h" #include "google_apis/gaia/gaia_urls.h" @@ -21,15 +23,26 @@ DiceTabHelper::~DiceTabHelper() = default; void DiceTabHelper::InitializeSigninFlow( + const GURL& signin_url, signin_metrics::AccessPoint access_point, signin_metrics::Reason reason, signin_metrics::PromoAction promo_action) { + DCHECK(signin_url.is_valid()); + DCHECK(signin_url_.is_empty() || signin_url_ == signin_url); + + // The signin page must be loading. + DCHECK(web_contents()->GetController().GetPendingEntry()); + DCHECK_EQ(signin_url, + web_contents()->GetController().GetPendingEntry()->GetURL()); + + signin_url_ = signin_url; signin_access_point_ = access_point; signin_reason_ = reason; signin_promo_action_ = promo_action; - did_finish_loading_signin_page_ = false; + is_chrome_signin_page_ = true; + signin_page_load_recorded_ = false; - if (signin_reason_ == signin_metrics::Reason::REASON_SIGNIN_PRIMARY_ACCOUNT) { + if (reason == signin_metrics::Reason::REASON_SIGNIN_PRIMARY_ACCOUNT) { signin_metrics::LogSigninAccessPointStarted(access_point, promo_action); signin_metrics::RecordSigninUserActionForAccessPoint(access_point, promo_action); @@ -37,14 +50,54 @@ } } -void DiceTabHelper::DidFinishLoad(content::RenderFrameHost* render_frame_host, - const GURL& validated_url) { - if (did_finish_loading_signin_page_) +bool DiceTabHelper::IsChromeSigninPage() const { + return is_chrome_signin_page_; +} + +void DiceTabHelper::DidStartNavigation( + content::NavigationHandle* navigation_handle) { + if (!is_chrome_signin_page_) return; - if (validated_url.GetOrigin() == GaiaUrls::GetInstance()->gaia_url()) { - VLOG(1) << "Finished loading sign-in page: " << validated_url.spec(); - did_finish_loading_signin_page_ = true; + // Ignore internal navigations. + if (!navigation_handle->IsInMainFrame() || + navigation_handle->IsSameDocument()) { + return; + } + + if (!IsSigninPageNavigation(navigation_handle)) { + // Navigating away from the signin page. + is_chrome_signin_page_ = false; + } +} + +void DiceTabHelper::DidFinishNavigation( + content::NavigationHandle* navigation_handle) { + if (!is_chrome_signin_page_) + return; + + // Ignore internal navigations. + if (!navigation_handle->IsInMainFrame() || + navigation_handle->IsSameDocument()) { + return; + } + + if (!IsSigninPageNavigation(navigation_handle)) { + // Navigating away from the signin page. + is_chrome_signin_page_ = false; + return; + } + + if (!signin_page_load_recorded_) { + signin_page_load_recorded_ = true; base::RecordAction(base::UserMetricsAction("Signin_SigninPage_Shown")); } } + +bool DiceTabHelper::IsSigninPageNavigation( + content::NavigationHandle* navigation_handle) const { + return !navigation_handle->IsErrorPage() && + navigation_handle->GetRedirectChain()[0] == signin_url_ && + navigation_handle->GetURL().GetOrigin() == + GaiaUrls::GetInstance()->gaia_url(); +}
diff --git a/chrome/browser/signin/dice_tab_helper.h b/chrome/browser/signin/dice_tab_helper.h index c206879..3e39d1d7 100644 --- a/chrome/browser/signin/dice_tab_helper.h +++ b/chrome/browser/signin/dice_tab_helper.h
@@ -11,8 +11,9 @@ #include "content/public/browser/web_contents_user_data.h" namespace content { -class RenderFrameHost; +class NavigationHandle; } + // Tab helper used for DICE to mark that sync should start after a web sign-in // with a Google account. class DiceTabHelper : public content::WebContentsUserData<DiceTabHelper>, @@ -31,26 +32,40 @@ signin_metrics::Reason signin_reason() { return signin_reason_; } // Initializes the DiceTabHelper for a new signin flow. Must be called once - // per signin flow happening in the tab. - void InitializeSigninFlow(signin_metrics::AccessPoint access_point, + // per signin flow happening in the tab, when the signin URL is being loaded. + void InitializeSigninFlow(const GURL& signin_url, + signin_metrics::AccessPoint access_point, signin_metrics::Reason reason, signin_metrics::PromoAction promo_action); - // content::WebContentsObserver: - void DidFinishLoad(content::RenderFrameHost* render_frame_host, - const GURL& validated_url) override; + // Returns true if this the tab is a re-usable chrome sign-in page (the signin + // page is loading or loaded in the tab). + // Returns false if the user or the page has navigated away from |signin_url|. + bool IsChromeSigninPage() const; private: friend class content::WebContentsUserData<DiceTabHelper>; explicit DiceTabHelper(content::WebContents* web_contents); + // content::WebContentsObserver: + void DidStartNavigation( + content::NavigationHandle* navigation_handle) override; + void DidFinishNavigation( + content::NavigationHandle* navigation_handle) override; + + // Returns true if this is a navigation to the signin URL. + bool IsSigninPageNavigation( + content::NavigationHandle* navigation_handle) const; + + GURL signin_url_; signin_metrics::AccessPoint signin_access_point_ = signin_metrics::AccessPoint::ACCESS_POINT_UNKNOWN; signin_metrics::PromoAction signin_promo_action_ = signin_metrics::PromoAction::PROMO_ACTION_NO_SIGNIN_PROMO; signin_metrics::Reason signin_reason_ = signin_metrics::Reason::REASON_UNKNOWN_REASON; - bool did_finish_loading_signin_page_ = false; + bool is_chrome_signin_page_ = false; + bool signin_page_load_recorded_ = false; DISALLOW_COPY_AND_ASSIGN(DiceTabHelper); };
diff --git a/chrome/browser/signin/dice_tab_helper_unittest.cc b/chrome/browser/signin/dice_tab_helper_unittest.cc index 018e5b3c..5158ce9 100644 --- a/chrome/browser/signin/dice_tab_helper_unittest.cc +++ b/chrome/browser/signin/dice_tab_helper_unittest.cc
@@ -6,50 +6,113 @@ #include "base/test/metrics/histogram_tester.h" #include "base/test/metrics/user_action_tester.h" +#include "chrome/test/base/chrome_render_view_host_test_harness.h" #include "chrome/test/base/testing_profile.h" #include "components/signin/core/browser/signin_metrics.h" -#include "content/public/test/test_browser_thread_bundle.h" -#include "content/public/test/test_web_contents_factory.h" +#include "content/public/test/navigation_simulator.h" +#include "content/public/test/test_renderer_host.h" #include "google_apis/gaia/gaia_urls.h" #include "testing/gtest/include/gtest/gtest.h" +class DiceTabHelperTest : public ChromeRenderViewHostTestHarness { + public: + DiceTabHelperTest() { + signin_url_ = GaiaUrls::GetInstance()->signin_chrome_sync_dice(); + } + + // Does a navigation to Gaia and initializes the tab helper. + void InitializeDiceTabHelper(DiceTabHelper* helper, + signin_metrics::AccessPoint access_point, + signin_metrics::Reason reason) { + // Load the signin page. + std::unique_ptr<content::NavigationSimulator> simulator = + content::NavigationSimulator::CreateRendererInitiated(signin_url_, + main_rfh()); + simulator->Start(); + helper->InitializeSigninFlow( + signin_url_, access_point, reason, + signin_metrics::PromoAction::PROMO_ACTION_NO_SIGNIN_PROMO); + EXPECT_TRUE(helper->IsChromeSigninPage()); + simulator->Commit(); + } + + GURL signin_url_; +}; + // Tests DiceTabHelper intialization. -TEST(DiceTabHelperTest, Initialization) { - content::TestBrowserThreadBundle thread_bundle; - TestingProfile profile; - content::TestWebContentsFactory factory; - content::WebContents* web_contents = factory.CreateWebContents(&profile); - DiceTabHelper::CreateForWebContents(web_contents); - DiceTabHelper* dice_tab_helper = DiceTabHelper::FromWebContents(web_contents); +TEST_F(DiceTabHelperTest, Initialization) { + DiceTabHelper::CreateForWebContents(web_contents()); + DiceTabHelper* dice_tab_helper = + DiceTabHelper::FromWebContents(web_contents()); // Check default state. EXPECT_EQ(signin_metrics::AccessPoint::ACCESS_POINT_UNKNOWN, dice_tab_helper->signin_access_point()); EXPECT_EQ(signin_metrics::Reason::REASON_UNKNOWN_REASON, dice_tab_helper->signin_reason()); + EXPECT_FALSE(dice_tab_helper->IsChromeSigninPage()); // Initialize the signin flow. signin_metrics::AccessPoint access_point = signin_metrics::AccessPoint::ACCESS_POINT_BOOKMARK_BUBBLE; signin_metrics::Reason reason = signin_metrics::Reason::REASON_SIGNIN_PRIMARY_ACCOUNT; - dice_tab_helper->InitializeSigninFlow( - access_point, reason, - signin_metrics::PromoAction::PROMO_ACTION_NO_SIGNIN_PROMO); + InitializeDiceTabHelper(dice_tab_helper, access_point, reason); EXPECT_EQ(access_point, dice_tab_helper->signin_access_point()); EXPECT_EQ(reason, dice_tab_helper->signin_reason()); + EXPECT_TRUE(dice_tab_helper->IsChromeSigninPage()); +} + +TEST_F(DiceTabHelperTest, SigninPageStatus) { + DiceTabHelper::CreateForWebContents(web_contents()); + DiceTabHelper* dice_tab_helper = + DiceTabHelper::FromWebContents(web_contents()); + EXPECT_FALSE(dice_tab_helper->IsChromeSigninPage()); + + // Load the signin page. + signin_metrics::AccessPoint access_point = + signin_metrics::AccessPoint::ACCESS_POINT_BOOKMARK_BUBBLE; + signin_metrics::Reason reason = + signin_metrics::Reason::REASON_SIGNIN_PRIMARY_ACCOUNT; + InitializeDiceTabHelper(dice_tab_helper, access_point, reason); + EXPECT_TRUE(dice_tab_helper->IsChromeSigninPage()); + + // Reloading the signin page does not interrupt the signin flow. + content::NavigationSimulator::Reload(web_contents()); + EXPECT_TRUE(dice_tab_helper->IsChromeSigninPage()); + + // Subframe navigation are ignored. + std::unique_ptr<content::NavigationSimulator> simulator = + content::NavigationSimulator::CreateRendererInitiated( + signin_url_.Resolve("#baz"), main_rfh()); + simulator->CommitSameDocument(); + EXPECT_TRUE(dice_tab_helper->IsChromeSigninPage()); + + // Navigation in subframe does not interrupt the signin flow. + content::RenderFrameHostTester* render_frame_host_tester = + content::RenderFrameHostTester::For(main_rfh()); + content::RenderFrameHost* sub_frame = + render_frame_host_tester->AppendChild("subframe"); + content::NavigationSimulator::NavigateAndCommitFromDocument(signin_url_, + sub_frame); + EXPECT_TRUE(dice_tab_helper->IsChromeSigninPage()); + + // Navigating to a different page resets the page status. + simulator = content::NavigationSimulator::CreateRendererInitiated( + signin_url_.Resolve("/foo"), main_rfh()); + simulator->Start(); + EXPECT_FALSE(dice_tab_helper->IsChromeSigninPage()); + simulator->Commit(); + EXPECT_FALSE(dice_tab_helper->IsChromeSigninPage()); } // Tests DiceTabHelper metrics. -TEST(DiceTabHelperTest, Metrics) { +TEST_F(DiceTabHelperTest, Metrics) { base::UserActionTester ua_tester; base::HistogramTester h_tester; - content::TestBrowserThreadBundle thread_bundle; - TestingProfile profile; - content::TestWebContentsFactory factory; - content::WebContents* web_contents = factory.CreateWebContents(&profile); - DiceTabHelper::CreateForWebContents(web_contents); - DiceTabHelper* dice_tab_helper = DiceTabHelper::FromWebContents(web_contents); + DiceTabHelper::CreateForWebContents(web_contents()); + DiceTabHelper* dice_tab_helper = + DiceTabHelper::FromWebContents(web_contents()); // No metrics are logged when the Dice tab helper is created. EXPECT_EQ(0, ua_tester.GetActionCount("Signin_Signin_FromStartPage")); @@ -57,8 +120,12 @@ EXPECT_EQ(0, ua_tester.GetActionCount("Signin_SigninPage_Shown")); // Check metrics logged when the Dice tab helper is initialized. + std::unique_ptr<content::NavigationSimulator> simulator = + content::NavigationSimulator::CreateRendererInitiated(signin_url_, + main_rfh()); + simulator->Start(); dice_tab_helper->InitializeSigninFlow( - signin_metrics::AccessPoint::ACCESS_POINT_SETTINGS, + signin_url_, signin_metrics::AccessPoint::ACCESS_POINT_SETTINGS, signin_metrics::Reason::REASON_SIGNIN_PRIMARY_ACCOUNT, signin_metrics::PromoAction::PROMO_ACTION_NEW_ACCOUNT); EXPECT_EQ(1, ua_tester.GetActionCount("Signin_Signin_FromSettings")); @@ -73,19 +140,21 @@ // First call to did finish load does logs any Signin_SigninPage_Shown user // action. - GURL signin_page_url = GaiaUrls::GetInstance()->gaia_url(); - dice_tab_helper->DidFinishLoad(nullptr, signin_page_url); + simulator->Commit(); EXPECT_EQ(1, ua_tester.GetActionCount("Signin_SigninPage_Loading")); EXPECT_EQ(1, ua_tester.GetActionCount("Signin_SigninPage_Shown")); // Second call to did finish load does not log any metrics. - dice_tab_helper->DidFinishLoad(nullptr, signin_page_url); + dice_tab_helper->DidFinishLoad(main_rfh(), signin_url_); EXPECT_EQ(1, ua_tester.GetActionCount("Signin_SigninPage_Loading")); EXPECT_EQ(1, ua_tester.GetActionCount("Signin_SigninPage_Shown")); // Check metrics are logged again when the Dice tab helper is re-initialized. + simulator = content::NavigationSimulator::CreateRendererInitiated(signin_url_, + main_rfh()); + simulator->Start(); dice_tab_helper->InitializeSigninFlow( - signin_metrics::AccessPoint::ACCESS_POINT_SETTINGS, + signin_url_, signin_metrics::AccessPoint::ACCESS_POINT_SETTINGS, signin_metrics::Reason::REASON_SIGNIN_PRIMARY_ACCOUNT, signin_metrics::PromoAction::PROMO_ACTION_WITH_DEFAULT); EXPECT_EQ(2, ua_tester.GetActionCount("Signin_Signin_FromSettings"));
diff --git a/chrome/browser/signin/signin_ui_util.cc b/chrome/browser/signin/signin_ui_util.cc index 0359ed9..c76aaa64 100644 --- a/chrome/browser/signin/signin_ui_util.cc +++ b/chrome/browser/signin/signin_ui_util.cc
@@ -207,7 +207,6 @@ return email; } -// TODO(tangltom): Add a unit test for this function. std::vector<AccountInfo> GetAccountsForDicePromos(Profile* profile) { // Fetch account ids for accounts that have a token. ProfileOAuth2TokenService* token_service =
diff --git a/chrome/browser/signin/signin_ui_util_unittest.cc b/chrome/browser/signin/signin_ui_util_unittest.cc index 559b5a4..10111bf 100644 --- a/chrome/browser/signin/signin_ui_util_unittest.cc +++ b/chrome/browser/signin/signin_ui_util_unittest.cc
@@ -82,7 +82,9 @@ class DiceSigninUiUtilTest : public BrowserWithTestWindowTest { public: DiceSigninUiUtilTest() - : scoped_account_consistency_(signin::AccountConsistencyMethod::kDice) {} + : BrowserWithTestWindowTest( + content::TestBrowserThreadBundle::IO_MAINLOOP), + scoped_account_consistency_(signin::AccountConsistencyMethod::kDice) {} ~DiceSigninUiUtilTest() override = default; struct CreateDiceTurnSyncOnHelperParams { @@ -213,7 +215,7 @@ } const signin::ScopedAccountConsistency scoped_account_consistency_; - const signin_metrics::AccessPoint access_point_ = + signin_metrics::AccessPoint access_point_ = signin_metrics::AccessPoint::ACCESS_POINT_BOOKMARK_BUBBLE; bool create_dice_turn_sync_on_helper_called_ = false; @@ -270,6 +272,7 @@ } TEST_F(DiceSigninUiUtilTest, EnableSyncWithAccountThatNeedsReauth) { + AddTab(browser(), GURL("http://example.com")); // Add an account to the account tracker, but do not add it to the token // service in order for it to require a reauth before enabling sync. std::string account_id = @@ -304,11 +307,14 @@ } // Verify that the active tab has the correct DICE sign-in URL. - content::WebContents* active_contents = - browser()->tab_strip_model()->GetActiveWebContents(); + TabStripModel* tab_strip = browser()->tab_strip_model(); + content::WebContents* active_contents = tab_strip->GetActiveWebContents(); ASSERT_TRUE(active_contents); EXPECT_EQ(signin::GetSigninURLForDice(profile(), kMainEmail), active_contents->GetVisibleURL()); + tab_strip->CloseWebContentsAt( + tab_strip->GetIndexOfWebContents(active_contents), + TabStripModel::CLOSE_USER_GESTURE); } } @@ -364,6 +370,49 @@ EXPECT_EQ(signin::GetSigninURLForDice(profile(), ""), active_contents->GetVisibleURL()); } + +TEST_F(DiceSigninUiUtilTest, GetAccountsForDicePromos) { + // Should start off with no accounts. + std::vector<AccountInfo> accounts = GetAccountsForDicePromos(profile()); + EXPECT_TRUE(accounts.empty()); + + // TODO(tangltom): Flesh out this test. +} + +TEST_F(DiceSigninUiUtilTest, MergeDiceSigninTab) { + base::UserActionTester user_action_tester; + EnableSync(AccountInfo(), false); + EXPECT_EQ( + 1, user_action_tester.GetActionCount("Signin_Signin_FromBookmarkBubble")); + + // Signin tab is reused. + EnableSync(AccountInfo(), false); + EXPECT_EQ( + 1, user_action_tester.GetActionCount("Signin_Signin_FromBookmarkBubble")); + + // Give focus to a different tab. + TabStripModel* tab_strip = browser()->tab_strip_model(); + ASSERT_EQ(0, tab_strip->active_index()); + GURL other_url = GURL("http://example.com"); + AddTab(browser(), other_url); + tab_strip->ActivateTabAt(0, true); + ASSERT_EQ(other_url, tab_strip->GetActiveWebContents()->GetVisibleURL()); + ASSERT_EQ(0, tab_strip->active_index()); + + // Extensions re-use the tab but do not take focus. + access_point_ = signin_metrics::AccessPoint::ACCESS_POINT_EXTENSIONS; + EnableSync(AccountInfo(), false); + EXPECT_EQ( + 1, user_action_tester.GetActionCount("Signin_Signin_FromBookmarkBubble")); + EXPECT_EQ(0, tab_strip->active_index()); + + // Other access points re-use the tab and take focus. + access_point_ = signin_metrics::AccessPoint::ACCESS_POINT_SETTINGS; + EnableSync(AccountInfo(), false); + EXPECT_EQ( + 1, user_action_tester.GetActionCount("Signin_Signin_FromBookmarkBubble")); + EXPECT_EQ(1, tab_strip->active_index()); +} #endif // BUILDFLAG(ENABLE_DICE_SUPPORT) } // namespace signin_ui_util
diff --git a/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper.cc b/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper.cc index a1aa1554..f40a58c 100644 --- a/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper.cc +++ b/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper.cc
@@ -8,6 +8,7 @@ #include "chrome/browser/infobars/infobar_service.h" #include "chrome/grit/generated_resources.h" #include "components/infobars/core/simple_alert_infobar_delegate.h" +#include "content/public/browser/navigation_entry.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/render_process_host.h" #include "content/public/common/page_importance_signals.h" @@ -96,7 +97,22 @@ if (web_contents()->GetPageImportanceSignals().had_form_interaction) return false; - // TODO(ulan): Check if the navigation controller has POST data. + // Do not reload if no entry was committed. + content::NavigationEntry* committed_entry = + web_contents()->GetController().GetLastCommittedEntry(); + if (!committed_entry) + return false; + + // Do not reload if the visible entry does not match the last committed entry. + // This means that the entry is either transient or pending. + content::NavigationEntry* visible_entry = + web_contents()->GetController().GetVisibleEntry(); + if (visible_entry != committed_entry) + return false; + + // Do not reload if the last committed entry has post data. + if (committed_entry->GetHasPostData()) + return false; return true; }
diff --git a/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper.h b/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper.h index 290591de..bbb835c 100644 --- a/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper.h +++ b/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper.h
@@ -53,6 +53,9 @@ CannotReloadBloatedTabInvalidURL); FRIEND_TEST_ALL_PREFIXES(BloatedRendererTabHelperTest, CannotReloadBloatedTabPendingUserInteraction); + FRIEND_TEST_ALL_PREFIXES(BloatedRendererTabHelperTest, + CannotReloadBloatedTabWithPostData); + enum class State { kInactive, kRequestingReload, kStartedNavigation }; explicit BloatedRendererTabHelper(content::WebContents* contents);
diff --git a/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper_unittest.cc b/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper_unittest.cc index 123abbc3..817978f 100644 --- a/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper_unittest.cc +++ b/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper_unittest.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" +#include "content/public/browser/navigation_entry.h" #include "content/public/browser/navigation_handle.h" #include "content/public/common/page_importance_signals.h" #include "content/public/test/web_contents_tester.h" @@ -15,10 +16,11 @@ ChromeRenderViewHostTestHarness::SetUp(); BloatedRendererTabHelper::CreateForWebContents(web_contents()); tab_helper_ = BloatedRendererTabHelper::FromWebContents(web_contents()); - content::WebContentsTester::For(web_contents()) - ->SetLastCommittedURL(GURL("https://test.test")); + web_contents_tester_ = content::WebContentsTester::For(web_contents()); + web_contents_tester_->SetLastCommittedURL(GURL("https://test.test")); } BloatedRendererTabHelper* tab_helper_; + content::WebContentsTester* web_contents_tester_; }; TEST_F(BloatedRendererTabHelperTest, DetectReload) { @@ -58,6 +60,7 @@ } TEST_F(BloatedRendererTabHelperTest, CanReloadBloatedTab) { + web_contents_tester_->NavigateAndCommit(GURL("https://test.test")); EXPECT_TRUE(tab_helper_->CanReloadBloatedTab()); } @@ -68,8 +71,14 @@ } TEST_F(BloatedRendererTabHelperTest, CannotReloadBloatedTabInvalidURL) { - content::WebContentsTester::For(web_contents()) - ->SetLastCommittedURL(GURL("invalid :)")); + web_contents_tester_->SetLastCommittedURL(GURL("invalid :)")); + + EXPECT_FALSE(tab_helper_->CanReloadBloatedTab()); +} + +TEST_F(BloatedRendererTabHelperTest, CannotReloadBloatedTabWithPostData) { + web_contents_tester_->NavigateAndCommit(GURL("https://test.test")); + web_contents()->GetController().GetLastCommittedEntry()->SetHasPostData(true); EXPECT_FALSE(tab_helper_->CanReloadBloatedTab()); } @@ -78,7 +87,6 @@ CannotReloadBloatedTabPendingUserInteraction) { content::PageImportanceSignals signals; signals.had_form_interaction = true; - content::WebContentsTester::For(web_contents()) - ->SetPageImportanceSignals(signals); + web_contents_tester_->SetPageImportanceSignals(signals); EXPECT_FALSE(tab_helper_->CanReloadBloatedTab()); }
diff --git a/chrome/browser/ui/passwords/manage_passwords_state.cc b/chrome/browser/ui/passwords/manage_passwords_state.cc index 7db4ea99..299d195 100644 --- a/chrome/browser/ui/passwords/manage_passwords_state.cc +++ b/chrome/browser/ui/passwords/manage_passwords_state.cc
@@ -201,7 +201,10 @@ return; bool applied_delete = false; + bool all_changes_are_deletion = true; for (const password_manager::PasswordStoreChange& change : changes) { + if (change.type() != password_manager::PasswordStoreChange::REMOVE) + all_changes_are_deletion = false; const autofill::PasswordForm& changed_form = change.form(); if (changed_form.blacklisted_by_user) continue; @@ -220,8 +223,8 @@ // itself adds a credential, they should not be refetched. The password // generation can be confused as the generated password will be refetched and // autofilled immediately. - if (applied_delete && client_->GetPasswordManager()) - client_->GetPasswordManager()->UpdateFormManagers(); + if (applied_delete && all_changes_are_deletion) + client_->UpdateFormManagers(); } void ManagePasswordsState::ChooseCredential(
diff --git a/chrome/browser/ui/passwords/manage_passwords_state_unittest.cc b/chrome/browser/ui/passwords/manage_passwords_state_unittest.cc index 66b87cb..76d2c30 100644 --- a/chrome/browser/ui/passwords/manage_passwords_state_unittest.cc +++ b/chrome/browser/ui/passwords/manage_passwords_state_unittest.cc
@@ -25,9 +25,12 @@ using ::testing::Contains; using ::testing::ElementsAre; using ::testing::IsEmpty; +using ::testing::Mock; using ::testing::Not; using ::testing::Pointee; using ::testing::UnorderedElementsAre; +using password_manager::PasswordStoreChange; +using password_manager::PasswordStoreChangeList; namespace { @@ -44,9 +47,15 @@ return result; } +class MockPasswordManagerClient + : public password_manager::StubPasswordManagerClient { + public: + MOCK_METHOD0(UpdateFormManagers, void()); +}; + class ManagePasswordsStateTest : public testing::Test { public: - ManagePasswordsStateTest() : password_manager_(&stub_client_) { + ManagePasswordsStateTest() : password_manager_(&mock_client_) { fetcher_.Fetch(); } @@ -73,7 +82,7 @@ test_local_federated_form_.signon_realm = "federation://example.com/accounts.com"; - passwords_data_.set_client(&stub_client_); + passwords_data_.set_client(&mock_client_); } autofill::PasswordForm& test_local_form() { return test_local_form_; } @@ -113,7 +122,7 @@ std::unique_ptr<password_manager::PasswordFormManager> CreateFormManagerInternal(bool include_federated); - password_manager::StubPasswordManagerClient stub_client_; + MockPasswordManagerClient mock_client_; password_manager::StubPasswordManagerDriver driver_; password_manager::PasswordManager password_manager_; password_manager::FakeFormFetcher fetcher_; @@ -140,7 +149,7 @@ ManagePasswordsStateTest::CreateFormManagerInternal(bool include_federated) { std::unique_ptr<password_manager::PasswordFormManager> test_form_manager( new password_manager::PasswordFormManager( - &password_manager_, &stub_client_, driver_.AsWeakPtr(), + &password_manager_, &mock_client_, driver_.AsWeakPtr(), test_local_form(), base::WrapUnique(new password_manager::StubFormSaver), &fetcher_)); test_form_manager->Init(nullptr); @@ -169,9 +178,8 @@ form.origin = GURL("http://3rdparty.com"); form.username_value = base::ASCIIToUTF16("username"); form.password_value = base::ASCIIToUTF16("12345"); - password_manager::PasswordStoreChange change( - password_manager::PasswordStoreChange::ADD, form); - password_manager::PasswordStoreChangeList list(1, change); + PasswordStoreChange change(PasswordStoreChange::ADD, form); + PasswordStoreChangeList list(1, change); passwords_data().ProcessLoginsChanged(list); EXPECT_EQ(forms, GetRawPointers(passwords_data().GetCurrentForms())); EXPECT_EQ(state, passwords_data().state()); @@ -179,16 +187,14 @@ // Update the form. form.password_value = base::ASCIIToUTF16("password"); - list[0] = password_manager::PasswordStoreChange( - password_manager::PasswordStoreChange::UPDATE, form); + list[0] = PasswordStoreChange(PasswordStoreChange::UPDATE, form); passwords_data().ProcessLoginsChanged(list); EXPECT_EQ(forms, GetRawPointers(passwords_data().GetCurrentForms())); EXPECT_EQ(state, passwords_data().state()); EXPECT_EQ(origin, passwords_data().origin()); // Delete the form. - list[0] = password_manager::PasswordStoreChange( - password_manager::PasswordStoreChange::REMOVE, form); + list[0] = PasswordStoreChange(PasswordStoreChange::REMOVE, form); passwords_data().ProcessLoginsChanged(list); EXPECT_EQ(forms, GetRawPointers(passwords_data().GetCurrentForms())); EXPECT_EQ(state, passwords_data().state()); @@ -210,30 +216,44 @@ form.signon_realm = form.origin.GetOrigin().spec(); form.username_value = base::ASCIIToUTF16("user15"); form.password_value = base::ASCIIToUTF16("12345"); - password_manager::PasswordStoreChange change( - password_manager::PasswordStoreChange::ADD, form); - password_manager::PasswordStoreChangeList list(1, change); + PasswordStoreChange change(PasswordStoreChange::ADD, form); + PasswordStoreChangeList list(1, change); + EXPECT_CALL(mock_client_, UpdateFormManagers()).Times(0); passwords_data().ProcessLoginsChanged(list); EXPECT_THAT(passwords_data().GetCurrentForms(), Contains(Pointee(form))); EXPECT_EQ(state, passwords_data().state()); EXPECT_EQ(origin, passwords_data().origin()); + Mock::VerifyAndClearExpectations(&mock_client_); + + // Remove and Add form. + list[0] = PasswordStoreChange(PasswordStoreChange::REMOVE, form); + form.username_value = base::ASCIIToUTF16("user15"); + list.push_back(PasswordStoreChange(PasswordStoreChange::ADD, form)); + EXPECT_CALL(mock_client_, UpdateFormManagers()).Times(0); + passwords_data().ProcessLoginsChanged(list); + EXPECT_EQ(state, passwords_data().state()); + EXPECT_EQ(origin, passwords_data().origin()); + Mock::VerifyAndClearExpectations(&mock_client_); + list.erase(++list.begin()); // Update the form. form.password_value = base::ASCIIToUTF16("password"); - list[0] = password_manager::PasswordStoreChange( - password_manager::PasswordStoreChange::UPDATE, form); + list[0] = PasswordStoreChange(PasswordStoreChange::UPDATE, form); + EXPECT_CALL(mock_client_, UpdateFormManagers()).Times(0); passwords_data().ProcessLoginsChanged(list); EXPECT_THAT(passwords_data().GetCurrentForms(), Contains(Pointee(form))); EXPECT_EQ(state, passwords_data().state()); EXPECT_EQ(origin, passwords_data().origin()); + Mock::VerifyAndClearExpectations(&mock_client_); // Delete the form. - list[0] = password_manager::PasswordStoreChange( - password_manager::PasswordStoreChange::REMOVE, form); + list[0] = PasswordStoreChange(PasswordStoreChange::REMOVE, form); + EXPECT_CALL(mock_client_, UpdateFormManagers()); passwords_data().ProcessLoginsChanged(list); EXPECT_EQ(forms, GetRawPointers(passwords_data().GetCurrentForms())); EXPECT_EQ(state, passwords_data().state()); EXPECT_EQ(origin, passwords_data().origin()); + Mock::VerifyAndClearExpectations(&mock_client_); TestNoisyUpdates(); } @@ -249,17 +269,15 @@ autofill::PasswordForm blacklisted; blacklisted.blacklisted_by_user = true; blacklisted.origin = origin; - password_manager::PasswordStoreChangeList list; - list.push_back(password_manager::PasswordStoreChange( - password_manager::PasswordStoreChange::ADD, blacklisted)); + PasswordStoreChangeList list; + list.push_back(PasswordStoreChange(PasswordStoreChange::ADD, blacklisted)); passwords_data().ProcessLoginsChanged(list); EXPECT_EQ(forms, GetRawPointers(passwords_data().GetCurrentForms())); EXPECT_EQ(state, passwords_data().state()); EXPECT_EQ(origin, passwords_data().origin()); // Delete the blacklisted form. - list[0] = password_manager::PasswordStoreChange( - password_manager::PasswordStoreChange::REMOVE, blacklisted); + list[0] = PasswordStoreChange(PasswordStoreChange::REMOVE, blacklisted); passwords_data().ProcessLoginsChanged(list); EXPECT_EQ(forms, GetRawPointers(passwords_data().GetCurrentForms())); EXPECT_EQ(state, passwords_data().state());
diff --git a/chrome/browser/ui/signin_view_controller.cc b/chrome/browser/ui/signin_view_controller.cc index d3781283..4f16a83 100644 --- a/chrome/browser/ui/signin_view_controller.cc +++ b/chrome/browser/ui/signin_view_controller.cc
@@ -7,6 +7,7 @@ #include <utility> #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/search/search.h" #include "chrome/browser/signin/account_consistency_mode_manager.h" #include "chrome/browser/signin/dice_tab_helper.h" #include "chrome/browser/signin/signin_manager_factory.h" @@ -18,9 +19,12 @@ #include "chrome/browser/ui/signin_view_controller_delegate.h" #include "chrome/browser/ui/singleton_tabs.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/common/webui_url_constants.h" #include "components/signin/core/browser/profile_management_switches.h" #include "components/signin/core/browser/signin_manager.h" +#include "content/public/browser/web_contents.h" #include "google_apis/gaia/gaia_urls.h" +#include "url/url_constants.h" namespace { @@ -40,6 +44,39 @@ return signin_metrics::Reason::REASON_UNKNOWN_REASON; } } + +// Opens a new tab on |url| or reuses the current tab if it is the NTP. +void ShowTabOverwritingNTP(Browser* browser, const GURL& url) { + NavigateParams params(browser, url, ui::PAGE_TRANSITION_AUTO_BOOKMARK); + params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB; + params.window_action = NavigateParams::SHOW_WINDOW; + params.user_gesture = true; + params.tabstrip_add_types |= TabStripModel::ADD_INHERIT_OPENER; + + content::WebContents* contents = + browser->tab_strip_model()->GetActiveWebContents(); + if (contents) { + const GURL& contents_url = contents->GetVisibleURL(); + if (contents_url == chrome::kChromeUINewTabURL || + search::IsInstantNTP(contents) || contents_url == url::kAboutBlankURL) { + params.disposition = WindowOpenDisposition::CURRENT_TAB; + } + } + + Navigate(¶ms); +} + +// Returns the index of an existing re-usable Dice signin tab, or -1. +int FindDiceSigninTab(TabStripModel* tab_strip) { + int tab_count = tab_strip->count(); + for (int tab_index = 0; tab_index < tab_count; ++tab_index) { + content::WebContents* web_contents = tab_strip->GetWebContentsAt(tab_index); + DiceTabHelper* tab_helper = DiceTabHelper::FromWebContents(web_contents); + if (tab_helper && tab_helper->IsChromeSigninPage()) + return tab_index; + } + return -1; +} #endif } // namespace @@ -174,15 +211,30 @@ ui::PAGE_TRANSITION_AUTO_TOPLEVEL, false); active_contents->OpenURL(params); } else { - NavigateParams params = GetSingletonTabNavigateParams(browser, signin_url); - ShowSingletonTabOverwritingNTP(browser, std::move(params)); + // Check if there is already a signin-tab open. + TabStripModel* tab_strip = browser->tab_strip_model(); + int dice_tab_index = FindDiceSigninTab(tab_strip); + if (dice_tab_index != -1) { + if (access_point != + signin_metrics::AccessPoint::ACCESS_POINT_EXTENSIONS) { + // Extensions do not activate the tab to prevent misbehaving + // extensions to keep focusing the signin tab. + tab_strip->ActivateTabAt(dice_tab_index, true /* user_gesture */); + } + // Do not create a new signin tab, because there is already one. + return; + } + + ShowTabOverwritingNTP(browser, signin_url); active_contents = browser->tab_strip_model()->GetActiveWebContents(); } + DCHECK(active_contents); DCHECK_EQ(signin_url, active_contents->GetVisibleURL()); DiceTabHelper::CreateForWebContents(active_contents); DiceTabHelper* tab_helper = DiceTabHelper::FromWebContents(active_contents); - tab_helper->InitializeSigninFlow(access_point, signin_reason, promo_action); + tab_helper->InitializeSigninFlow(signin_url, access_point, signin_reason, + promo_action); } #endif // !defined(OS_CHROMEOS)
diff --git a/chrome/browser/ui/views/autofill/dialog_event_waiter.h b/chrome/browser/ui/views/autofill/dialog_event_waiter.h deleted file mode 100644 index b789f5e..0000000 --- a/chrome/browser/ui/views/autofill/dialog_event_waiter.h +++ /dev/null
@@ -1,73 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_VIEWS_AUTOFILL_DIALOG_EVENT_WAITER_H_ -#define CHROME_BROWSER_UI_VIEWS_AUTOFILL_DIALOG_EVENT_WAITER_H_ - -#include <list> - -#include "base/run_loop.h" -#include "testing/gtest/include/gtest/gtest.h" - -// DialogEventWaiter is used to wait on specific events that may have occured -// before the call to Wait(), or after, in which case a RunLoop is used. -// -// Usage: -// waiter_ = std::make_unique<DialogEventWaiter>({ ... }); -// -// Do stuff, which (a)synchronously calls waiter_->OnEvent(...). -// -// waiter_->Wait(); <- Will either return right away if events were observed, -// <- or use a RunLoop's Run/Quit to wait. -template <typename DialogEvent> -class DialogEventWaiter { - public: - explicit DialogEventWaiter(std::list<DialogEvent> event_sequence); - ~DialogEventWaiter(); - - // Either returns right away if all events were observed between this - // object's construction and this call to Wait(), or use a RunLoop to wait - // for them. - void Wait(); - - // Observes an event (quits the RunLoop if we are done waiting). - void OnEvent(DialogEvent event); - - private: - std::list<DialogEvent> events_; - base::RunLoop run_loop_; - - DISALLOW_COPY_AND_ASSIGN(DialogEventWaiter); -}; - -template <typename DialogEvent> -DialogEventWaiter<DialogEvent>::DialogEventWaiter( - std::list<DialogEvent> event_sequence) - : events_(std::move(event_sequence)) {} - -template <typename DialogEvent> -DialogEventWaiter<DialogEvent>::~DialogEventWaiter() {} - -template <typename DialogEvent> -void DialogEventWaiter<DialogEvent>::Wait() { - if (events_.empty()) - return; - - DCHECK(!run_loop_.running()); - run_loop_.Run(); -} - -template <typename DialogEvent> -void DialogEventWaiter<DialogEvent>::OnEvent(DialogEvent event) { - if (events_.empty()) - return; - - ASSERT_EQ(events_.front(), event); - events_.pop_front(); - // Only quit the loop if no other events are expected. - if (events_.empty() && run_loop_.running()) - run_loop_.Quit(); -} - -#endif // CHROME_BROWSER_UI_VIEWS_AUTOFILL_DIALOG_EVENT_WAITER_H_
diff --git a/chrome/browser/ui/views/autofill/save_card_bubble_views_browsertest_base.cc b/chrome/browser/ui/views/autofill/save_card_bubble_views_browsertest_base.cc index 5af93ce..84a2bf7 100644 --- a/chrome/browser/ui/views/autofill/save_card_bubble_views_browsertest_base.cc +++ b/chrome/browser/ui/views/autofill/save_card_bubble_views_browsertest_base.cc
@@ -12,7 +12,6 @@ #include "chrome/browser/ui/autofill/save_card_bubble_controller_impl.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/browser/ui/views/autofill/dialog_event_waiter.h" #include "chrome/browser/ui/views/autofill/dialog_view_ids.h" #include "chrome/browser/ui/views/autofill/save_card_bubble_views.h" #include "chrome/test/base/ui_test_utils.h" @@ -356,8 +355,8 @@ void SaveCardBubbleViewsBrowserTestBase::ResetEventWaiterForSequence( std::list<DialogEvent> event_sequence) { - event_waiter_ = std::make_unique<DialogEventWaiter<DialogEvent>>( - std::move(event_sequence)); + event_waiter_ = + std::make_unique<EventWaiter<DialogEvent>>(std::move(event_sequence)); } void SaveCardBubbleViewsBrowserTestBase::WaitForObservedEvent() {
diff --git a/chrome/browser/ui/views/autofill/save_card_bubble_views_browsertest_base.h b/chrome/browser/ui/views/autofill/save_card_bubble_views_browsertest_base.h index e07c4a1..cf8961c2 100644 --- a/chrome/browser/ui/views/autofill/save_card_bubble_views_browsertest_base.h +++ b/chrome/browser/ui/views/autofill/save_card_bubble_views_browsertest_base.h
@@ -12,11 +12,11 @@ #include "base/command_line.h" #include "base/macros.h" #include "base/test/scoped_feature_list.h" -#include "chrome/browser/ui/views/autofill/dialog_event_waiter.h" #include "chrome/browser/ui/views/autofill/dialog_view_ids.h" #include "chrome/browser/ui/views/autofill/save_card_bubble_views.h" #include "chrome/test/base/in_process_browser_test.h" #include "components/autofill/core/browser/credit_card_save_manager.h" +#include "components/autofill/core/browser/test_event_waiter.h" #include "content/public/browser/web_contents_observer.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/url_request/test_url_fetcher_factory.h" @@ -109,7 +109,7 @@ base::test::ScopedFeatureList scoped_feature_list_; private: - std::unique_ptr<DialogEventWaiter<DialogEvent>> event_waiter_; + std::unique_ptr<autofill::EventWaiter<DialogEvent>> event_waiter_; std::unique_ptr<net::FakeURLFetcherFactory> url_fetcher_factory_; network::TestURLLoaderFactory test_url_loader_factory_; scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_;
diff --git a/chrome/browser/ui/views/overlay/overlay_window_views.cc b/chrome/browser/ui/views/overlay/overlay_window_views.cc index c9448aa..b339dc8 100644 --- a/chrome/browser/ui/views/overlay/overlay_window_views.cc +++ b/chrome/browser/ui/views/overlay/overlay_window_views.cc
@@ -232,7 +232,7 @@ // views::View that toggles play/pause. ------------------------------------- play_pause_controls_view_->SetImageAlignment( views::ImageButton::ALIGN_CENTER, views::ImageButton::ALIGN_MIDDLE); - play_pause_controls_view_->SetToggled(!controller_->IsPlayerActive()); + play_pause_controls_view_->SetToggled(controller_->IsPlayerActive()); play_pause_controls_view_->SetBackgroundImageAlignment( views::ImageButton::ALIGN_LEFT, views::ImageButton::ALIGN_TOP); UpdatePlayPauseControlsSize(); @@ -387,6 +387,9 @@ natural_size_ = natural_size; SetAspectRatio(natural_size_); + if (IsVisible()) + return; + // Update the views::Widget bounds to adhere to sizing spec. SetBounds(CalculateAndUpdateWindowBounds()); }
diff --git a/chrome/browser/ui/views/payments/payment_request_browsertest_base.cc b/chrome/browser/ui/views/payments/payment_request_browsertest_base.cc index b3775788..7e07dd6 100644 --- a/chrome/browser/ui/views/payments/payment_request_browsertest_base.cc +++ b/chrome/browser/ui/views/payments/payment_request_browsertest_base.cc
@@ -20,7 +20,6 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/browser/ui/views/autofill/dialog_event_waiter.h" #include "chrome/browser/ui/views/payments/editor_view_controller.h" #include "chrome/browser/ui/views/payments/payment_request_dialog_view_ids.h" #include "chrome/browser/ui/views/payments/validating_combobox.h" @@ -758,13 +757,13 @@ } void PaymentRequestBrowserTestBase::ResetEventWaiter(DialogEvent event) { - event_waiter_ = std::make_unique<DialogEventWaiter<DialogEvent>>( + event_waiter_ = std::make_unique<autofill::EventWaiter<DialogEvent>>( std::list<DialogEvent>{event}); } void PaymentRequestBrowserTestBase::ResetEventWaiterForSequence( std::list<DialogEvent> event_sequence) { - event_waiter_ = std::make_unique<DialogEventWaiter<DialogEvent>>( + event_waiter_ = std::make_unique<autofill::EventWaiter<DialogEvent>>( std::move(event_sequence)); }
diff --git a/chrome/browser/ui/views/payments/payment_request_browsertest_base.h b/chrome/browser/ui/views/payments/payment_request_browsertest_base.h index 9c62d6bd..5377b9f 100644 --- a/chrome/browser/ui/views/payments/payment_request_browsertest_base.h +++ b/chrome/browser/ui/views/payments/payment_request_browsertest_base.h
@@ -15,12 +15,12 @@ #include "base/macros.h" #include "base/run_loop.h" #include "base/strings/string16.h" -#include "chrome/browser/ui/views/autofill/dialog_event_waiter.h" #include "chrome/browser/ui/views/payments/payment_request_dialog_view.h" #include "chrome/browser/ui/views/payments/test_chrome_payment_request_delegate.h" #include "chrome/test/base/in_process_browser_test.h" #include "components/autofill/core/browser/field_types.h" #include "components/autofill/core/browser/personal_data_manager_observer.h" +#include "components/autofill/core/browser/test_event_waiter.h" #include "components/autofill/core/browser/test_sync_service.h" #include "components/payments/content/payment_request.h" #include "components/sync_preferences/testing_pref_service_syncable.h" @@ -65,7 +65,7 @@ public PaymentRequestDialogView::ObserverForTest, public content::WebContentsObserver { public: - // Various events that can be waited on by the DialogEventWaiter. + // Various events that can be waited on by the EventWaiter. enum DialogEvent : int { DIALOG_OPENED, DIALOG_CLOSED, @@ -257,7 +257,7 @@ void WaitForObservedEvent(); private: - std::unique_ptr<DialogEventWaiter<DialogEvent>> event_waiter_; + std::unique_ptr<autofill::EventWaiter<DialogEvent>> event_waiter_; std::unique_ptr<net::EmbeddedTestServer> https_server_; // Weak, owned by the PaymentRequest object. TestChromePaymentRequestDelegate* delegate_;
diff --git a/chrome/browser/ui/webui/policy_ui_handler.cc b/chrome/browser/ui/webui/policy_ui_handler.cc index c3a44e2..979e20dfb6 100644 --- a/chrome/browser/ui/webui/policy_ui_handler.cc +++ b/chrome/browser/ui/webui/policy_ui_handler.cc
@@ -773,20 +773,26 @@ void PolicyUIHandler::HandleReloadPolicies(const base::ListValue* args) { #if defined(OS_CHROMEOS) - // Allow user to manually fetch remote commands, in case invalidation - // service is not working properly. - // TODO(binjin): evaluate and possibly remove this after invalidation - // service is landed and tested. http://crbug.com/480982 - policy::CloudPolicyManager* manager = + // Allow user to manually fetch remote commands. Useful for testing or when + // the invalidation service is not working properly. + policy::CloudPolicyManager* const device_manager = g_browser_process->platform_part() ->browser_policy_connector_chromeos() ->GetDeviceCloudPolicyManager(); - // Active Directory management has no CloudPolicyManager. - if (manager) { - policy::RemoteCommandsService* remote_commands_service = - manager->core()->remote_commands_service(); - if (remote_commands_service) - remote_commands_service->FetchRemoteCommands(); + Profile* const profile = Profile::FromWebUI(web_ui()); + policy::CloudPolicyManager* const user_manager = + policy::UserPolicyManagerFactoryChromeOS::GetCloudPolicyManagerForProfile( + profile); + + // Fetch both device and user remote commands. + for (policy::CloudPolicyManager* manager : {device_manager, user_manager}) { + // Active Directory management has no CloudPolicyManager. + if (manager) { + policy::RemoteCommandsService* const remote_commands_service = + manager->core()->remote_commands_service(); + if (remote_commands_service) + remote_commands_service->FetchRemoteCommands(); + } } #endif GetPolicyService()->RefreshPolicies(base::Bind(
diff --git a/chrome/browser/ui/webui/signin/sync_confirmation_handler_unittest.cc b/chrome/browser/ui/webui/signin/sync_confirmation_handler_unittest.cc index 4ff0919..b02fd6b 100644 --- a/chrome/browser/ui/webui/signin/sync_confirmation_handler_unittest.cc +++ b/chrome/browser/ui/webui/signin/sync_confirmation_handler_unittest.cc
@@ -357,8 +357,12 @@ "Signin_Signin_WithAdvancedSyncSettings")); // The corresponding string IDs get recorded. - std::vector<std::vector<int>> expected_id_vectors = {{1, 2, 4, 5}}; + std::vector<std::vector<int>> expected_id_vectors = {{1, 2, 4}}; + std::vector<int> expected_confirmation_ids = {5}; + EXPECT_EQ(expected_id_vectors, consent_auditor()->recorded_id_vectors()); + EXPECT_EQ(expected_confirmation_ids, + consent_auditor()->recorded_confirmation_ids()); EXPECT_EQ(signin_manager()->GetAuthenticatedAccountId(), consent_auditor()->account_id()); @@ -395,8 +399,11 @@ "Signin_Signin_WithAdvancedSyncSettings")); // The corresponding string IDs get recorded. - std::vector<std::vector<int>> expected_id_vectors = {{2, 3, 5, 2}}; + std::vector<std::vector<int>> expected_id_vectors = {{2, 3, 5}}; + std::vector<int> expected_confirmation_ids = {2}; EXPECT_EQ(expected_id_vectors, consent_auditor()->recorded_id_vectors()); + EXPECT_EQ(expected_confirmation_ids, + consent_auditor()->recorded_confirmation_ids()); EXPECT_EQ(signin_manager()->GetAuthenticatedAccountId(), consent_auditor()->account_id());
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index 37df497..18d3b52 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc
@@ -728,6 +728,11 @@ const char kWebRtcRemoteEventLogProactivePruningDelta[] = "webrtc-event-log-proactive-pruning-delta"; +// WebRTC event logs will only be uploaded if the conditions hold for this +// many milliseconds. +const char kWebRtcRemoteEventLogUploadDelayMs[] = + "webrtc-event-log-upload-delay-ms"; + // Normally, remote-bound WebRTC event logs are uploaded only when no // peer connections are active. With this flag, the upload is never suppressed. const char kWebRtcRemoteEventLogUploadNoSuppression[] =
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index 024b738..9d0c2aa 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h
@@ -209,6 +209,7 @@ extern const char kVersion[]; extern const char kWebAuthenticationUI[]; extern const char kWebRtcRemoteEventLogProactivePruningDelta[]; +extern const char kWebRtcRemoteEventLogUploadDelayMs[]; extern const char kWebRtcRemoteEventLogUploadNoSuppression[]; extern const char kWindowPosition[]; extern const char kWindowSize[];
diff --git a/chrome/renderer/pepper/pepper_flash_font_file_host.cc b/chrome/renderer/pepper/pepper_flash_font_file_host.cc index 981e54e3..4313c6a 100644 --- a/chrome/renderer/pepper/pepper_flash_font_file_host.cc +++ b/chrome/renderer/pepper/pepper_flash_font_file_host.cc
@@ -13,38 +13,12 @@ #include "ppapi/host/ppapi_host.h" #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/proxy/serialized_structs.h" + +#if defined(OS_LINUX) || defined(OS_OPENBSD) +#include "content/public/child/child_process_sandbox_support_linux.h" +#include "content/public/common/common_sandbox_support_linux.h" +#elif defined(OS_WIN) #include "third_party/skia/include/core/SkFontMgr.h" - -#if !defined(OS_WIN) -namespace { - -SkFontStyle::Weight PepperWeightToSkWeight(int pepper_weight) { - switch (pepper_weight) { - case PP_BROWSERFONT_TRUSTED_WEIGHT_100: - return SkFontStyle::kThin_Weight; - case PP_BROWSERFONT_TRUSTED_WEIGHT_200: - return SkFontStyle::kExtraLight_Weight; - case PP_BROWSERFONT_TRUSTED_WEIGHT_300: - return SkFontStyle::kLight_Weight; - case PP_BROWSERFONT_TRUSTED_WEIGHT_400: - return SkFontStyle::kNormal_Weight; - case PP_BROWSERFONT_TRUSTED_WEIGHT_500: - return SkFontStyle::kMedium_Weight; - case PP_BROWSERFONT_TRUSTED_WEIGHT_600: - return SkFontStyle::kSemiBold_Weight; - case PP_BROWSERFONT_TRUSTED_WEIGHT_700: - return SkFontStyle::kBold_Weight; - case PP_BROWSERFONT_TRUSTED_WEIGHT_800: - return SkFontStyle::kExtraBold_Weight; - case PP_BROWSERFONT_TRUSTED_WEIGHT_900: - return SkFontStyle::kBlack_Weight; - default: - NOTREACHED(); - return SkFontStyle::kInvisible_Weight; - } -} - -} // namespace #endif PepperFlashFontFileHost::PepperFlashFontFileHost( @@ -54,23 +28,24 @@ const ppapi::proxy::SerializedFontDescription& description, PP_PrivateFontCharset charset) : ResourceHost(host->GetPpapiHost(), instance, resource) { - int weight; -#if defined(OS_WIN) - // TODO(https://crbug.com/857388): Figure out why this diverges from the - // #else block. - weight = description.weight; +#if defined(OS_LINUX) || defined(OS_OPENBSD) + fd_.reset(content::MatchFontWithFallback( + description.face, + description.weight >= PP_BROWSERFONT_TRUSTED_WEIGHT_BOLD, + description.italic, + charset, + PP_BROWSERFONT_TRUSTED_FAMILY_DEFAULT)); +#elif defined(OS_WIN) + int weight = description.weight; if (weight == FW_DONTCARE) weight = SkFontStyle::kNormal_Weight; -#else - weight = PepperWeightToSkWeight(description.weight); -#endif SkFontStyle style(weight, SkFontStyle::kNormal_Width, description.italic ? SkFontStyle::kItalic_Slant : SkFontStyle::kUpright_Slant); sk_sp<SkFontMgr> font_mgr(SkFontMgr::RefDefault()); - typeface_ = sk_sp<SkTypeface>( font_mgr->matchFamilyStyle(description.face.c_str(), style)); +#endif // defined(OS_LINUX) || defined(OS_OPENBSD) } PepperFlashFontFileHost::~PepperFlashFontFileHost() {} @@ -89,6 +64,12 @@ void* buffer, size_t* length) { bool result = false; +#if defined(OS_LINUX) || defined(OS_OPENBSD) + int fd = fd_.get(); + if (fd != -1) + result = content::GetFontTable(fd, table, 0 /* offset */, + reinterpret_cast<uint8_t*>(buffer), length); +#elif defined(OS_WIN) if (typeface_) { table = base::ByteSwap(table); if (buffer == NULL) { @@ -101,6 +82,7 @@ result = true; } } +#endif return result; }
diff --git a/chrome/renderer/pepper/pepper_flash_font_file_host.h b/chrome/renderer/pepper/pepper_flash_font_file_host.h index 6b67a7c..3e9ba7d 100644 --- a/chrome/renderer/pepper/pepper_flash_font_file_host.h +++ b/chrome/renderer/pepper/pepper_flash_font_file_host.h
@@ -14,8 +14,12 @@ #include "ppapi/c/private/pp_private_font_charset.h" #include "ppapi/host/resource_host.h" +#if defined(OS_LINUX) || defined(OS_OPENBSD) +#include "base/files/scoped_file.h" +#elif defined(OS_WIN) #include "third_party/skia/include/core/SkRefCnt.h" #include "third_party/skia/include/core/SkTypeface.h" +#endif namespace content { class RendererPpapiHost; @@ -46,7 +50,11 @@ uint32_t table); bool GetFontData(uint32_t table, void* buffer, size_t* length); +#if defined(OS_LINUX) || defined(OS_OPENBSD) + base::ScopedFD fd_; +#elif defined(OS_WIN) sk_sp<SkTypeface> typeface_; +#endif DISALLOW_COPY_AND_ASSIGN(PepperFlashFontFileHost); };
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 73bddc0..90ac34e88 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -1419,7 +1419,6 @@ "../browser/ui/global_error/global_error_service_browsertest.cc", "../browser/ui/views/autofill/card_unmask_prompt_view_tester_views.cc", "../browser/ui/views/autofill/card_unmask_prompt_view_tester_views.h", - "../browser/ui/views/autofill/dialog_event_waiter.h", "../browser/ui/views/autofill/save_card_bubble_views_browsertest.cc", "../browser/ui/views/autofill/save_card_bubble_views_browsertest_base.cc", "../browser/ui/views/autofill/save_card_bubble_views_browsertest_base.h",
diff --git a/chrome/test/base/browser_with_test_window_test.cc b/chrome/test/base/browser_with_test_window_test.cc index 57708eed..13b9dd43 100644 --- a/chrome/test/base/browser_with_test_window_test.cc +++ b/chrome/test/base/browser_with_test_window_test.cc
@@ -44,11 +44,29 @@ using content::WebContents; BrowserWithTestWindowTest::BrowserWithTestWindowTest() - : BrowserWithTestWindowTest(Browser::TYPE_TABBED, false) {} + : BrowserWithTestWindowTest(Browser::TYPE_TABBED, + false, + content::TestBrowserThreadBundle::DEFAULT) {} + +BrowserWithTestWindowTest::BrowserWithTestWindowTest( + content::TestBrowserThreadBundle::Options thread_bundle_options) + : BrowserWithTestWindowTest(Browser::TYPE_TABBED, + false, + thread_bundle_options) {} BrowserWithTestWindowTest::BrowserWithTestWindowTest(Browser::Type browser_type, bool hosted_app) - : browser_type_(browser_type), hosted_app_(hosted_app) { + : BrowserWithTestWindowTest(browser_type, + hosted_app, + content::TestBrowserThreadBundle::DEFAULT) {} + +BrowserWithTestWindowTest::BrowserWithTestWindowTest( + Browser::Type browser_type, + bool hosted_app, + content::TestBrowserThreadBundle::Options thread_bundle_options) + : thread_bundle_(thread_bundle_options), + browser_type_(browser_type), + hosted_app_(hosted_app) { #if defined(OS_CHROMEOS) ash_test_environment_ = std::make_unique<AshTestEnvironmentChrome>(); ash_test_helper_ =
diff --git a/chrome/test/base/browser_with_test_window_test.h b/chrome/test/base/browser_with_test_window_test.h index 9b28dd89..df0bf09 100644 --- a/chrome/test/base/browser_with_test_window_test.h +++ b/chrome/test/base/browser_with_test_window_test.h
@@ -84,6 +84,19 @@ // the specified type. BrowserWithTestWindowTest(Browser::Type browser_type, bool hosted_app); + // Creates a BrowserWithTestWindowTest with the specified options for the + // TestBrowserThreadBundle. + explicit BrowserWithTestWindowTest( + content::TestBrowserThreadBundle::Options thread_bundle_options); + + // Creates a BrowserWithTestWindowTest for which the initial window will be + // the specified type and with the specified options for the + // TestBrowserThreadBundle. + BrowserWithTestWindowTest( + Browser::Type browser_type, + bool hosted_app, + content::TestBrowserThreadBundle::Options thread_bundle_options); + ~BrowserWithTestWindowTest() override; void SetUp() override;
diff --git a/chrome/test/data/webui/settings/personalization_options_test.js b/chrome/test/data/webui/settings/personalization_options_test.js index 2aa84fe..15ccf8e 100644 --- a/chrome/test/data/webui/settings/personalization_options_test.js +++ b/chrome/test/data/webui/settings/personalization_options_test.js
@@ -89,7 +89,7 @@ testElement.unifiedConsentEnabled = false; Polymer.dom.flush(); assertEquals( - 7, + 8, testElement.root.querySelectorAll('settings-toggle-button').length); testElement.unifiedConsentEnabled = true; Polymer.dom.flush();
diff --git a/chrome/utility/BUILD.gn b/chrome/utility/BUILD.gn index 732de74..ff14588 100644 --- a/chrome/utility/BUILD.gn +++ b/chrome/utility/BUILD.gn
@@ -199,10 +199,6 @@ if (is_android || enable_extensions) { deps += [ "//chrome/services/media_gallery_util:lib" ] } - - if (is_linux && !is_android) { - deps += [ "//components/services/font:lib" ] - } } if (!is_android) {
diff --git a/chromecast/browser/BUILD.gn b/chromecast/browser/BUILD.gn index 0fa8be5..3ba9532 100644 --- a/chromecast/browser/BUILD.gn +++ b/chromecast/browser/BUILD.gn
@@ -201,7 +201,6 @@ deps += [ "//components/metrics:serialization", - "//components/services/font:lib", "//third_party/fontconfig", ] }
diff --git a/chromecast/browser/DEPS b/chromecast/browser/DEPS index 225a17d1..aea8f3b 100644 --- a/chromecast/browser/DEPS +++ b/chromecast/browser/DEPS
@@ -16,7 +16,6 @@ "+components/prefs", "+components/pref_registry", "+components/proxy_config", - "+components/services/font", "+components/storage_monitor", "+components/user_prefs", "+components/version_info",
diff --git a/chromecast/browser/android/BUILD.gn b/chromecast/browser/android/BUILD.gn index e6d128e..788510e 100644 --- a/chromecast/browser/android/BUILD.gn +++ b/chromecast/browser/android/BUILD.gn
@@ -133,8 +133,8 @@ ":reactive_android_java", "//base:base_java", "//chromecast/base:base_java", - "//components/content_view:content_view_java", "//components/crash/android:java", + "//components/embedder_support/android:content_view_java", "//components/embedder_support/android:media_java", "//components/embedder_support/android:view_java", "//content/public/android:content_java",
diff --git a/chromecast/browser/android/DEPS b/chromecast/browser/android/DEPS index b548760..0a2a2f05 100644 --- a/chromecast/browser/android/DEPS +++ b/chromecast/browser/android/DEPS
@@ -1,6 +1,5 @@ include_rules = [ "+components/embedder_support/android", - "+components/content_view", "+content/public/android", "+jni", "+ui/android",
diff --git a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsView.java b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsView.java index d4be4c80..f86216c 100644 --- a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsView.java +++ b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastWebContentsView.java
@@ -8,7 +8,7 @@ import android.widget.FrameLayout; import org.chromium.chromecast.base.ScopeFactory; -import org.chromium.components.content_view.ContentView; +import org.chromium.components.embedder_support.view.ContentView; import org.chromium.components.embedder_support.view.ContentViewRenderView; import org.chromium.content_public.browser.ContentViewCore; import org.chromium.content_public.browser.WebContents;
diff --git a/chromecast/browser/cast_content_browser_client.cc b/chromecast/browser/cast_content_browser_client.cc index 2d914a59..05b22d807 100644 --- a/chromecast/browser/cast_content_browser_client.cc +++ b/chromecast/browser/cast_content_browser_client.cc
@@ -76,11 +76,6 @@ #include "media/mojo/services/media_service.h" // nogncheck #endif // ENABLE_MOJO_MEDIA_IN_BROWSER_PROCESS -#if defined(OS_LINUX) -#include "components/services/font/font_service_app.h" // nogncheck -#include "components/services/font/public/interfaces/constants.mojom.h" // nogncheck -#endif - #if defined(OS_LINUX) || defined(OS_ANDROID) #include "components/crash/content/app/breakpad_linux.h" #include "components/crash/content/browser/crash_handler_host_linux.h" @@ -688,14 +683,6 @@ #endif } -void CastContentBrowserClient::RegisterOutOfProcessServices( - OutOfProcessServiceMap* services) { -#if defined(OS_LINUX) - (*services)[font_service::mojom::kServiceName] = - base::BindRepeating(&base::ASCIIToUTF16, "Font Service"); -#endif -} - std::unique_ptr<base::Value> CastContentBrowserClient::GetServiceManifestOverlay( base::StringPiece service_name) {
diff --git a/chromecast/browser/cast_content_browser_client.h b/chromecast/browser/cast_content_browser_client.h index a61ea2db..8f9502c 100644 --- a/chromecast/browser/cast_content_browser_client.h +++ b/chromecast/browser/cast_content_browser_client.h
@@ -183,7 +183,6 @@ void RegisterInProcessServices( StaticServiceMap* services, content::ServiceManagerConnection* connection) override; - void RegisterOutOfProcessServices(OutOfProcessServiceMap* services) override; std::unique_ptr<base::Value> GetServiceManifestOverlay( base::StringPiece service_name) override; void GetAdditionalMappedFilesForChildProcess(
diff --git a/chromecast/graphics/cast_window_manager.h b/chromecast/graphics/cast_window_manager.h index fd2a5679..b17de4f3 100644 --- a/chromecast/graphics/cast_window_manager.h +++ b/chromecast/graphics/cast_window_manager.h
@@ -34,9 +34,9 @@ VOLUME, MEDIA_INFO, SETTINGS, - CORNERS_OVERLAY, BOOT_ANIMATION_OVERLAY, - TOP = BOOT_ANIMATION_OVERLAY + CORNERS_OVERLAY, + TOP = CORNERS_OVERLAY }; virtual ~CastWindowManager() {}
diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn index 8e171b0..bf64f423 100644 --- a/components/autofill/core/browser/BUILD.gn +++ b/components/autofill/core/browser/BUILD.gn
@@ -311,6 +311,7 @@ "test_autofill_provider.h", "test_credit_card_save_manager.cc", "test_credit_card_save_manager.h", + "test_event_waiter.h", "test_form_data_importer.cc", "test_form_data_importer.h", "test_form_structure.cc",
diff --git a/components/autofill/core/browser/test_event_waiter.h b/components/autofill/core/browser/test_event_waiter.h new file mode 100644 index 0000000..b7f7102 --- /dev/null +++ b/components/autofill/core/browser/test_event_waiter.h
@@ -0,0 +1,90 @@ +// 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 COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_EVENT_WAITER_H_ +#define COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_EVENT_WAITER_H_ + +#include <list> + +#include "base/location.h" +#include "base/run_loop.h" +#include "base/threading/thread_task_runner_handle.h" +#include "base/time/time.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace autofill { + +// EventWaiter is used to wait on specific events that may have occured +// before the call to Wait(), or after, in which case a RunLoop is used. +// +// Usage: +// waiter_ = std::make_unique<EventWaiter>({ ... }); +// +// Do stuff, which (a)synchronously calls waiter_->OnEvent(...). +// +// waiter_->Wait(); <- Will either return right away if events were observed, +// <- or use a RunLoop's Run/Quit to wait. +// +// Optionally, event waiters can be quit the RunLoop after timing out. +template <typename Event> +class EventWaiter { + public: + explicit EventWaiter( + std::list<Event> event_sequence, + base::TimeDelta timeout = base::TimeDelta::FromSeconds(0)); + ~EventWaiter(); + + // Either returns right away if all events were observed between this + // object's construction and this call to Wait(), or use a RunLoop to wait + // for them. + bool Wait(); + + // Observes an event (quits the RunLoop if we are done waiting). + void OnEvent(Event event); + + private: + std::list<Event> events_; + base::RunLoop run_loop_; + + DISALLOW_COPY_AND_ASSIGN(EventWaiter); +}; + +template <typename Event> +EventWaiter<Event>::EventWaiter(std::list<Event> event_sequence, + base::TimeDelta timeout) + : events_(std::move(event_sequence)) { + if (!timeout.is_zero()) { + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, run_loop_.QuitClosure(), timeout); + } +} + +template <typename Event> +EventWaiter<Event>::~EventWaiter() {} + +template <typename Event> +bool EventWaiter<Event>::Wait() { + if (events_.empty()) + return true; + + DCHECK(!run_loop_.running()); + run_loop_.Run(); + return events_.empty(); +} + +template <typename Event> +void EventWaiter<Event>::OnEvent(Event event) { + if (events_.empty()) + return; + + ASSERT_EQ(events_.front(), event); + events_.pop_front(); + // Only quit the loop if no other events are expected. + if (events_.empty() && run_loop_.running()) + run_loop_.Quit(); +} + +} // namespace autofill + +#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_TEST_EVENT_WAITER_H_
diff --git a/components/browser_sync/profile_sync_service.cc b/components/browser_sync/profile_sync_service.cc index 5dc9d77c..b72b5b9 100644 --- a/components/browser_sync/profile_sync_service.cc +++ b/components/browser_sync/profile_sync_service.cc
@@ -785,22 +785,25 @@ // TODO(crbug.com/839834): See if we can change this by either shutting down // immediately (not posting a task), or setting the unrecoverable error as // part of the posted task. - DCHECK((GetDisableReasons() & DISABLE_REASON_UNRECOVERABLE_ERROR) || - !engine_); + DCHECK(HasDisableReason(DISABLE_REASON_UNRECOVERABLE_ERROR) || !engine_); return State::DISABLED; } - // From this point on, Sync can start in principle. + // Since there is no disable reason, Sync can start in principle. DCHECK(CanSyncStart()); + // The presence of an auth error overrides any non-disabled state. + // Note: We typically shouldn't have auth errors without an initialized + // engine, but it can happen e.g. if a refresh token gets revoked while Sync + // is off. + if (GetAuthError().state() != GoogleServiceAuthError::NONE) { + return State::AUTH_ERROR; + } + // Typically, Sync won't start until the initial setup is at least in // progress. StartupController::TryStartImmediately bypasses the first setup // check though, so we first have to check whether the engine is initialized. if (!IsEngineInitialized()) { - // Note: We generally shouldn't be in an auth error state here (we get those - // errors only after the engine is initialized), but if we received an auth - // error and then shut down, it'll still be here. - // TODO(crbug.com/839834): Should we check for an auth error first here? switch (startup_controller_->GetState()) { case syncer::StartupController::State::NOT_STARTED: DCHECK(!engine_); @@ -818,10 +821,6 @@ // The DataTypeManager gets created once the engine is initialized. DCHECK(data_type_manager_); - if (GetAuthError().state() != GoogleServiceAuthError::NONE) { - return State::AUTH_ERROR; - } - if (!IsFirstSetupComplete()) { DCHECK(!ConfigurationDone()); return State::WAITING_FOR_CONSENT;
diff --git a/components/browser_sync/sync_auth_manager.cc b/components/browser_sync/sync_auth_manager.cc index ff1a730..17bd3e0 100644 --- a/components/browser_sync/sync_auth_manager.cc +++ b/components/browser_sync/sync_auth_manager.cc
@@ -153,11 +153,13 @@ if (!request_access_token_retry_timer_.IsRunning()) { request_access_token_backoff_.Reset(); } - ClearAuthError(); + last_auth_error_ = GoogleServiceAuthError::AuthErrorNone(); break; case syncer::CONNECTION_SERVER_ERROR: - UpdateAuthErrorState( - GoogleServiceAuthError(GoogleServiceAuthError::CONNECTION_FAILED)); + // TODO(crbug.com/839834): Verify whether CONNECTION_FAILED is really an + // appropriate auth error here; maybe SERVICE_ERROR would be better? + last_auth_error_ = + GoogleServiceAuthError(GoogleServiceAuthError::CONNECTION_FAILED); break; case syncer::CONNECTION_NOT_ATTEMPTED: // The connection status should never change to "not attempted". @@ -166,15 +168,6 @@ } } -void SyncAuthManager::UpdateAuthErrorState( - const GoogleServiceAuthError& error) { - last_auth_error_ = error; -} - -void SyncAuthManager::ClearAuthError() { - UpdateAuthErrorState(GoogleServiceAuthError::AuthErrorNone()); -} - void SyncAuthManager::ClearAccessTokenAndRequest() { access_token_.clear(); request_access_token_retry_timer_.Stop(); @@ -184,7 +177,10 @@ } void SyncAuthManager::Clear() { - ClearAuthError(); + // TODO(crbug.com/839834): Clearing the auth error here isn't quite right. + // It makes sense to clear any auth error we got from the Sync server, but we + // should probably retain any errors from the identity manager. + last_auth_error_ = GoogleServiceAuthError::AuthErrorNone(); ClearAccessTokenAndRequest(); } @@ -222,7 +218,7 @@ GoogleServiceAuthError::FromInvalidGaiaCredentialsReason( GoogleServiceAuthError::InvalidGaiaCredentialsReason:: CREDENTIALS_REJECTED_BY_CLIENT); - UpdateAuthErrorState(invalid_token_error); + last_auth_error_ = invalid_token_error; credentials_changed_callback_.Run(); return; @@ -248,8 +244,10 @@ return; } - UpdateAuthErrorState( - GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED)); + // TODO(crbug.com/839834): REQUEST_CANCELED doesn't seem like the right auth + // error to use here. Maybe INVALID_GAIA_CREDENTIALS? + last_auth_error_ = + GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED); ClearAccessTokenAndRequest(); @@ -310,7 +308,7 @@ case GoogleServiceAuthError::NONE: token_status_.token_receive_time = base::Time::Now(); sync_prefs_->SetSyncAuthError(false); - ClearAuthError(); + last_auth_error_ = GoogleServiceAuthError::AuthErrorNone(); break; case GoogleServiceAuthError::CONNECTION_FAILED: case GoogleServiceAuthError::REQUEST_CANCELED: @@ -328,11 +326,11 @@ break; case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS: sync_prefs_->SetSyncAuthError(true); - UpdateAuthErrorState(error); + last_auth_error_ = error; break; default: LOG(ERROR) << "Unexpected persistent error: " << error.ToString(); - UpdateAuthErrorState(error); + last_auth_error_ = error; } credentials_changed_callback_.Run();
diff --git a/components/browser_sync/sync_auth_manager.h b/components/browser_sync/sync_auth_manager.h index a3278f3a..3bbdf23 100644 --- a/components/browser_sync/sync_auth_manager.h +++ b/components/browser_sync/sync_auth_manager.h
@@ -94,9 +94,6 @@ void ResetRequestAccessTokenBackoffForTest(); private: - void UpdateAuthErrorState(const GoogleServiceAuthError& error); - void ClearAuthError(); - void ClearAccessTokenAndRequest(); void RequestAccessToken(); @@ -114,6 +111,10 @@ // This is a cache of the last authentication response we received either // from the sync server or from Chrome's identity/token management system. + // TODO(crbug.com/839834): Differentiate between these types of auth errors, + // since their semantics and lifetimes are quite different: e.g. the former + // can only exist while the Sync engine is initialized; the latter exists + // independent of Sync state, and probably shouldn't get reset in Clear(). GoogleServiceAuthError last_auth_error_; // The current access token. This is mutually exclusive with
diff --git a/components/consent_auditor/consent_auditor.cc b/components/consent_auditor/consent_auditor.cc index 678f169..643292f9 100644 --- a/components/consent_auditor/consent_auditor.cc +++ b/components/consent_auditor/consent_auditor.cc
@@ -44,6 +44,8 @@ return UserEventSpecifics::UserConsent::BACKUP_AND_RESTORE; case consent_auditor::Feature::GOOGLE_LOCATION_SERVICE: return UserEventSpecifics::UserConsent::GOOGLE_LOCATION_SERVICE; + case consent_auditor::Feature::CHROME_UNIFIED_CONSENT: + return UserEventSpecifics::UserConsent::CHROME_UNIFIED_CONSENT; } NOTREACHED(); return UserEventSpecifics::UserConsent::FEATURE_UNSPECIFIED; @@ -72,6 +74,8 @@ return UserConsentSpecifics::BACKUP_AND_RESTORE; case consent_auditor::Feature::GOOGLE_LOCATION_SERVICE: return UserConsentSpecifics::GOOGLE_LOCATION_SERVICE; + case consent_auditor::Feature::CHROME_UNIFIED_CONSENT: + return UserConsentSpecifics::CHROME_UNIFIED_CONSENT; } NOTREACHED(); return UserConsentSpecifics::FEATURE_UNSPECIFIED; @@ -91,9 +95,9 @@ app_version_(app_version), app_locale_(app_locale) { if (IsSeparateConsentTypeEnabled()) { - DCHECK(consent_sync_bridge_); + DCHECK(consent_sync_bridge_ && !user_event_service_); } else { - DCHECK(user_event_service_); + DCHECK(user_event_service_ && !consent_sync_bridge_); } DCHECK(pref_service_); }
diff --git a/components/consent_auditor/consent_auditor.h b/components/consent_auditor/consent_auditor.h index ceb9b9ff..ef00767 100644 --- a/components/consent_auditor/consent_auditor.h +++ b/components/consent_auditor/consent_auditor.h
@@ -42,6 +42,7 @@ PLAY_STORE = 1, BACKUP_AND_RESTORE = 2, GOOGLE_LOCATION_SERVICE = 3, + CHROME_UNIFIED_CONSENT = 4, FEATURE_LAST = GOOGLE_LOCATION_SERVICE };
diff --git a/components/consent_auditor/consent_auditor_unittest.cc b/components/consent_auditor/consent_auditor_unittest.cc index 503607c..3648427 100644 --- a/components/consent_auditor/consent_auditor_unittest.cc +++ b/components/consent_auditor/consent_auditor_unittest.cc
@@ -132,6 +132,10 @@ void SetConsentSyncBridge(std::unique_ptr<syncer::ConsentSyncBridge> bridge) { consent_sync_bridge_ = std::move(bridge); } + void SetUserEventService( + std::unique_ptr<syncer::FakeUserEventService> service) { + user_event_service_ = std::move(service); + } void SetIsSeparateConsentTypeEnabledFeature(bool new_value) { // VariationParamsManager supports only one @@ -286,11 +290,14 @@ } TEST_F(ConsentAuditorTest, RecordGaiaConsentAsUserConsent) { + SetIsSeparateConsentTypeEnabledFeature(true); + auto wrapped_fake_bridge = std::make_unique<FakeConsentSyncBridge>(); FakeConsentSyncBridge* fake_bridge = wrapped_fake_bridge.get(); SetIsSeparateConsentTypeEnabledFeature(true); SetConsentSyncBridge(std::move(wrapped_fake_bridge)); + SetUserEventService(nullptr); SetAppVersion(kCurrentAppVersion); SetAppLocale(kCurrentAppLocale); BuildConsentAuditor(); @@ -304,9 +311,6 @@ kConfirmationMessageId, ConsentStatus::GIVEN); base::Time time_after = base::Time::Now(); - // The consent should be recorded as a separate type and not as a user event. - EXPECT_EQ(0U, user_event_service()->GetRecordedUserEvents().size()); - std::vector<UserConsentSpecifics> consents = fake_bridge->GetRecordedUserConsents(); ASSERT_EQ(1U, consents.size()); @@ -347,6 +351,7 @@ fake_bridge->SetControllerDelegateOnUIThread(expected_delegate_ptr); SetConsentSyncBridge(std::move(fake_bridge)); + SetUserEventService(nullptr); BuildConsentAuditor(); // There is a bridge (i.e. separate sync type for consents is enabled), thus,
diff --git a/components/consent_auditor/fake_consent_auditor.cc b/components/consent_auditor/fake_consent_auditor.cc index ca0960a..2adee70 100644 --- a/components/consent_auditor/fake_consent_auditor.cc +++ b/components/consent_auditor/fake_consent_auditor.cc
@@ -26,9 +26,8 @@ int confirmation_grd_id, consent_auditor::ConsentStatus status) { account_id_ = account_id; - std::vector<int> ids = description_grd_ids; - ids.push_back(confirmation_grd_id); - recorded_id_vectors_.push_back(std::move(ids)); + recorded_id_vectors_.push_back(description_grd_ids); + recorded_confirmation_ids_.push_back(confirmation_grd_id); recorded_features_.push_back(feature); recorded_statuses_.push_back(status); }
diff --git a/components/consent_auditor/fake_consent_auditor.h b/components/consent_auditor/fake_consent_auditor.h index d8cf63b..56a37ce 100644 --- a/components/consent_auditor/fake_consent_auditor.h +++ b/components/consent_auditor/fake_consent_auditor.h
@@ -36,6 +36,10 @@ return recorded_id_vectors_; } + const std::vector<int>& recorded_confirmation_ids() const { + return recorded_confirmation_ids_; + } + const std::vector<Feature>& recorded_features() { return recorded_features_; } const std::vector<ConsentStatus>& recorded_statuses() { @@ -45,6 +49,7 @@ private: std::string account_id_; std::vector<std::vector<int>> recorded_id_vectors_; + std::vector<int> recorded_confirmation_ids_; std::vector<Feature> recorded_features_; std::vector<ConsentStatus> recorded_statuses_;
diff --git a/components/content_settings/core/browser/content_settings_ephemeral_provider.cc b/components/content_settings/core/browser/content_settings_ephemeral_provider.cc index a50936bf..7e80a06 100644 --- a/components/content_settings/core/browser/content_settings_ephemeral_provider.cc +++ b/components/content_settings/core/browser/content_settings_ephemeral_provider.cc
@@ -68,11 +68,23 @@ return false; } - content_settings_rules_.SetValue( - primary_pattern, secondary_pattern, content_type, resource_identifier, - store_last_modified_ ? clock_->Now() : base::Time(), in_value); - NotifyObservers(primary_pattern, secondary_pattern, content_type, - resource_identifier); + if (in_value) { + content_settings_rules_.SetValue( + primary_pattern, secondary_pattern, content_type, resource_identifier, + store_last_modified_ ? clock_->Now() : base::Time(), in_value); + NotifyObservers(primary_pattern, secondary_pattern, content_type, + resource_identifier); + } else { + // If the value exists, delete it. + if (content_settings_rules_.GetLastModified( + primary_pattern, secondary_pattern, content_type, + resource_identifier) != base::Time()) { + content_settings_rules_.DeleteValue(primary_pattern, secondary_pattern, + content_type, resource_identifier); + NotifyObservers(primary_pattern, secondary_pattern, content_type, + resource_identifier); + } + } return true; }
diff --git a/components/content_settings/core/browser/content_settings_ephemeral_provider_unittest.cc b/components/content_settings/core/browser/content_settings_ephemeral_provider_unittest.cc index f9208f8..33e6b6d 100644 --- a/components/content_settings/core/browser/content_settings_ephemeral_provider_unittest.cc +++ b/components/content_settings/core/browser/content_settings_ephemeral_provider_unittest.cc
@@ -157,4 +157,23 @@ EXPECT_EQ(nullptr, rule_iterator); } +// Tests if a pattern can be deleted by passing null value. +TEST_F(ContentSettingsEphemeralProviderTest, DeleteValueByPassingNull) { + ContentSettingsPattern site_pattern = + ContentSettingsPattern::FromString("https://example.com"); + + provider()->SetWebsiteSetting(site_pattern, site_pattern, ephemeral_type(0), + std::string(), + new base::Value(CONTENT_SETTING_ALLOW)); + std::unique_ptr<RuleIterator> rule_iterator = + provider()->GetRuleIterator(ephemeral_type(0), std::string(), false); + EXPECT_NE(nullptr, rule_iterator); + + provider()->SetWebsiteSetting(site_pattern, site_pattern, ephemeral_type(0), + std::string(), nullptr); + rule_iterator = + provider()->GetRuleIterator(ephemeral_type(0), std::string(), false); + EXPECT_EQ(nullptr, rule_iterator); +} + } // namespace content_settings
diff --git a/components/content_view/BUILD.gn b/components/content_view/BUILD.gn deleted file mode 100644 index c50f552..0000000 --- a/components/content_view/BUILD.gn +++ /dev/null
@@ -1,15 +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. - -import("//build/config/android/rules.gni") - -android_library("content_view_java") { - deps = [ - "//base:base_java", - "//content/public/android:content_java", - "//ui/android:ui_java", - ] - java_files = - [ "java/src/org/chromium/components/content_view/ContentView.java" ] -}
diff --git a/components/content_view/DEPS b/components/content_view/DEPS deleted file mode 100644 index f20cebbb..0000000 --- a/components/content_view/DEPS +++ /dev/null
@@ -1,6 +0,0 @@ -include_rules = [ - "-content/public/android/java", - "+content/public/android/java/src/org/chromium/content_public", - - "+ui/android/java", -]
diff --git a/components/content_view/OWNERS b/components/content_view/OWNERS deleted file mode 100644 index 7bf23a78..0000000 --- a/components/content_view/OWNERS +++ /dev/null
@@ -1,6 +0,0 @@ -boliu@chromium.org -jinsukkim@chromium.org -tedchoc@chromium.org - -# COMPONENT: Internals>Core -# OS: Android
diff --git a/components/content_view/README b/components/content_view/README deleted file mode 100644 index e8196ae1..0000000 --- a/components/content_view/README +++ /dev/null
@@ -1,2 +0,0 @@ -- ContentView exists in Android UI view hierarchy, and exposes various -view functionality to content layer.
diff --git a/components/embedder_support/android/BUILD.gn b/components/embedder_support/android/BUILD.gn index 64186efc..3e993b0 100644 --- a/components/embedder_support/android/BUILD.gn +++ b/components/embedder_support/android/BUILD.gn
@@ -28,6 +28,17 @@ ] } +android_library("content_view_java") { + deps = [ + "//base:base_java", + "//content/public/android:content_java", + "//ui/android:ui_java", + ] + java_files = [ + "java/src/org/chromium/components/embedder_support/view/ContentView.java", + ] +} + android_library("view_java") { deps = [ "//base:base_java",
diff --git a/components/content_view/java/src/org/chromium/components/content_view/ContentView.java b/components/embedder_support/android/java/src/org/chromium/components/embedder_support/view/ContentView.java similarity index 99% rename from components/content_view/java/src/org/chromium/components/content_view/ContentView.java rename to components/embedder_support/android/java/src/org/chromium/components/embedder_support/view/ContentView.java index 513233d..c3334d9 100644 --- a/components/content_view/java/src/org/chromium/components/content_view/ContentView.java +++ b/components/embedder_support/android/java/src/org/chromium/components/embedder_support/view/ContentView.java
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -package org.chromium.components.content_view; +package org.chromium.components.embedder_support.view; import android.content.Context; import android.content.res.Configuration;
diff --git a/components/password_manager/core/browser/DEPS b/components/password_manager/core/browser/DEPS index 80a0800..b62763e 100644 --- a/components/password_manager/core/browser/DEPS +++ b/components/password_manager/core/browser/DEPS
@@ -30,4 +30,7 @@ "password_manager_metrics_recorder_unittest\.cc": [ "+components/ukm", ], + "password_manager_unittest\.cc": [ + "+components/ukm", + ], }
diff --git a/components/password_manager/core/browser/password_form_metrics_recorder.cc b/components/password_manager/core/browser/password_form_metrics_recorder.cc index f231b48..226cc8e 100644 --- a/components/password_manager/core/browser/password_form_metrics_recorder.cc +++ b/components/password_manager/core/browser/password_form_metrics_recorder.cc
@@ -144,6 +144,11 @@ spec_priority_of_generated_password_.value()); } + if (showed_manual_fallback_for_saving_) { + ukm_entry_builder_.SetSaving_ShowedManualFallbackForSaving( + showed_manual_fallback_for_saving_.value()); + } + ukm_entry_builder_.Record(ukm::UkmRecorder::Get()); } @@ -278,6 +283,13 @@ static_cast<uint64_t>(comparison_result)); } +void PasswordFormMetricsRecorder::RecordShowManualFallbackForSaving( + bool has_generated_password, + bool is_update) { + showed_manual_fallback_for_saving_ = + 1 + (has_generated_password ? 2 : 0) + (is_update ? 4 : 0); +} + int PasswordFormMetricsRecorder::GetActionsTaken() const { return static_cast<int>(user_action_) + static_cast<int>(UserAction::kMax) *
diff --git a/components/password_manager/core/browser/password_form_metrics_recorder.h b/components/password_manager/core/browser/password_form_metrics_recorder.h index 4277d507..f0d1916 100644 --- a/components/password_manager/core/browser/password_form_metrics_recorder.h +++ b/components/password_manager/core/browser/password_form_metrics_recorder.h
@@ -272,6 +272,11 @@ void RecordParsingsComparisonResult( ParsingComparisonResult comparison_result); + // Records that Chrome noticed that it should show a manual fallback for + // saving. + void RecordShowManualFallbackForSaving(bool has_generated_password, + bool is_update); + private: friend class base::RefCounted<PasswordFormMetricsRecorder>; @@ -369,6 +374,12 @@ // PasswordFormManager. Reported upon destruction. std::map<DetailedUserAction, int64_t> detailed_user_actions_counts_; + // Bitmap of whether and why a manual fallback for saving was shown: + // 1 = the fallback was shown. + // 2 = the password was generated. + // 4 = this was an update prompt. + base::Optional<uint32_t> showed_manual_fallback_for_saving_; + DISALLOW_COPY_AND_ASSIGN(PasswordFormMetricsRecorder); };
diff --git a/components/password_manager/core/browser/password_form_metrics_recorder_unittest.cc b/components/password_manager/core/browser/password_form_metrics_recorder_unittest.cc index d2fb9f8..05a9e8b 100644 --- a/components/password_manager/core/browser/password_form_metrics_recorder_unittest.cc +++ b/components/password_manager/core/browser/password_form_metrics_recorder_unittest.cc
@@ -612,4 +612,68 @@ } } +// Verify that the the mapping is correct and that metrics are actually +// recorded. +TEST(PasswordFormMetricsRecorder, RecordShowManualFallbackForSaving) { + base::test::ScopedTaskEnvironment scoped_task_environment_; + struct { + bool has_generated_password; + bool is_update; + int expected_value; + } kTests[] = { + {false, false, 1}, + {true, false, 1 + 2}, + {false, true, 1 + 4}, + {true, true, 1 + 2 + 4}, + }; + for (const auto& test : kTests) { + ukm::TestAutoSetUkmRecorder test_ukm_recorder; + { + auto recorder = CreatePasswordFormMetricsRecorder( + true /*is_main_frame_secure*/, &test_ukm_recorder); + recorder->RecordShowManualFallbackForSaving(test.has_generated_password, + test.is_update); + } + auto entries = test_ukm_recorder.GetEntriesByName(UkmEntry::kEntryName); + ASSERT_EQ(1u, entries.size()); + EXPECT_EQ(kTestSourceId, entries[0]->source_id); + test_ukm_recorder.ExpectEntryMetric( + entries[0], UkmEntry::kSaving_ShowedManualFallbackForSavingName, + test.expected_value); + } +} + +// Verify that no 0 is recorded if now fallback icon is shown. +TEST(PasswordFormMetricsRecorder, NoRecordShowManualFallbackForSaving) { + base::test::ScopedTaskEnvironment scoped_task_environment_; + ukm::TestAutoSetUkmRecorder test_ukm_recorder; + { + auto recorder = CreatePasswordFormMetricsRecorder( + true /*is_main_frame_secure*/, &test_ukm_recorder); + } + auto entries = test_ukm_recorder.GetEntriesByName(UkmEntry::kEntryName); + ASSERT_EQ(1u, entries.size()); + EXPECT_EQ(kTestSourceId, entries[0]->source_id); + EXPECT_FALSE(test_ukm_recorder.EntryHasMetric( + entries[0], UkmEntry::kSaving_ShowedManualFallbackForSavingName)); +} + +// Verify that only the latest value is recorded +TEST(PasswordFormMetricsRecorder, RecordShowManualFallbackForSavingLatestOnly) { + base::test::ScopedTaskEnvironment scoped_task_environment_; + ukm::TestAutoSetUkmRecorder test_ukm_recorder; + { + auto recorder = CreatePasswordFormMetricsRecorder( + true /*is_main_frame_secure*/, &test_ukm_recorder); + recorder->RecordShowManualFallbackForSaving(true, false); + recorder->RecordShowManualFallbackForSaving(true, true); + } + auto entries = test_ukm_recorder.GetEntriesByName(UkmEntry::kEntryName); + ASSERT_EQ(1u, entries.size()); + EXPECT_EQ(kTestSourceId, entries[0]->source_id); + test_ukm_recorder.ExpectEntryMetric( + entries[0], UkmEntry::kSaving_ShowedManualFallbackForSavingName, + 1 + 2 + 4); +} + } // namespace password_manager
diff --git a/components/password_manager/core/browser/password_manager.cc b/components/password_manager/core/browser/password_manager.cc index 429aeaf..e4c0e56 100644 --- a/components/password_manager/core/browser/password_manager.cc +++ b/components/password_manager/core/browser/password_manager.cc
@@ -534,6 +534,8 @@ bool is_update = IsPasswordUpdate(*provisional_save_manager_); client_->ShowManualFallbackForSaving(std::move(provisional_save_manager_), has_generated_password, is_update); + matched_manager->GetMetricsRecorder()->RecordShowManualFallbackForSaving( + has_generated_password, is_update); } else { HideManualFallbackForSaving(); }
diff --git a/components/password_manager/core/browser/password_manager_client.h b/components/password_manager/core/browser/password_manager_client.h index ef41ed6..30e19da 100644 --- a/components/password_manager/core/browser/password_manager_client.h +++ b/components/password_manager/core/browser/password_manager_client.h
@@ -260,6 +260,10 @@ // incognito context. Callers should guard against this. virtual PasswordRequirementsService* GetPasswordRequirementsService(); + // Causes all live PasswordFormManager objects to query the password store + // again. Results in updating the fill information on the page. + virtual void UpdateFormManagers() {} + private: DISALLOW_COPY_AND_ASSIGN(PasswordManagerClient); };
diff --git a/components/password_manager/core/browser/password_manager_unittest.cc b/components/password_manager/core/browser/password_manager_unittest.cc index 587ed1a..bbb1f02 100644 --- a/components/password_manager/core/browser/password_manager_unittest.cc +++ b/components/password_manager/core/browser/password_manager_unittest.cc
@@ -32,7 +32,10 @@ #include "components/password_manager/core/browser/stub_password_manager_driver.h" #include "components/password_manager/core/common/password_manager_features.h" #include "components/password_manager/core/common/password_manager_pref_names.h" +#include "components/ukm/test_ukm_recorder.h" +#include "components/ukm/ukm_source.h" #include "net/cert/cert_status_flags.h" +#include "services/metrics/public/cpp/ukm_builders.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -2156,6 +2159,8 @@ #endif TEST_F(PasswordManagerTest, ManualFallbackForSaving) { + ukm::TestAutoSetUkmRecorder test_ukm_recorder; + EXPECT_CALL(client_, IsSavingAndFillingEnabledForCurrentPage()) .WillRepeatedly(Return(true)); @@ -2191,6 +2196,22 @@ // Hide the manual fallback. EXPECT_CALL(client_, HideManualFallbackForSaving()); manager()->HideManualFallbackForSaving(); + + // Two PasswordFormManagers instances hold references to a shared + // PasswordFormMetrics recorder. These need to be freed to flush the metrics + // into the test_ukm_recorder. + manager_.reset(); + form_manager_to_save.reset(); + + // Verify that the last state is recorded. + std::vector<const ukm::mojom::UkmEntry*> ukm_entries = + test_ukm_recorder.GetEntriesByName( + ukm::builders::PasswordForm::kEntryName); + ASSERT_EQ(1u, ukm_entries.size()); + test_ukm_recorder.ExpectEntryMetric( + ukm_entries[0], + ukm::builders::PasswordForm::kSaving_ShowedManualFallbackForSavingName, + 1); } // Tests that the manual fallback for saving isn't shown if there is no response
diff --git a/components/services/font/public/cpp/font_service_thread.cc b/components/services/font/public/cpp/font_service_thread.cc index b4f3aa4..38e3640 100644 --- a/components/services/font/public/cpp/font_service_thread.cc +++ b/components/services/font/public/cpp/font_service_thread.cc
@@ -22,7 +22,6 @@ : base::Thread(kFontThreadName), font_service_info_(font_service.PassInterface()), weak_factory_(this) { - DETACH_FROM_THREAD(thread_checker_); Start(); } @@ -32,7 +31,7 @@ SkFontConfigInterface::FontIdentity* out_font_identity, SkString* out_family_name, SkFontStyle* out_style) { - DCHECK_NE(GetThreadId(), base::PlatformThread::CurrentId()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); bool out_valid = false; // This proxies to the other thread, which proxies to mojo. Only on the reply @@ -55,7 +54,6 @@ std::string* out_family_name, bool* out_is_bold, bool* out_is_italic) { - DCHECK_NE(GetThreadId(), base::PlatformThread::CurrentId()); bool out_valid = false; base::WaitableEvent done_event; task_runner()->PostTask( @@ -76,7 +74,6 @@ bool is_bold, float device_scale_factor, font_service::mojom::FontRenderStylePtr* out_font_render_style) { - DCHECK_NE(GetThreadId(), base::PlatformThread::CurrentId()); bool out_valid = false; base::WaitableEvent done_event; task_runner()->PostTask( @@ -95,7 +92,6 @@ uint32_t charset, uint32_t fallback_family_type, base::File* out_font_file_handle) { - DCHECK_NE(GetThreadId(), base::PlatformThread::CurrentId()); base::WaitableEvent done_event; task_runner()->PostTask( FROM_HERE, @@ -107,7 +103,7 @@ scoped_refptr<MappedFontFile> FontServiceThread::OpenStream( const SkFontConfigInterface::FontIdentity& identity) { - DCHECK_NE(GetThreadId(), base::PlatformThread::CurrentId()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); base::File stream_file; // This proxies to the other thread, which proxies to mojo. Only on the @@ -214,7 +210,6 @@ void FontServiceThread::OnOpenStreamComplete(base::WaitableEvent* done_event, base::File* output_file, base::File file) { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); pending_waitable_events_.erase(done_event); *output_file = std::move(file); done_event->Signal();
diff --git a/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerFacade.java b/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerFacade.java index 231668a..2bb0c90 100644 --- a/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerFacade.java +++ b/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerFacade.java
@@ -13,7 +13,6 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.os.SystemClock; @@ -22,6 +21,7 @@ import android.support.annotation.MainThread; import android.support.annotation.Nullable; +import org.chromium.base.AsyncTask; import org.chromium.base.Callback; import org.chromium.base.ContextUtils; import org.chromium.base.Log; @@ -311,6 +311,9 @@ /** * Asynchronous version of {@link #getGoogleAccounts()}. */ + // Incorrectly infers that this is called on a worker thread because of AsyncTask doInBackground + // overriding. + @SuppressWarnings("WrongThread") @MainThread public void getGoogleAccounts(final Callback<AccountManagerResult<Account[]>> callback) { ThreadUtils.assertOnUiThread(); @@ -347,6 +350,9 @@ /** * Asynchronous version of {@link #tryGetGoogleAccounts()}. */ + // Incorrectly infers that this is called on a worker thread because of AsyncTask doInBackground + // overriding. + @SuppressWarnings("WrongThread") @MainThread public void tryGetGoogleAccounts(final Callback<Account[]> callback) { ThreadUtils.assertOnUiThread(); @@ -519,6 +525,9 @@ }); } + // Incorrectly infers that this is called on a worker thread because of AsyncTask doInBackground + // overriding. + @SuppressWarnings("WrongThread") @MainThread public void checkChildAccountStatus(Account account, Callback<Integer> callback) { ThreadUtils.assertOnUiThread();
diff --git a/components/signin/core/browser/android/junit/src/org/chromium/components/signin/test/AccountManagerFacadeTest.java b/components/signin/core/browser/android/junit/src/org/chromium/components/signin/test/AccountManagerFacadeTest.java index afe485a..b0c9af7 100644 --- a/components/signin/core/browser/android/junit/src/org/chromium/components/signin/test/AccountManagerFacadeTest.java +++ b/components/signin/core/browser/android/junit/src/org/chromium/components/signin/test/AccountManagerFacadeTest.java
@@ -24,13 +24,13 @@ import org.chromium.base.Callback; import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.base.test.asynctask.CustomShadowAsyncTask; import org.chromium.components.signin.AccountManagerDelegateException; import org.chromium.components.signin.AccountManagerFacade; import org.chromium.components.signin.ChildAccountStatus; import org.chromium.components.signin.ProfileDataSource; import org.chromium.components.signin.test.util.AccountHolder; import org.chromium.components.signin.test.util.FakeAccountManagerDelegate; -import org.chromium.testing.local.CustomShadowAsyncTask; import org.chromium.testing.local.CustomShadowUserManager; import java.util.Arrays;
diff --git a/components/signin/core/browser/gaia_cookie_manager_service_unittest.cc b/components/signin/core/browser/gaia_cookie_manager_service_unittest.cc index 8713ea5..4dcfc511 100644 --- a/components/signin/core/browser/gaia_cookie_manager_service_unittest.cc +++ b/components/signin/core/browser/gaia_cookie_manager_service_unittest.cc
@@ -60,30 +60,35 @@ int total = 0; -// Custom matcher for ListedAccounts. -MATCHER_P(ListedAccountEquals, expected, "") { - if (expected.size() != arg.size()) +bool AreAccountListsEqual(const std::vector<gaia::ListedAccount>& left, + const std::vector<gaia::ListedAccount>& right) { + if (left.size() != right.size()) return false; - for (size_t i = 0u; i < expected.size(); ++i) { - const gaia::ListedAccount& expected_account = expected[i]; - const gaia::ListedAccount& actual_account = arg[i]; + for (size_t i = 0u; i < left.size(); ++i) { + const gaia::ListedAccount& left_account = left[i]; + const gaia::ListedAccount& actual_account = right[i]; // If both accounts have an ID, use it for the comparison. - if (!expected_account.id.empty() && !actual_account.id.empty()) { - if (expected_account.id != actual_account.id) + if (!left_account.id.empty() && !actual_account.id.empty()) { + if (left_account.id != actual_account.id) return false; - } else if (expected_account.email != actual_account.email || - expected_account.gaia_id != actual_account.gaia_id || - expected_account.raw_email != actual_account.raw_email || - expected_account.valid != actual_account.valid || - expected_account.signed_out != actual_account.signed_out || - expected_account.verified != actual_account.verified) { + } else if (left_account.email != actual_account.email || + left_account.gaia_id != actual_account.gaia_id || + left_account.raw_email != actual_account.raw_email || + left_account.valid != actual_account.valid || + left_account.signed_out != actual_account.signed_out || + left_account.verified != actual_account.verified) { return false; } } return true; } +// Custom matcher for ListedAccounts. +MATCHER_P(ListedAccountEquals, expected, "") { + return AreAccountListsEqual(expected, arg); +} + class InstrumentedGaiaCookieManagerService : public GaiaCookieManagerService { public: InstrumentedGaiaCookieManagerService( @@ -668,21 +673,31 @@ std::vector<gaia::ListedAccount> signed_out_accounts; std::vector<gaia::ListedAccount> empty_signed_out_accounts; + std::vector<gaia::ListedAccount> nonempty_list_accounts; + gaia::ListedAccount listed_account; + listed_account.email = "a@b.com"; + listed_account.raw_email = "a@b.com"; + listed_account.gaia_id = "8"; + nonempty_list_accounts.push_back(listed_account); + + // Add a single account. EXPECT_CALL(helper, StartFetchingListAccounts()); EXPECT_CALL(observer, OnGaiaAccountsInCookieUpdated( - ListedAccountEquals(empty_list_accounts), + ListedAccountEquals(nonempty_list_accounts), ListedAccountEquals(empty_signed_out_accounts), no_error())); ASSERT_FALSE(helper.ListAccounts(&list_accounts, &signed_out_accounts, GaiaConstants::kChromeSource)); ASSERT_TRUE(list_accounts.empty()); ASSERT_TRUE(signed_out_accounts.empty()); - SimulateListAccountsSuccess(&helper, "[\"f\",[]]"); + SimulateListAccountsSuccess( + &helper, + "[\"f\", [[\"b\", 0, \"n\", \"a@b.com\", \"p\", 0, 0, 0, 0, 1, \"8\"]]]"); - // ListAccounts returns cached data. + // Sanity-check that ListAccounts returns the cached data. ASSERT_TRUE(helper.ListAccounts(&list_accounts, &signed_out_accounts, GaiaConstants::kChromeSource)); - ASSERT_TRUE(list_accounts.empty()); + ASSERT_TRUE(AreAccountListsEqual(nonempty_list_accounts, list_accounts)); ASSERT_TRUE(signed_out_accounts.empty()); EXPECT_CALL(helper, StartFetchingListAccounts()); @@ -692,7 +707,13 @@ ListedAccountEquals(empty_signed_out_accounts), no_error())); helper.ForceOnCookieChangeProcessing(); - // OnCookieChange should invalidate cached data. + // OnCookieChange should invalidate the cached data. + + // Clear the list before calling |ListAccounts()| as GaiaCookieManagerService + // simply leaves the input unaffected in the case where the accounts are + // stale. + list_accounts.clear(); + ASSERT_FALSE(helper.ListAccounts(&list_accounts, &signed_out_accounts, GaiaConstants::kChromeSource)); ASSERT_TRUE(list_accounts.empty());
diff --git a/components/sync/driver/fake_sync_service.cc b/components/sync/driver/fake_sync_service.cc index 5d3102c7..e659d11 100644 --- a/components/sync/driver/fake_sync_service.cc +++ b/components/sync/driver/fake_sync_service.cc
@@ -44,15 +44,17 @@ } // From this point on, Sync can start in principle. DCHECK(CanSyncStart()); + // The presence of an auth error overrides any non-disabled state. + if (GetAuthError() != GoogleServiceAuthError::AuthErrorNone()) { + return State::AUTH_ERROR; + } // Note: We don't distinguish here if the engine doesn't exist at all, or // exists but hasn't finished initializing. if (!IsEngineInitialized()) { return State::INITIALIZING; } - if (GetAuthError() != GoogleServiceAuthError::AuthErrorNone()) { - return State::AUTH_ERROR; - } if (!IsFirstSetupComplete()) { + DCHECK(!ConfigurationDone()); return State::WAITING_FOR_CONSENT; } DCHECK(IsSyncActive());
diff --git a/components/sync/driver/glue/sync_backend_host_core.cc b/components/sync/driver/glue/sync_backend_host_core.cc index 09fd6f07..6e4e2a5 100644 --- a/components/sync/driver/glue/sync_backend_host_core.cc +++ b/components/sync/driver/glue/sync_backend_host_core.cc
@@ -102,7 +102,7 @@ DCHECK(thread_checker_.CalledOnValidThread()); if (!success) { - DoDestroySyncManager(STOP_SYNC); + DoDestroySyncManager(); host_.Call(FROM_HERE, &SyncBackendHostImpl::HandleInitializationFailureOnFrontendLoop); return; @@ -443,7 +443,7 @@ void SyncBackendHostCore::DoShutdown(ShutdownReason reason) { DCHECK(thread_checker_.CalledOnValidThread()); - DoDestroySyncManager(reason); + DoDestroySyncManager(); registrar_ = nullptr; @@ -454,7 +454,7 @@ weak_ptr_factory_.InvalidateWeakPtrs(); } -void SyncBackendHostCore::DoDestroySyncManager(ShutdownReason reason) { +void SyncBackendHostCore::DoDestroySyncManager() { DCHECK(thread_checker_.CalledOnValidThread()); base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( this); @@ -462,7 +462,7 @@ DisableDirectoryTypeDebugInfoForwarding(); save_changes_timer_.reset(); sync_manager_->RemoveObserver(this); - sync_manager_->ShutdownOnSyncThread(reason); + sync_manager_->ShutdownOnSyncThread(); sync_manager_.reset(); } }
diff --git a/components/sync/driver/glue/sync_backend_host_core.h b/components/sync/driver/glue/sync_backend_host_core.h index 7df3b6a..f0d4d978 100644 --- a/components/sync/driver/glue/sync_backend_host_core.h +++ b/components/sync/driver/glue/sync_backend_host_core.h
@@ -132,7 +132,7 @@ // directory and destroy sync manager. void ShutdownOnUIThread(); void DoShutdown(ShutdownReason reason); - void DoDestroySyncManager(ShutdownReason reason); + void DoDestroySyncManager(); // Configuration methods that must execute on sync loop. void DoPurgeDisabledTypes(const ModelTypeSet& to_purge,
diff --git a/components/sync/driver/sync_service.h b/components/sync/driver/sync_service.h index ec332d8..32366672 100644 --- a/components/sync/driver/sync_service.h +++ b/components/sync/driver/sync_service.h
@@ -107,6 +107,11 @@ // disabled it, or simply because there is no authenticated user. Call // GetDisableReasons to figure out which of these it is. DISABLED, + // Sync has encountered an authentication error. Note that Sync may have + // been in any of the below states before, and might go straight back to it + // if the auth error gets resolved. Call GetAuthError for more details on + // the error. + AUTH_ERROR, // Sync can start in principle, but nothing has prodded it to actually do it // yet. Note that during subsequent browser startups, Sync starts // automatically, i.e. no prod is necessary, but during the first start Sync @@ -122,14 +127,6 @@ START_DEFERRED, // The Sync engine is in the process of initializing. INITIALIZING, - // The Sync engine is initialized and the data types may or may not be - // configured (i.e. any of the states below), but Sync has encountered an - // auth error. Call GetAuthError for more details. - // TODO(crbug.com/839834): If we receive an auth error and then shut down, - // we can be in one of the previous states but still have an auth error. Can - // we clear the auth error on shutdown, since it's not persisted anyway? - // Otherwise this state might have to move to just after DISABLED. - AUTH_ERROR, // The Sync engine is initialized, but the user hasn't completed the initial // Sync setup yet, so we won't actually configure the data types. WAITING_FOR_CONSENT,
diff --git a/components/sync/engine/fake_sync_manager.cc b/components/sync/engine/fake_sync_manager.cc index 4801559e..b3b674b15 100644 --- a/components/sync/engine/fake_sync_manager.cc +++ b/components/sync/engine/fake_sync_manager.cc
@@ -192,7 +192,7 @@ // Do nothing. } -void FakeSyncManager::ShutdownOnSyncThread(ShutdownReason reason) { +void FakeSyncManager::ShutdownOnSyncThread() { DCHECK(sync_task_runner_->RunsTasksInCurrentSequence()); test_user_share_.TearDown(); }
diff --git a/components/sync/engine/fake_sync_manager.h b/components/sync/engine/fake_sync_manager.h index f6b1232..1f2b39e 100644 --- a/components/sync/engine/fake_sync_manager.h +++ b/components/sync/engine/fake_sync_manager.h
@@ -98,7 +98,7 @@ void RemoveObserver(Observer* observer) override; SyncStatus GetDetailedStatus() const override; void SaveChanges() override; - void ShutdownOnSyncThread(ShutdownReason reason) override; + void ShutdownOnSyncThread() override; UserShare* GetUserShare() override; ModelTypeConnector* GetModelTypeConnector() override; std::unique_ptr<ModelTypeConnector> GetModelTypeConnectorProxy() override;
diff --git a/components/sync/engine/sync_manager.h b/components/sync/engine/sync_manager.h index d65c6b3c..a1d92af 100644 --- a/components/sync/engine/sync_manager.h +++ b/components/sync/engine/sync_manager.h
@@ -26,7 +26,6 @@ #include "components/sync/engine/model_safe_worker.h" #include "components/sync/engine/model_type_connector.h" #include "components/sync/engine/net/http_post_provider_factory.h" -#include "components/sync/engine/shutdown_reason.h" #include "components/sync/engine/sync_credentials.h" #include "components/sync/engine/sync_encryption_handler.h" #include "components/sync/engine/sync_status.h" @@ -335,7 +334,7 @@ virtual void SaveChanges() = 0; // Issue a final SaveChanges, and close sqlite handles. - virtual void ShutdownOnSyncThread(ShutdownReason reason) = 0; + virtual void ShutdownOnSyncThread() = 0; // May be called from any thread. virtual UserShare* GetUserShare() = 0;
diff --git a/components/sync/engine_impl/sync_manager_impl.cc b/components/sync/engine_impl/sync_manager_impl.cc index 5f753b2..3391def 100644 --- a/components/sync/engine_impl/sync_manager_impl.cc +++ b/components/sync/engine_impl/sync_manager_impl.cc
@@ -489,7 +489,7 @@ observers_.RemoveObserver(observer); } -void SyncManagerImpl::ShutdownOnSyncThread(ShutdownReason reason) { +void SyncManagerImpl::ShutdownOnSyncThread() { DCHECK(thread_checker_.CalledOnValidThread()); // Prevent any in-flight method calls from running. Also
diff --git a/components/sync/engine_impl/sync_manager_impl.h b/components/sync/engine_impl/sync_manager_impl.h index 20009384..4071fcb 100644 --- a/components/sync/engine_impl/sync_manager_impl.h +++ b/components/sync/engine_impl/sync_manager_impl.h
@@ -87,7 +87,7 @@ void RemoveObserver(SyncManager::Observer* observer) override; SyncStatus GetDetailedStatus() const override; void SaveChanges() override; - void ShutdownOnSyncThread(ShutdownReason reason) override; + void ShutdownOnSyncThread() override; UserShare* GetUserShare() override; ModelTypeConnector* GetModelTypeConnector() override; std::unique_ptr<ModelTypeConnector> GetModelTypeConnectorProxy() override;
diff --git a/components/sync/engine_impl/sync_manager_impl_unittest.cc b/components/sync/engine_impl/sync_manager_impl_unittest.cc index d9382d76..bb1ae7b 100644 --- a/components/sync/engine_impl/sync_manager_impl_unittest.cc +++ b/components/sync/engine_impl/sync_manager_impl_unittest.cc
@@ -994,7 +994,7 @@ void TearDown() override { sync_manager_.RemoveObserver(&manager_observer_); - sync_manager_.ShutdownOnSyncThread(STOP_SYNC); + sync_manager_.ShutdownOnSyncThread(); PumpLoop(); }
diff --git a/components/zucchini/fuzzers/BUILD.gn b/components/zucchini/fuzzers/BUILD.gn index 12964f365..e2720fc 100644 --- a/components/zucchini/fuzzers/BUILD.gn +++ b/components/zucchini/fuzzers/BUILD.gn
@@ -61,7 +61,11 @@ "--raw", "old_eventlog_provider.dll", # <old_file> "new_eventlog_provider.dll", # <new_file> - "eventlog_provider.patch", # <patch_file> (temporary) + + # <patch_file> (temporary) + rebase_path( + "$target_gen_dir/testdata/apply_fuzzer/eventlog_provider.patch", + root_build_dir), # <output_file> rebase_path( @@ -94,7 +98,10 @@ args = [ "old.ztf", # <old_file> "new.ztf", # <new_file> - "ztf.patch", # <patch_file> (temporary) + + # <patch_file> (temporary) + rebase_path("$target_gen_dir/testdata/apply_fuzzer/ztf.patch", + root_build_dir), # <output_file> rebase_path(
diff --git a/components/zucchini/fuzzers/disassembler_dex_fuzzer.cc b/components/zucchini/fuzzers/disassembler_dex_fuzzer.cc index 5968c98..ab08696d 100644 --- a/components/zucchini/fuzzers/disassembler_dex_fuzzer.cc +++ b/components/zucchini/fuzzers/disassembler_dex_fuzzer.cc
@@ -24,15 +24,16 @@ return 0; // Prepare data. std::vector<uint8_t> mutable_data(data, data + size); - zucchini::MutableBufferView mutable_image(mutable_data.data(), - mutable_data.size()); + zucchini::ConstBufferView image(mutable_data.data(), mutable_data.size()); // Create disassembler. Early exit on failure. auto disassembler_dex = - zucchini::Disassembler::Make<zucchini::DisassemblerDex>( - zucchini::ConstBufferView(mutable_image)); + zucchini::Disassembler::Make<zucchini::DisassemblerDex>(image); if (!disassembler_dex) return 0; + CHECK_LE(disassembler_dex->size(), image.size()); + zucchini::MutableBufferView mutable_image(mutable_data.data(), + disassembler_dex->size()); std::vector<zucchini::Reference> references; // Read all references in the file.
diff --git a/components/zucchini/fuzzers/generate_fuzzer_data.py b/components/zucchini/fuzzers/generate_fuzzer_data.py index 5a22109..5f5867b 100755 --- a/components/zucchini/fuzzers/generate_fuzzer_data.py +++ b/components/zucchini/fuzzers/generate_fuzzer_data.py
@@ -72,7 +72,7 @@ args = parse_args() return gen(os.path.join(ABS_TESTDATA_PATH, args.old_file), os.path.join(ABS_TESTDATA_PATH, args.new_file), - os.path.join(ABS_TESTDATA_PATH, args.patch_file), + os.path.abspath(args.patch_file), os.path.abspath(args.output_file), args.raw, platform.system() == 'Windows')
diff --git a/components/zucchini/integration_test.cc b/components/zucchini/integration_test.cc index e7df927..2d2e61f 100644 --- a/components/zucchini/integration_test.cc +++ b/components/zucchini/integration_test.cc
@@ -23,8 +23,7 @@ base::FilePath MakeTestPath(const std::string& filename) { base::FilePath path; DCHECK(base::PathService::Get(base::DIR_SOURCE_ROOT, &path)); - return path.AppendASCII("chrome") - .AppendASCII("installer") + return path.AppendASCII("components") .AppendASCII("zucchini") .AppendASCII("testdata") .AppendASCII(filename);
diff --git a/content/DEPS b/content/DEPS index 8973f765..6072b0b 100644 --- a/content/DEPS +++ b/content/DEPS
@@ -24,7 +24,6 @@ # settings, packaging details, installation or crash reporting. "+components/services/filesystem", - "+components/services/font", "+crypto", "+grit/blink_resources.h",
diff --git a/content/app/content_main_runner_impl.cc b/content/app/content_main_runner_impl.cc index 998a8a8..1fec0c7 100644 --- a/content/app/content_main_runner_impl.cc +++ b/content/app/content_main_runner_impl.cc
@@ -97,11 +97,13 @@ #if defined(OS_LINUX) #include "base/native_library.h" #include "base/rand_util.h" +#include "content/common/font_config_ipc_linux.h" #include "services/service_manager/zygote/common/common_sandbox_support_linux.h" #include "third_party/blink/public/platform/web_font_render_style.h" #include "third_party/boringssl/src/include/openssl/crypto.h" #include "third_party/boringssl/src/include/openssl/rand.h" #include "third_party/skia/include/core/SkFontMgr.h" +#include "third_party/skia/include/ports/SkFontConfigInterface.h" #include "third_party/skia/include/ports/SkFontMgr_android.h" #include "third_party/webrtc_overrides/init_webrtc.h" // nogncheck @@ -387,6 +389,9 @@ #endif InitializeWebRtcModule(); + SkFontConfigInterface::SetGlobal( + sk_make_sp<FontConfigIPC>(service_manager::GetSandboxFD())); + // Set the android SkFontMgr for blink. We need to ensure this is done // before the sandbox is initialized to allow the font manager to access // font configuration files on disk.
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 7c204dd..e15d26df 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -441,6 +441,8 @@ "background_fetch/storage/delete_registration_task.h", "background_fetch/storage/get_developer_ids_task.cc", "background_fetch/storage/get_developer_ids_task.h", + "background_fetch/storage/get_initialization_data_task.cc", + "background_fetch/storage/get_initialization_data_task.h", "background_fetch/storage/get_metadata_task.cc", "background_fetch/storage/get_metadata_task.h", "background_fetch/storage/get_num_requests_task.cc", @@ -1247,6 +1249,8 @@ "renderer_host/event_with_latency_info.h", "renderer_host/file_utilities_host_impl.cc", "renderer_host/file_utilities_host_impl.h", + "renderer_host/font_utils_linux.cc", + "renderer_host/font_utils_linux.h", "renderer_host/frame_connector_delegate.cc", "renderer_host/frame_connector_delegate.h", "renderer_host/frame_metadata_util.cc", @@ -2042,9 +2046,6 @@ if (use_pangocairo) { sources += [ "renderer_host/pepper/pepper_truetype_font_list_pango.cc" ] } - if (is_linux && !is_android) { - deps += [ "//components/services/font:ppapi_fontconfig_matching" ] - } } if (enable_library_cdms) {
diff --git a/content/browser/background_fetch/background_fetch_data_manager.cc b/content/browser/background_fetch/background_fetch_data_manager.cc index c406f65..f3c776a8 100644 --- a/content/browser/background_fetch/background_fetch_data_manager.cc +++ b/content/browser/background_fetch/background_fetch_data_manager.cc
@@ -100,6 +100,14 @@ DCHECK_CURRENTLY_ON(BrowserThread::IO); } +void BackgroundFetchDataManager::GetInitializationData( + GetInitializationDataCallback callback) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + AddDatabaseTask(std::make_unique<background_fetch::GetInitializationDataTask>( + this, std::move(callback))); +} + void BackgroundFetchDataManager::CreateRegistration( const BackgroundFetchRegistrationId& registration_id, const std::vector<ServiceWorkerFetchRequest>& requests,
diff --git a/content/browser/background_fetch/background_fetch_data_manager.h b/content/browser/background_fetch/background_fetch_data_manager.h index 04e01a4..fa55d36b 100644 --- a/content/browser/background_fetch/background_fetch_data_manager.h +++ b/content/browser/background_fetch/background_fetch_data_manager.h
@@ -21,6 +21,7 @@ #include "content/browser/background_fetch/background_fetch_registration_id.h" #include "content/browser/background_fetch/background_fetch_scheduler.h" #include "content/browser/background_fetch/storage/database_task.h" +#include "content/browser/background_fetch/storage/get_initialization_data_task.h" #include "content/browser/cache_storage/cache_storage_context_impl.h" #include "content/common/content_export.h" #include "third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom.h" @@ -54,6 +55,9 @@ : public BackgroundFetchScheduler::RequestProvider, public background_fetch::DatabaseTaskHost { public: + using GetInitializationDataCallback = base::OnceCallback<void( + blink::mojom::BackgroundFetchError, + std::vector<background_fetch::BackgroundFetchInitializationData>)>; using SettledFetchesCallback = base::OnceCallback<void( blink::mojom::BackgroundFetchError, bool /* background_fetch_succeeded */, @@ -80,6 +84,11 @@ // Grabs a reference to CacheStorageManager. virtual void InitializeOnIOThread(); + // Gets the required data to initialize BackgroundFetchContext with the + // appropriate JobControllers. This will be called when BackgroundFetchContext + // is being intialized on the IO thread. + void GetInitializationData(GetInitializationDataCallback callback); + // Creates and stores a new registration with the given properties. Will // invoke the |callback| when the registration has been created, which may // fail due to invalid input or storage errors.
diff --git a/content/browser/background_fetch/background_fetch_data_manager_unittest.cc b/content/browser/background_fetch/background_fetch_data_manager_unittest.cc index 5da9a74..f18a59e 100644 --- a/content/browser/background_fetch/background_fetch_data_manager_unittest.cc +++ b/content/browser/background_fetch/background_fetch_data_manager_unittest.cc
@@ -32,6 +32,7 @@ namespace content { namespace { +using background_fetch::BackgroundFetchInitializationData; using ::testing::UnorderedElementsAre; using ::testing::IsEmpty; @@ -47,6 +48,16 @@ constexpr size_t kResponseFileSize = 42u; +void DidGetInitializationData( + base::Closure quit_closure, + std::vector<BackgroundFetchInitializationData>* out_result, + blink::mojom::BackgroundFetchError error, + std::vector<BackgroundFetchInitializationData> result) { + DCHECK_EQ(error, blink::mojom::BackgroundFetchError::NONE); + *out_result = std::move(result); + std::move(quit_closure).Run(); +} + void DidCreateRegistration( base::Closure quit_closure, blink::mojom::BackgroundFetchError* out_error, @@ -151,6 +162,22 @@ background_fetch_data_manager_->InitializeOnIOThread(); } + // Synchronous version of BackgroundFetchDataManager::GetInitializationData(). + std::vector<BackgroundFetchInitializationData> GetInitializationData() { + // Simulate browser restart. This re-initializes |data_manager_|, since + // this DatabaseTask should only be called on browser startup. + RestartDataManagerFromPersistentStorage(); + + std::vector<BackgroundFetchInitializationData> result; + + base::RunLoop run_loop; + background_fetch_data_manager_->GetInitializationData(base::BindOnce( + &DidGetInitializationData, run_loop.QuitClosure(), &result)); + run_loop.Run(); + + return result; + } + // Synchronous version of BackgroundFetchDataManager::CreateRegistration(). void CreateRegistration( const BackgroundFetchRegistrationId& registration_id, @@ -1307,6 +1334,75 @@ GetRegistrationUserDataByKeyPrefix(sw_id, kUserDataPrefix).size()); } +TEST_F(BackgroundFetchDataManagerTest, GetInitializationData) { + { + // No registered ServiceWorkers. + std::vector<BackgroundFetchInitializationData> data = + GetInitializationData(); + EXPECT_TRUE(data.empty()); + } + + int64_t sw_id = RegisterServiceWorker(); + ASSERT_NE(blink::mojom::kInvalidServiceWorkerRegistrationId, sw_id); + { + // Register ServiceWorker with no Background Fetch Registrations. + std::vector<BackgroundFetchInitializationData> data = + GetInitializationData(); + EXPECT_TRUE(data.empty()); + } + + std::vector<ServiceWorkerFetchRequest> requests(2u); + BackgroundFetchOptions options; + blink::mojom::BackgroundFetchError error; + // Register a Background Fetch. + BackgroundFetchRegistrationId registration_id( + sw_id, origin(), kExampleDeveloperId, kExampleUniqueId); + + CreateRegistration(registration_id, requests, options, &error); + ASSERT_EQ(error, blink::mojom::BackgroundFetchError::NONE); + { + std::vector<BackgroundFetchInitializationData> data = + GetInitializationData(); + ASSERT_EQ(data.size(), 1u); + + EXPECT_EQ(data[0].registration_id, registration_id); + EXPECT_EQ(data[0].registration.unique_id, kExampleUniqueId); + EXPECT_EQ(data[0].registration.developer_id, kExampleDeveloperId); + EXPECT_EQ(data[0].num_requests, requests.size()); + EXPECT_EQ(data[0].num_completed_requests, 0u); + EXPECT_TRUE(data[0].active_fetch_guids.empty()); + } + + // Mark one request as complete and start another. + scoped_refptr<BackgroundFetchRequestInfo> request_info; + PopNextRequest(registration_id, &request_info); + ASSERT_TRUE(request_info); + AnnotateRequestInfoWithFakeDownloadManagerData(request_info.get()); + MarkRequestAsComplete(registration_id, request_info.get()); + PopNextRequest(registration_id, &request_info); + ASSERT_TRUE(request_info); + { + std::vector<BackgroundFetchInitializationData> data = + GetInitializationData(); + ASSERT_EQ(data.size(), 1u); + + EXPECT_EQ(data[0].num_requests, requests.size()); + EXPECT_EQ(data[0].num_completed_requests, 1u); + EXPECT_EQ(data[0].active_fetch_guids.size(), 1u); + } + + // Create another registration. + BackgroundFetchRegistrationId registration_id2( + sw_id, origin(), kAlternativeDeveloperId, kAlternativeUniqueId); + CreateRegistration(registration_id2, requests, options, &error); + EXPECT_EQ(error, blink::mojom::BackgroundFetchError::NONE); + { + std::vector<BackgroundFetchInitializationData> data = + GetInitializationData(); + ASSERT_EQ(data.size(), 2u); + } +} + TEST_F(BackgroundFetchDataManagerTest, CreateInParallel) { // Tests that multiple parallel calls to the BackgroundFetchDataManager are // linearized and handled one at a time, rather than producing inconsistent
diff --git a/content/browser/background_fetch/storage/database_task.cc b/content/browser/background_fetch/storage/database_task.cc index 04fbcf7..06582f8 100644 --- a/content/browser/background_fetch/storage/database_task.cc +++ b/content/browser/background_fetch/storage/database_task.cc
@@ -14,19 +14,29 @@ namespace background_fetch { +DatabaseTaskHost::DatabaseTaskHost() : weak_factory_(this) {} + +DatabaseTaskHost::~DatabaseTaskHost() = default; + +base::WeakPtr<DatabaseTaskHost> DatabaseTaskHost::GetWeakPtr() { + return weak_factory_.GetWeakPtr(); +} + DatabaseTask::DatabaseTask(DatabaseTaskHost* host) : host_(host) { DCHECK(host_); // Hold a reference to the CacheStorageManager. cache_manager_ = data_manager()->cache_manager(); } -DatabaseTask::~DatabaseTask() { - DCHECK(active_subtasks_.empty() || data_manager()->shutting_down_); -} +DatabaseTask::~DatabaseTask() = default; void DatabaseTask::Finished() { DCHECK_CURRENTLY_ON(BrowserThread::IO); - host_->OnTaskFinished(this); + // Post the OnTaskFinished callback to the same thread, to allow the the + // DatabaseTask to finish execution before deallocating it. + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(&DatabaseTaskHost::OnTaskFinished, + host_->GetWeakPtr(), this)); } void DatabaseTask::OnTaskFinished(DatabaseTask* finished_subtask) {
diff --git a/content/browser/background_fetch/storage/database_task.h b/content/browser/background_fetch/storage/database_task.h index c6f531f..177e977b 100644 --- a/content/browser/background_fetch/storage/database_task.h +++ b/content/browser/background_fetch/storage/database_task.h
@@ -38,7 +38,15 @@ public: virtual void OnTaskFinished(DatabaseTask* task) = 0; virtual BackgroundFetchDataManager* data_manager() = 0; - virtual ~DatabaseTaskHost() = default; + virtual ~DatabaseTaskHost(); + + base::WeakPtr<DatabaseTaskHost> GetWeakPtr(); + + protected: + DatabaseTaskHost(); + + private: + base::WeakPtrFactory<DatabaseTaskHost> weak_factory_; }; // A DatabaseTask is an asynchronous "transaction" that needs to read/write the
diff --git a/content/browser/background_fetch/storage/get_initialization_data_task.cc b/content/browser/background_fetch/storage/get_initialization_data_task.cc new file mode 100644 index 0000000..40f8c65c --- /dev/null +++ b/content/browser/background_fetch/storage/get_initialization_data_task.cc
@@ -0,0 +1,356 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/background_fetch/storage/get_initialization_data_task.h" + +#include "base/barrier_closure.h" +#include "content/browser/background_fetch/background_fetch.pb.h" +#include "content/browser/background_fetch/storage/database_helpers.h" +#include "content/browser/service_worker/service_worker_context_wrapper.h" +#include "url/origin.h" + +namespace content { + +namespace background_fetch { + +namespace { + +// Base class with all the common implementation for the SubTasks +// needed in this file. +class InitializationSubTask : public DatabaseTask { + public: + // Holds data used by all SubTasks. + struct SubTaskInit { + SubTaskInit() = delete; + ~SubTaskInit() = default; + + // Service Worker Database metadata. + int64_t service_worker_registration_id; + std::string unique_id; + + // The results to report. + BackgroundFetchInitializationData* initialization_data; + blink::mojom::BackgroundFetchError* error; + }; + + InitializationSubTask(DatabaseTaskHost* host, + const SubTaskInit& sub_task_init, + base::OnceClosure done_closure) + : DatabaseTask(host), + sub_task_init_(sub_task_init), + done_closure_(std::move(done_closure)) { + DCHECK(sub_task_init_.initialization_data); + DCHECK(sub_task_init_.error); + } + + ~InitializationSubTask() override = default; + + protected: + void FinishTask() { + std::move(done_closure_).Run(); + Finished(); // Destroys |this|. + } + + SubTaskInit& sub_task_init() { return sub_task_init_; } + + private: + SubTaskInit sub_task_init_; + base::OnceClosure done_closure_; + + DISALLOW_COPY_AND_ASSIGN(InitializationSubTask); +}; + +// Fills the BackgroundFetchInitializationData with the number of completed +// requests. +class GetCompletedRequestsTask : public InitializationSubTask { + public: + GetCompletedRequestsTask(DatabaseTaskHost* host, + const SubTaskInit& sub_task_init, + base::OnceClosure done_closure) + : InitializationSubTask(host, sub_task_init, std::move(done_closure)), + weak_factory_(this) {} + + ~GetCompletedRequestsTask() override = default; + + void Start() override { + service_worker_context()->GetRegistrationUserDataByKeyPrefix( + sub_task_init().service_worker_registration_id, + {CompletedRequestKeyPrefix(sub_task_init().unique_id)}, + base::BindOnce(&GetCompletedRequestsTask::DidGetCompletedRequests, + weak_factory_.GetWeakPtr())); + } + + private: + void DidGetCompletedRequests(const std::vector<std::string>& data, + blink::ServiceWorkerStatusCode status) { + switch (ToDatabaseStatus(status)) { + case DatabaseStatus::kFailed: + *sub_task_init().error = + blink::mojom::BackgroundFetchError::STORAGE_ERROR; + FinishTask(); + return; + case DatabaseStatus::kNotFound: + case DatabaseStatus::kOk: + break; + } + + sub_task_init().initialization_data->num_completed_requests = data.size(); + FinishTask(); + } + + base::WeakPtrFactory<GetCompletedRequestsTask> + weak_factory_; // Keep as last. +}; + +// Fills the BackgroundFetchInitializationData with the guids of active +// (previously started) requests. +class GetActiveRequestsTask : public InitializationSubTask { + public: + GetActiveRequestsTask(DatabaseTaskHost* host, + const SubTaskInit& sub_task_init, + base::OnceClosure done_closure) + : InitializationSubTask(host, sub_task_init, std::move(done_closure)), + weak_factory_(this) {} + + ~GetActiveRequestsTask() override = default; + + void Start() override { + service_worker_context()->GetRegistrationUserDataByKeyPrefix( + sub_task_init().service_worker_registration_id, + {ActiveRequestKeyPrefix(sub_task_init().unique_id)}, + base::BindOnce(&GetActiveRequestsTask::DidGetActiveRequests, + weak_factory_.GetWeakPtr())); + } + + private: + void DidGetActiveRequests(const std::vector<std::string>& data, + blink::ServiceWorkerStatusCode status) { + switch (ToDatabaseStatus(status)) { + case DatabaseStatus::kFailed: + *sub_task_init().error = + blink::mojom::BackgroundFetchError::STORAGE_ERROR; + FinishTask(); + return; + case DatabaseStatus::kNotFound: + case DatabaseStatus::kOk: + break; + } + + for (const std::string& serialized_active_request : data) { + proto::BackgroundFetchActiveRequest active_request; + if (!active_request.ParseFromString(serialized_active_request)) { + *sub_task_init().error = + blink::mojom::BackgroundFetchError::STORAGE_ERROR; + continue; + } + DCHECK_EQ(sub_task_init().unique_id, active_request.unique_id()); + sub_task_init().initialization_data->active_fetch_guids.push_back( + active_request.download_guid()); + } + + FinishTask(); + } + + base::WeakPtrFactory<GetActiveRequestsTask> weak_factory_; // Keep as last. + + DISALLOW_COPY_AND_ASSIGN(GetActiveRequestsTask); +}; + +// Fills the BackgroundFetchInitializationData with all the relevant information +// stored in the BackgroundFetchMetadata proto. +class FillFromMetadataTask : public InitializationSubTask { + public: + FillFromMetadataTask(DatabaseTaskHost* host, + const SubTaskInit& sub_task_init, + base::OnceClosure done_closure) + : InitializationSubTask(host, sub_task_init, std::move(done_closure)), + weak_factory_(this) {} + + ~FillFromMetadataTask() override = default; + + void Start() override { + service_worker_context()->GetRegistrationUserDataByKeyPrefix( + sub_task_init().service_worker_registration_id, + {RegistrationKey(sub_task_init().unique_id)}, + base::BindOnce(&FillFromMetadataTask::DidGetMetadata, + weak_factory_.GetWeakPtr())); + } + + private: + void DidGetMetadata(const std::vector<std::string>& data, + blink::ServiceWorkerStatusCode status) { + switch (ToDatabaseStatus(status)) { + case DatabaseStatus::kFailed: + case DatabaseStatus::kNotFound: + *sub_task_init().error = + blink::mojom::BackgroundFetchError::STORAGE_ERROR; + FinishTask(); + return; + case DatabaseStatus::kOk: + break; + } + + if (data.size() != 1u) { + *sub_task_init().error = + blink::mojom::BackgroundFetchError::STORAGE_ERROR; + FinishTask(); + return; + } + + proto::BackgroundFetchMetadata metadata; + if (!metadata.ParseFromString(data[0])) { + *sub_task_init().error = + blink::mojom::BackgroundFetchError::STORAGE_ERROR; + FinishTask(); + return; + } + + if (sub_task_init().unique_id != metadata.registration().unique_id()) { + *sub_task_init().error = + blink::mojom::BackgroundFetchError::STORAGE_ERROR; + FinishTask(); + return; + } + + // Fill BackgroundFetchRegistrationId. + sub_task_init().initialization_data->registration_id = + BackgroundFetchRegistrationId( + sub_task_init().service_worker_registration_id, + url::Origin::Create(GURL(metadata.origin())), + metadata.registration().developer_id(), + metadata.registration().unique_id()); + + // Fill BackgroundFetchRegistration. + auto& registration = sub_task_init().initialization_data->registration; + // TODO(crbug.com/853874): Unify conversion logic. + registration.developer_id = metadata.registration().developer_id(); + registration.unique_id = metadata.registration().unique_id(); + registration.upload_total = metadata.registration().upload_total(); + registration.uploaded = metadata.registration().uploaded(); + registration.download_total = metadata.registration().download_total(); + registration.downloaded = metadata.registration().downloaded(); + + // Total number of requests. + sub_task_init().initialization_data->num_requests = metadata.num_fetches(); + + // TODO(rayankans): Fill BackgroundFetchOptions and the icon after it is + // persisted. + FinishTask(); + } + + base::WeakPtrFactory<FillFromMetadataTask> weak_factory_; // Keep as last. + + DISALLOW_COPY_AND_ASSIGN(FillFromMetadataTask); +}; + +// Asynchronously calls the SubTasks required to collect all the information for +// the BackgroundFetchInitializationData. +class FillBackgroundFetchInitializationDataTask : public InitializationSubTask { + public: + FillBackgroundFetchInitializationDataTask(DatabaseTaskHost* host, + const SubTaskInit& sub_task_init, + base::OnceClosure done_closure) + : InitializationSubTask(host, sub_task_init, std::move(done_closure)), + weak_factory_(this) {} + + ~FillBackgroundFetchInitializationDataTask() override = default; + + void Start() override { + // We need 3 queries to get the initialization data. These are wrapped + // in a BarrierClosure to avoid querying them serially. + // 1. Metadata + // 2. Active Requests + // 3. Completed Requests + // TODO(rayankans): 4. UI Title + base::RepeatingClosure barrier_closure = base::BarrierClosure( + 3u, + base::BindOnce(&FillBackgroundFetchInitializationDataTask::FinishTask, + weak_factory_.GetWeakPtr())); + AddSubTask(std::make_unique<FillFromMetadataTask>(this, sub_task_init(), + barrier_closure)); + AddSubTask(std::make_unique<GetCompletedRequestsTask>(this, sub_task_init(), + barrier_closure)); + AddSubTask(std::make_unique<GetActiveRequestsTask>(this, sub_task_init(), + barrier_closure)); + } + + private: + base::WeakPtrFactory<FillBackgroundFetchInitializationDataTask> + weak_factory_; // Keep as last. + + DISALLOW_COPY_AND_ASSIGN(FillBackgroundFetchInitializationDataTask); +}; + +} // namespace + +BackgroundFetchInitializationData::BackgroundFetchInitializationData() = + default; + +BackgroundFetchInitializationData::BackgroundFetchInitializationData( + BackgroundFetchInitializationData&&) = default; + +BackgroundFetchInitializationData::~BackgroundFetchInitializationData() = + default; + +GetInitializationDataTask::GetInitializationDataTask( + DatabaseTaskHost* host, + GetInitializationDataCallback callback) + : DatabaseTask(host), callback_(std::move(callback)), weak_factory_(this) {} + +GetInitializationDataTask::~GetInitializationDataTask() = default; + +void GetInitializationDataTask::Start() { + service_worker_context()->GetUserDataForAllRegistrationsByKeyPrefix( + kActiveRegistrationUniqueIdKeyPrefix, + base::BindOnce(&GetInitializationDataTask::DidGetRegistrations, + weak_factory_.GetWeakPtr())); +} + +void GetInitializationDataTask::DidGetRegistrations( + const std::vector<std::pair<int64_t, std::string>>& user_data, + blink::ServiceWorkerStatusCode status) { + switch (ToDatabaseStatus(status)) { + case DatabaseStatus::kFailed: + error_ = blink::mojom::BackgroundFetchError::STORAGE_ERROR; + FinishTask(); + return; + case DatabaseStatus::kNotFound: + case DatabaseStatus::kOk: + break; + } + + if (user_data.empty()) { + FinishTask(); + return; + } + + base::RepeatingClosure barrier_closure = base::BarrierClosure( + user_data.size(), base::BindOnce(&GetInitializationDataTask::FinishTask, + weak_factory_.GetWeakPtr())); + for (const auto& ud : user_data) { + auto insertion_result = initialization_data_map_.emplace( + ud.second, BackgroundFetchInitializationData()); + DCHECK(insertion_result.second); // Check unique_id is in fact unique. + + AddSubTask(std::make_unique<FillBackgroundFetchInitializationDataTask>( + this, + InitializationSubTask::SubTaskInit{ + ud.first, ud.second, + &insertion_result.first->second /* initialization_data */, &error_}, + barrier_closure)); + } +} +void GetInitializationDataTask::FinishTask() { + std::vector<BackgroundFetchInitializationData> results; + results.reserve(initialization_data_map_.size()); + for (auto& id : initialization_data_map_) + results.emplace_back(std::move(id.second)); + + std::move(callback_).Run(error_, std::move(results)); + Finished(); // Destroys |this|. +} + +} // namespace background_fetch + +} // namespace content
diff --git a/content/browser/background_fetch/storage/get_initialization_data_task.h b/content/browser/background_fetch/storage/get_initialization_data_task.h new file mode 100644 index 0000000..42c722e --- /dev/null +++ b/content/browser/background_fetch/storage/get_initialization_data_task.h
@@ -0,0 +1,99 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_BACKGROUND_FETCH_STORAGE_GET_INITIALIZATION_DATA_TASK_H_ +#define CONTENT_BROWSER_BACKGROUND_FETCH_STORAGE_GET_INITIALIZATION_DATA_TASK_H_ + +#include <map> +#include <string> +#include <vector> + +#include "base/callback.h" +#include "content/browser/background_fetch/background_fetch_registration_id.h" +#include "content/browser/background_fetch/storage/database_task.h" +#include "content/browser/service_worker/service_worker_info.h" +#include "content/common/background_fetch/background_fetch_types.h" +#include "content/common/content_export.h" +#include "third_party/blink/public/common/service_worker/service_worker_status_code.h" +#include "third_party/blink/public/platform/modules/background_fetch/background_fetch.mojom.h" +#include "third_party/skia/include/core/SkBitmap.h" + +namespace content { + +namespace background_fetch { + +// All the information needed to create a JobController and resume the fetch +// after start-up. +struct CONTENT_EXPORT BackgroundFetchInitializationData { + BackgroundFetchInitializationData(); + BackgroundFetchInitializationData(BackgroundFetchInitializationData&&); + ~BackgroundFetchInitializationData(); + + BackgroundFetchRegistrationId registration_id; + BackgroundFetchOptions options; + SkBitmap icon; + BackgroundFetchRegistration registration; + size_t num_requests; + size_t num_completed_requests; + std::vector<std::string> active_fetch_guids; + + DISALLOW_COPY_AND_ASSIGN(BackgroundFetchInitializationData); +}; + +using GetInitializationDataCallback = + base::OnceCallback<void(blink::mojom::BackgroundFetchError, + std::vector<BackgroundFetchInitializationData>)>; + +// Gets all the data needed to resume fetches. The task starts by getting +// all the <ServiceWorker Registration ID, Background Fetch Unique ID> +// pairs available. +// * TODO(crbug.com/853060): Consider persisting which SWIDs contain BGF +// info. +// Then for every Background Fetch Unique ID the required information is +// queried from the ServiceWorker Database to fill an instance of +// BackgroundFetchInitializationData. +// +// Note: All of this must run in one DatabaseTask, to ensure the +// BackgroundFetchContext is properly initialized with JobControllers before +// running any additional DatabaseTasks and reaching an incorrect state. +class GetInitializationDataTask : public DatabaseTask { + public: + using InitializationDataMap = + std::map<std::string, BackgroundFetchInitializationData>; + + GetInitializationDataTask(DatabaseTaskHost* host, + GetInitializationDataCallback callback); + + ~GetInitializationDataTask() override; + + // DatabaseTask implementation: + void Start() override; + + private: + void DidGetRegistrations( + const std::vector<std::pair<int64_t, std::string>>& user_data, + blink::ServiceWorkerStatusCode status); + + void FinishTask(); + + GetInitializationDataCallback callback_; + + // Map from the unique_id to the initialization data. + InitializationDataMap initialization_data_map_; + + // The error to report with |callback_|. + blink::mojom::BackgroundFetchError error_ = + blink::mojom::BackgroundFetchError::NONE; + + base::WeakPtrFactory<GetInitializationDataTask> + weak_factory_; // Keep as last. + + DISALLOW_COPY_AND_ASSIGN(GetInitializationDataTask); +}; + +} // namespace background_fetch + +} // namespace content + +#endif // CONTENT_BROWSER_BACKGROUND_FETCH_STORAGE_GET_INITIALIZATION_DATA_TASK_H_
diff --git a/content/browser/background_fetch/storage/get_settled_fetches_task.cc b/content/browser/background_fetch/storage/get_settled_fetches_task.cc index c05871e..99a4c94e 100644 --- a/content/browser/background_fetch/storage/get_settled_fetches_task.cc +++ b/content/browser/background_fetch/storage/get_settled_fetches_task.cc
@@ -102,7 +102,7 @@ } base::RepeatingClosure barrier_closure = base::BarrierClosure( - completed_requests_.size() + /* finalizer */ 1, + completed_requests_.size(), base::BindOnce(&GetSettledFetchesTask::FinishTaskWithErrorCode, weak_factory_.GetWeakPtr(), blink::mojom::BackgroundFetchError::NONE)); @@ -115,14 +115,6 @@ completed_request.serialized_request())); FillResponse(&settled_fetches_.back(), barrier_closure); } - - // The callback within |barrier_closure| eventually calls Finished(), which - // will destroy |this|. If the callback runs within the loop, the task might - // crash since |completed_requests_| will be destroyed, and the for loop - // condition statement will access deleted memory. This is why 1 was added to - // the |barrier_closure| closure number, so that it can be explicitly called - // outside the loop. - barrier_closure.Run(); } void GetSettledFetchesTask::FillResponse(
diff --git a/content/browser/linux_ipc_browsertest.cc b/content/browser/linux_ipc_browsertest.cc new file mode 100644 index 0000000..7be0589 --- /dev/null +++ b/content/browser/linux_ipc_browsertest.cc
@@ -0,0 +1,91 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <map> +#include <set> +#include <string> + +#include "base/command_line.h" +#include "base/macros.h" +#include "base/synchronization/lock.h" +#include "content/browser/sandbox_ipc_linux.h" +#include "content/public/common/content_switches.h" +#include "content/public/test/content_browser_test.h" +#include "content/public/test/content_browser_test_utils.h" +#include "services/service_manager/sandbox/switches.h" +#include "testing/gmock/include/gmock/gmock-matchers.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace content { + +class LinuxIPCBrowserTest : public ContentBrowserTest, + public SandboxIPCHandler::TestObserver, + public testing::WithParamInterface<std::string> { + public: + LinuxIPCBrowserTest() { + SandboxIPCHandler::SetObserverForTests(this); + } + ~LinuxIPCBrowserTest() override {} + + protected: + void SetUpCommandLine(base::CommandLine* command_line) override { + ContentBrowserTest::SetUpCommandLine(command_line); + if (GetParam() == "no-zygote") { + command_line->AppendSwitch(service_manager::switches::kNoSandbox); + command_line->AppendSwitch(switches::kNoZygote); + } + } + + void OnFontOpen(int id) override { + base::AutoLock lock(lock_); + opened_fonts_.insert(font_names_[id]); + } + + void OnGetFallbackFontForChar(UChar32 c, std::string name, int id) override { + base::AutoLock lock(lock_); + fallback_fonts_[c] = name; + font_names_[id] = name; + } + + std::string FallbackFontName(UChar32 c) { + base::AutoLock lock(lock_); + return fallback_fonts_[c]; + } + + std::set<std::string> OpenedFonts() { + base::AutoLock lock(lock_); + return opened_fonts_; + } + + // These variables are accessed on the IPC thread and the test thread. + // All accesses on the IPC thread should be before the renderer process + // completes navigation, and all accesses on the test thread should be after. + // However we still need a mutex for the accesses to be sequenced according to + // the C++ memory model. + base::Lock lock_; + std::map<UChar32, std::string> fallback_fonts_; + std::map<int, std::string> font_names_; + std::set<std::string> opened_fonts_; + + DISALLOW_COPY_AND_ASSIGN(LinuxIPCBrowserTest); +}; + +// Tests that Linux IPC font fallback code runs round-trip when Zygote is +// disabled. It doesn't care what font is chosen, just that the IPC messages are +// flowing. This test assumes that U+65E5 (CJK "Sun" character) will trigger the +// font fallback codepath. +IN_PROC_BROWSER_TEST_P(LinuxIPCBrowserTest, FontFallbackIPCWorks) { + GURL test_url = GetTestUrl("font", "font_fallback.html"); + EXPECT_TRUE(NavigateToURL(shell(), test_url)); + EXPECT_THAT(FallbackFontName(U'\U000065E5'), testing::Ne("")); + EXPECT_THAT(OpenedFonts(), + testing::Contains(FallbackFontName(U'\U000065E5'))); +} + +INSTANTIATE_TEST_CASE_P(LinuxIPCBrowserTest, + LinuxIPCBrowserTest, + ::testing::Values("zygote", "no-zygote")); + +} // namespace
diff --git a/content/browser/notifications/blink_notification_service_impl.cc b/content/browser/notifications/blink_notification_service_impl.cc index cd8c01b..f9711053 100644 --- a/content/browser/notifications/blink_notification_service_impl.cc +++ b/content/browser/notifications/blink_notification_service_impl.cc
@@ -28,7 +28,7 @@ namespace { // Returns the implementation of the PlatformNotificationService. May be NULL. -PlatformNotificationService* Service() { +PlatformNotificationService* GetNotificationService() { return GetContentClient()->browser()->GetPlatformNotificationService(); } @@ -63,7 +63,7 @@ void BlinkNotificationServiceImpl::GetPermissionStatus( GetPermissionStatusCallback callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (!Service()) { + if (!GetNotificationService()) { std::move(callback).Run(blink::mojom::PermissionStatus::DENIED); return; } @@ -83,7 +83,7 @@ const NotificationResources& notification_resources, blink::mojom::NonPersistentNotificationListenerPtr event_listener_ptr) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (!Service()) + if (!GetNotificationService()) return; if (CheckPermissionStatus() != blink::mojom::PermissionStatus::GRANTED) @@ -98,15 +98,15 @@ event_dispatcher->RegisterNonPersistentNotificationListener( notification_id, std::move(event_listener_ptr)); - Service()->DisplayNotification(browser_context_, notification_id, - origin_.GetURL(), platform_notification_data, - notification_resources); + GetNotificationService()->DisplayNotification( + browser_context_, notification_id, origin_.GetURL(), + platform_notification_data, notification_resources); } void BlinkNotificationServiceImpl::CloseNonPersistentNotification( const std::string& token) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (!Service()) + if (!GetNotificationService()) return; if (CheckPermissionStatus() != blink::mojom::PermissionStatus::GRANTED) @@ -116,7 +116,8 @@ notification_context_->notification_id_generator() ->GenerateForNonPersistentNotification(origin_, token); - Service()->CloseNotification(browser_context_, notification_id); + GetNotificationService()->CloseNotification(browser_context_, + notification_id); // TODO(https://crbug.com/442141): Pass a callback here to focus the tab // which created the notification, unless the event is canceled. @@ -140,7 +141,7 @@ const NotificationResources& notification_resources, DisplayPersistentNotificationCallback callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (!Service()) { + if (!GetNotificationService()) { std::move(callback).Run(PersistentNotificationError::INTERNAL_ERROR); return; } @@ -230,8 +231,8 @@ BrowserThread::UI, FROM_HERE, base::BindOnce( &PlatformNotificationService::DisplayPersistentNotification, - base::Unretained(Service()), browser_context_, notification_id, - registration->pattern(), origin_.GetURL(), + base::Unretained(GetNotificationService()), browser_context_, + notification_id, registration->pattern(), origin_.GetURL(), platform_notification_data, notification_resources)); error = PersistentNotificationError::NONE; @@ -244,13 +245,14 @@ void BlinkNotificationServiceImpl::ClosePersistentNotification( const std::string& notification_id) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (!Service()) + if (!GetNotificationService()) return; if (CheckPermissionStatus() != blink::mojom::PermissionStatus::GRANTED) return; - Service()->ClosePersistentNotification(browser_context_, notification_id); + GetNotificationService()->ClosePersistentNotification(browser_context_, + notification_id); // Deleting the data associated with |notification_id| from the notification // database has to be done on the IO thread, but there's no reason to postpone @@ -267,7 +269,7 @@ const std::string& filter_tag, GetNotificationsCallback callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (!Service() || + if (!GetNotificationService() || CheckPermissionStatus() != blink::mojom::PermissionStatus::GRANTED) { // No permission has been granted for the given origin. It is harmless to // try to get notifications without permission, so return empty vectors
diff --git a/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc b/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc index 4729a7b..4a9bd2b 100644 --- a/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc +++ b/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc
@@ -131,8 +131,10 @@ } bool PictureInPictureWindowControllerImpl::IsPlayerActive() { - if (!media_player_id_.has_value()) - media_web_contents_observer_->GetPictureInPictureVideoMediaPlayerId(); + if (!media_player_id_.has_value()) { + media_player_id_ = + media_web_contents_observer_->GetPictureInPictureVideoMediaPlayerId(); + } return media_player_id_.has_value() && media_web_contents_observer_->IsPlayerActive(*media_player_id_);
diff --git a/content/browser/renderer_host/font_utils_linux.cc b/content/browser/renderer_host/font_utils_linux.cc new file mode 100644 index 0000000..e5fd81a --- /dev/null +++ b/content/browser/renderer_host/font_utils_linux.cc
@@ -0,0 +1,265 @@ +// 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 <fcntl.h> +#include <fontconfig/fontconfig.h> +#include <stddef.h> +#include <string.h> +#include <sys/stat.h> +#include <sys/types.h> + +#include <string> + +#include "base/posix/eintr_wrapper.h" + +// TODO(crbug/685022): Guard the inclusion of ppapi headers with +// BUILDFLAG(ENABLE_PLUGINS). +#include "ppapi/c/private/pp_private_font_charset.h" // nogncheck +#include "ppapi/c/trusted/ppb_browser_font_trusted.h" // nogncheck + +namespace { + +// MSCharSetToFontconfig translates a Microsoft charset identifier to a +// fontconfig language set by appending to |langset|. +// Returns true if |langset| is Latin/Greek/Cyrillic. +bool MSCharSetToFontconfig(FcLangSet* langset, unsigned fdwCharSet) { + // We have need to translate raw fdwCharSet values into terms that + // fontconfig can understand. (See the description of fdwCharSet in the MSDN + // documentation for CreateFont: + // http://msdn.microsoft.com/en-us/library/dd183499(VS.85).aspx ) + // + // Although the argument is /called/ 'charset', the actual values conflate + // character sets (which are sets of Unicode code points) and character + // encodings (which are algorithms for turning a series of bits into a + // series of code points.) Sometimes the values will name a language, + // sometimes they'll name an encoding. In the latter case I'm assuming that + // they mean the set of code points in the domain of that encoding. + // + // fontconfig deals with ISO 639-1 language codes: + // http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes + // + // So, for each of the documented fdwCharSet values I've had to take a + // guess at the set of ISO 639-1 languages intended. + + bool is_lgc = false; + switch (fdwCharSet) { + case PP_PRIVATEFONTCHARSET_ANSI: + // These values I don't really know what to do with, so I'm going to map + // them to English also. + case PP_PRIVATEFONTCHARSET_DEFAULT: + case PP_PRIVATEFONTCHARSET_MAC: + case PP_PRIVATEFONTCHARSET_OEM: + case PP_PRIVATEFONTCHARSET_SYMBOL: + is_lgc = true; + FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("en")); + break; + case PP_PRIVATEFONTCHARSET_BALTIC: + // The three baltic languages. + is_lgc = true; + FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("et")); + FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("lv")); + FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("lt")); + break; + case PP_PRIVATEFONTCHARSET_CHINESEBIG5: + FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("zh-tw")); + break; + case PP_PRIVATEFONTCHARSET_GB2312: + FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("zh-cn")); + break; + case PP_PRIVATEFONTCHARSET_EASTEUROPE: + // A scattering of eastern European languages. + is_lgc = true; + FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("pl")); + FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("cs")); + FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("sk")); + FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("hu")); + FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("hr")); + break; + case PP_PRIVATEFONTCHARSET_GREEK: + is_lgc = true; + FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("el")); + break; + case PP_PRIVATEFONTCHARSET_HANGUL: + case PP_PRIVATEFONTCHARSET_JOHAB: + // Korean + FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("ko")); + break; + case PP_PRIVATEFONTCHARSET_RUSSIAN: + is_lgc = true; + FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("ru")); + break; + case PP_PRIVATEFONTCHARSET_SHIFTJIS: + // Japanese + FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("ja")); + break; + case PP_PRIVATEFONTCHARSET_TURKISH: + is_lgc = true; + FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("tr")); + break; + case PP_PRIVATEFONTCHARSET_VIETNAMESE: + is_lgc = true; + FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("vi")); + break; + case PP_PRIVATEFONTCHARSET_ARABIC: + FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("ar")); + break; + case PP_PRIVATEFONTCHARSET_HEBREW: + FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("he")); + break; + case PP_PRIVATEFONTCHARSET_THAI: + FcLangSetAdd(langset, reinterpret_cast<const FcChar8*>("th")); + break; + // default: + // Don't add any languages in that case that we don't recognise the + // constant. + } + return is_lgc; +} + +} // namespace + +namespace content { + +int MatchFontFaceWithFallback(const std::string& face, + bool is_bold, + bool is_italic, + uint32_t charset, + uint32_t fallback_family) { + FcLangSet* langset = FcLangSetCreate(); + bool is_lgc = MSCharSetToFontconfig(langset, charset); + FcPattern* pattern = FcPatternCreate(); + FcPatternAddString( + pattern, FC_FAMILY, reinterpret_cast<const FcChar8*>(face.c_str())); + + // TODO(thestig) Check if we can access Chrome's per-script font preference + // here and select better default fonts for non-LGC case. + std::string generic_font_name; + if (is_lgc) { + switch (fallback_family) { + case PP_BROWSERFONT_TRUSTED_FAMILY_SERIF: + generic_font_name = "Times New Roman"; + break; + case PP_BROWSERFONT_TRUSTED_FAMILY_SANSSERIF: + generic_font_name = "Arial"; + break; + case PP_BROWSERFONT_TRUSTED_FAMILY_MONOSPACE: + generic_font_name = "Courier New"; + break; + } + } + if (!generic_font_name.empty()) { + const FcChar8* fc_generic_font_name = + reinterpret_cast<const FcChar8*>(generic_font_name.c_str()); + FcPatternAddString(pattern, FC_FAMILY, fc_generic_font_name); + } + + if (is_bold) + FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD); + if (is_italic) + FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC); + FcPatternAddLangSet(pattern, FC_LANG, langset); + FcPatternAddBool(pattern, FC_SCALABLE, FcTrue); + FcConfigSubstitute(nullptr, pattern, FcMatchPattern); + FcDefaultSubstitute(pattern); + + FcResult result; + FcFontSet* font_set = FcFontSort(nullptr, pattern, 0, nullptr, &result); + int font_fd = -1; + int good_enough_index = -1; + bool good_enough_index_set = false; + + if (font_set) { + for (int i = 0; i < font_set->nfont; ++i) { + FcPattern* current = font_set->fonts[i]; + + // Older versions of fontconfig have a bug where they cannot select + // only scalable fonts so we have to manually filter the results. + FcBool is_scalable; + if (FcPatternGetBool(current, FC_SCALABLE, 0, &is_scalable) != + FcResultMatch || + !is_scalable) { + continue; + } + + FcChar8* c_filename; + if (FcPatternGetString(current, FC_FILE, 0, &c_filename) != + FcResultMatch) { + continue; + } + + // We only want to return sfnt (TrueType) based fonts. We don't have a + // very good way of detecting this so we'll filter based on the + // filename. + bool is_sfnt = false; + static const char kSFNTExtensions[][5] = {".ttf", ".otc", ".TTF", ".ttc", + ""}; + const size_t filename_len = strlen(reinterpret_cast<char*>(c_filename)); + for (unsigned j = 0;; j++) { + if (kSFNTExtensions[j][0] == 0) { + // None of the extensions matched. + break; + } + const size_t ext_len = strlen(kSFNTExtensions[j]); + if (filename_len > ext_len && + memcmp(c_filename + filename_len - ext_len, + kSFNTExtensions[j], + ext_len) == 0) { + is_sfnt = true; + break; + } + } + + if (!is_sfnt) + continue; + + // This font is good enough to pass muster, but we might be able to do + // better with subsequent ones. + if (!good_enough_index_set) { + good_enough_index = i; + good_enough_index_set = true; + } + + FcValue matrix; + bool have_matrix = FcPatternGet(current, FC_MATRIX, 0, &matrix) == 0; + + if (is_italic && have_matrix) { + // we asked for an italic font, but fontconfig is giving us a + // non-italic font with a transformation matrix. + continue; + } + + FcValue embolden; + const bool have_embolden = + FcPatternGet(current, FC_EMBOLDEN, 0, &embolden) == 0; + + if (is_bold && have_embolden) { + // we asked for a bold font, but fontconfig gave us a non-bold font + // and asked us to apply fake bolding. + continue; + } + + font_fd = + HANDLE_EINTR(open(reinterpret_cast<char*>(c_filename), O_RDONLY)); + if (font_fd >= 0) + break; + } + } + + if (font_fd == -1 && good_enough_index_set) { + // We didn't find a font that we liked, so we fallback to something + // acceptable. + FcPattern* current = font_set->fonts[good_enough_index]; + FcChar8* c_filename; + FcPatternGetString(current, FC_FILE, 0, &c_filename); + font_fd = HANDLE_EINTR(open(reinterpret_cast<char*>(c_filename), O_RDONLY)); + } + + if (font_set) + FcFontSetDestroy(font_set); + FcPatternDestroy(pattern); + + return font_fd; +} + +} // namespace content
diff --git a/content/browser/renderer_host/font_utils_linux.h b/content/browser/renderer_host/font_utils_linux.h new file mode 100644 index 0000000..33b31af6 --- /dev/null +++ b/content/browser/renderer_host/font_utils_linux.h
@@ -0,0 +1,22 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_RENDERER_HOST_FONT_UTILS_LINUX_H_ +#define CONTENT_BROWSER_RENDERER_HOST_FONT_UTILS_LINUX_H_ + +#include <stdint.h> + +#include <string> + +namespace content { + +int MatchFontFaceWithFallback(const std::string& face, + bool is_bold, + bool is_italic, + uint32_t charset, + uint32_t fallback_family); + +} // namespace content + +#endif // CONTENT_BROWSER_RENDERER_HOST_FONT_UTILS_LINUX_H_
diff --git a/content/browser/renderer_host/pepper/pepper_truetype_font_linux.cc b/content/browser/renderer_host/pepper/pepper_truetype_font_linux.cc index c71954e..c9a8d3f 100644 --- a/content/browser/renderer_host/pepper/pepper_truetype_font_linux.cc +++ b/content/browser/renderer_host/pepper/pepper_truetype_font_linux.cc
@@ -14,10 +14,8 @@ #include "base/macros.h" #include "base/numerics/safe_conversions.h" #include "base/sys_byteorder.h" -#include "build/build_config.h" -#include "components/services/font/ppapi_fontconfig_matching.h" +#include "content/browser/renderer_host/font_utils_linux.h" #include "content/public/common/common_sandbox_support_linux.h" -#include "ppapi/buildflags/buildflags.h" #include "ppapi/c/dev/ppb_truetype_font_dev.h" #include "ppapi/c/pp_errors.h" #include "ppapi/c/trusted/ppb_browser_font_trusted.h" @@ -76,10 +74,12 @@ } } - fd_.reset(font_service::MatchFontFaceWithFallback( - desc->family, desc->weight >= PP_TRUETYPEFONTWEIGHT_BOLD, - desc->style & PP_TRUETYPEFONTSTYLE_ITALIC, desc->charset, - PP_BROWSERFONT_TRUSTED_FAMILY_DEFAULT)); + fd_.reset( + MatchFontFaceWithFallback(desc->family, + desc->weight >= PP_TRUETYPEFONTWEIGHT_BOLD, + desc->style & PP_TRUETYPEFONTSTYLE_ITALIC, + desc->charset, + PP_BROWSERFONT_TRUSTED_FAMILY_DEFAULT)); // TODO(bbudge) Modify content API to return results of font matching and // fallback, so we can update |desc| to reflect that. return fd_.is_valid() ? PP_OK : PP_ERROR_FAILED;
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc index fec7a4c..bb4cd9f 100644 --- a/content/browser/renderer_host/render_view_host_impl.cc +++ b/content/browser/renderer_host/render_view_host_impl.cc
@@ -566,9 +566,6 @@ prefs.background_video_track_optimization_enabled = base::FeatureList::IsEnabled(media::kBackgroundVideoTrackOptimization); - prefs.picture_in_picture_enabled = - base::FeatureList::IsEnabled(media::kUseSurfaceLayerForVideo); - GetContentClient()->browser()->OverrideWebkitPrefs(this, &prefs); return prefs; }
diff --git a/content/browser/sandbox_ipc_linux.cc b/content/browser/sandbox_ipc_linux.cc index a893d1b..c37d0a53 100644 --- a/content/browser/sandbox_ipc_linux.cc +++ b/content/browser/sandbox_ipc_linux.cc
@@ -21,15 +21,69 @@ #include "base/posix/unix_domain_socket.h" #include "base/process/launch.h" #include "base/strings/string_number_conversions.h" +#include "content/browser/renderer_host/font_utils_linux.h" +#include "content/common/font_config_ipc_linux.h" #include "content/public/common/content_switches.h" #include "sandbox/linux/services/libc_interceptor.h" #include "services/service_manager/sandbox/linux/sandbox_linux.h" +#include "skia/ext/skia_utils_base.h" +#include "third_party/skia/include/ports/SkFontConfigInterface.h" +#include "ui/gfx/font.h" +#include "ui/gfx/font_fallback_linux.h" +#include "ui/gfx/font_render_params.h" namespace content { -const size_t kMaxSandboxIPCMessagePayloadSize = 64; +namespace { + +SandboxIPCHandler::TestObserver* g_test_observer = nullptr; + +// Converts gfx::FontRenderParams::Hinting to WebFontRenderStyle::hintStyle. +// Returns an int for serialization, but the underlying Blink type is a char. +int ConvertHinting(gfx::FontRenderParams::Hinting hinting) { + switch (hinting) { + case gfx::FontRenderParams::HINTING_NONE: + return 0; + case gfx::FontRenderParams::HINTING_SLIGHT: + return 1; + case gfx::FontRenderParams::HINTING_MEDIUM: + return 2; + case gfx::FontRenderParams::HINTING_FULL: + return 3; + } + NOTREACHED() << "Unexpected hinting value " << hinting; + return 0; +} + +// Converts gfx::FontRenderParams::SubpixelRendering to +// WebFontRenderStyle::useSubpixelRendering. Returns an int for serialization, +// but the underlying Blink type is a char. +int ConvertSubpixelRendering( + gfx::FontRenderParams::SubpixelRendering rendering) { + switch (rendering) { + case gfx::FontRenderParams::SUBPIXEL_RENDERING_NONE: + return 0; + case gfx::FontRenderParams::SUBPIXEL_RENDERING_RGB: + return 1; + case gfx::FontRenderParams::SUBPIXEL_RENDERING_BGR: + return 1; + case gfx::FontRenderParams::SUBPIXEL_RENDERING_VRGB: + return 1; + case gfx::FontRenderParams::SUBPIXEL_RENDERING_VBGR: + return 1; + } + NOTREACHED() << "Unexpected subpixel rendering value " << rendering; + return 0; +} + +} // namespace // static +void SandboxIPCHandler::SetObserverForTests( + SandboxIPCHandler::TestObserver* observer) { + g_test_observer = observer; +} + SandboxIPCHandler::SandboxIPCHandler(int lifeline_fd, int browser_socket) : lifeline_fd_(lifeline_fd), browser_socket_(browser_socket) {} @@ -82,22 +136,17 @@ // A FontConfigIPC::METHOD_MATCH message could be kMaxFontFamilyLength // bytes long (this is the largest message type). - // The size limit used to be FontConfigIPC::kMaxFontFamilyLength which was - // 2048, but we do not receive FontConfig IPC here anymore. The only payloads - // here are service_manager::SandboxLinux::METHOD_MAKE_SHARED_MEMORY_SEGMENT - // and HandleLocalTime from libc_interceptor for which - // kMaxSandboxIPCMessagePayloadSize set to 64 should be plenty. // 128 bytes padding are necessary so recvmsg() does not return MSG_TRUNC // error for a maximum length message. - char buf[kMaxSandboxIPCMessagePayloadSize + 128]; + char buf[FontConfigIPC::kMaxFontFamilyLength + 128]; const ssize_t len = base::UnixDomainSocket::RecvMsg(fd, buf, sizeof(buf), &fds); if (len == -1) { // TODO: should send an error reply, or the sender might block forever. if (errno == EMSGSIZE) { - NOTREACHED() << "Sandbox host message is larger than " - "kMaxSandboxIPCMessagePayloadSize"; + NOTREACHED() + << "Sandbox host message is larger than kMaxFontFamilyLength"; } else { PLOG(ERROR) << "Recvmsg failed"; NOTREACHED(); @@ -119,12 +168,167 @@ if (sandbox::HandleInterceptedCall(kind, fd, iter, fds)) return; - if (kind == - service_manager::SandboxLinux::METHOD_MAKE_SHARED_MEMORY_SEGMENT) { + if (kind == FontConfigIPC::METHOD_MATCH) { + HandleFontMatchRequest(fd, iter, fds); + } else if (kind == FontConfigIPC::METHOD_OPEN) { + HandleFontOpenRequest(fd, iter, fds); + } else if (kind == + service_manager::SandboxLinux::METHOD_GET_FALLBACK_FONT_FOR_CHAR) { + HandleGetFallbackFontForChar(fd, iter, fds); + } else if (kind == + service_manager::SandboxLinux::METHOD_GET_STYLE_FOR_STRIKE) { + HandleGetStyleForStrike(fd, iter, fds); + } else if (kind == + service_manager::SandboxLinux::METHOD_MAKE_SHARED_MEMORY_SEGMENT) { HandleMakeSharedMemorySegment(fd, iter, fds); + } else if (kind == + service_manager::SandboxLinux::METHOD_MATCH_WITH_FALLBACK) { + HandleMatchWithFallback(fd, iter, fds); + } +} + +int SandboxIPCHandler::FindOrAddPath(const SkString& path) { + int count = paths_.size(); + for (int i = 0; i < count; ++i) { + if (path == paths_[i]) + return i; + } + paths_.emplace_back(path); + return count; +} + +void SandboxIPCHandler::HandleFontMatchRequest( + int fd, + base::PickleIterator iter, + const std::vector<base::ScopedFD>& fds) { + SkFontStyle requested_style; + std::string family; + if (!iter.ReadString(&family) || + !skia::ReadSkFontStyle(&iter, &requested_style)) + return; + + SkFontConfigInterface::FontIdentity result_identity; + SkString result_family; + SkFontStyle result_style; + SkFontConfigInterface* fc = + SkFontConfigInterface::GetSingletonDirectInterface(); + const bool r = + fc->matchFamilyName(family.c_str(), requested_style, &result_identity, + &result_family, &result_style); + + base::Pickle reply; + if (!r) { + reply.WriteBool(false); + } else { + // Stash away the returned path, so we can give it an ID (index) + // which will later be given to us in a request to open the file. + int index = FindOrAddPath(result_identity.fString); + result_identity.fID = static_cast<uint32_t>(index); + + reply.WriteBool(true); + skia::WriteSkString(&reply, result_family); + skia::WriteSkFontIdentity(&reply, result_identity); + skia::WriteSkFontStyle(&reply, result_style); + } + SendRendererReply(fds, reply, -1); +} + +void SandboxIPCHandler::HandleFontOpenRequest( + int fd, + base::PickleIterator iter, + const std::vector<base::ScopedFD>& fds) { + uint32_t index; + if (!iter.ReadUInt32(&index)) + return; + if (index >= static_cast<uint32_t>(paths_.size())) + return; + if (g_test_observer) { + g_test_observer->OnFontOpen(index); + } + const int result_fd = open(paths_[index].c_str(), O_RDONLY); + + base::Pickle reply; + reply.WriteBool(result_fd != -1); + + // The receiver will have its own access to the file, so we will close it + // after this send. + SendRendererReply(fds, reply, result_fd); + + if (result_fd >= 0) { + int err = IGNORE_EINTR(close(result_fd)); + DCHECK(!err); + } +} + +void SandboxIPCHandler::HandleGetFallbackFontForChar( + int fd, + base::PickleIterator iter, + const std::vector<base::ScopedFD>& fds) { + // The other side of this call is + // content/common/child_process_sandbox_support_impl_linux.cc + + UChar32 c; + if (!iter.ReadInt(&c)) + return; + + std::string preferred_locale; + if (!iter.ReadString(&preferred_locale)) + return; + + auto fallback_font = gfx::GetFallbackFontForChar(c, preferred_locale); + int fontconfig_interface_id = + FindOrAddPath(SkString(fallback_font.filename.data())); + + if (g_test_observer) { + g_test_observer->OnGetFallbackFontForChar(c, fallback_font.name, + fontconfig_interface_id); + } + base::Pickle reply; + reply.WriteString(fallback_font.name); + reply.WriteString(fallback_font.filename); + reply.WriteInt(fontconfig_interface_id); + reply.WriteInt(fallback_font.ttc_index); + reply.WriteBool(fallback_font.is_bold); + reply.WriteBool(fallback_font.is_italic); + SendRendererReply(fds, reply, -1); +} + +void SandboxIPCHandler::HandleGetStyleForStrike( + int fd, + base::PickleIterator iter, + const std::vector<base::ScopedFD>& fds) { + std::string family; + bool bold; + bool italic; + uint16_t pixel_size; + float device_scale_factor; + + if (!iter.ReadString(&family) || !iter.ReadBool(&bold) || + !iter.ReadBool(&italic) || !iter.ReadUInt16(&pixel_size) || + !iter.ReadFloat(&device_scale_factor)) { return; } - NOTREACHED(); + + gfx::FontRenderParamsQuery query; + query.families.push_back(family); + query.pixel_size = pixel_size; + query.style = italic ? gfx::Font::ITALIC : 0; + query.weight = bold ? gfx::Font::Weight::BOLD : gfx::Font::Weight::NORMAL; + query.device_scale_factor = device_scale_factor; + const gfx::FontRenderParams params = gfx::GetFontRenderParams(query, nullptr); + + // These are passed as ints since they're interpreted as tri-state chars in + // Blink. + base::Pickle reply; + reply.WriteInt(params.use_bitmaps); + reply.WriteInt(params.autohinter); + reply.WriteInt(params.hinting != gfx::FontRenderParams::HINTING_NONE); + reply.WriteInt(ConvertHinting(params.hinting)); + reply.WriteInt(params.antialiasing); + reply.WriteInt(ConvertSubpixelRendering(params.subpixel_rendering)); + reply.WriteInt(params.subpixel_positioning); + + SendRendererReply(fds, reply, -1); } void SandboxIPCHandler::HandleMakeSharedMemorySegment( @@ -146,6 +350,34 @@ SendRendererReply(fds, reply, shm_fd); } +void SandboxIPCHandler::HandleMatchWithFallback( + int fd, + base::PickleIterator iter, + const std::vector<base::ScopedFD>& fds) { + std::string face; + bool is_bold; + bool is_italic; + uint32_t charset; + uint32_t fallback_family; + + if (!iter.ReadString(&face) || face.empty() || !iter.ReadBool(&is_bold) || + !iter.ReadBool(&is_italic) || !iter.ReadUInt32(&charset) || + !iter.ReadUInt32(&fallback_family)) { + return; + } + + int font_fd = MatchFontFaceWithFallback(face, is_bold, is_italic, charset, + fallback_family); + + base::Pickle reply; + SendRendererReply(fds, reply, font_fd); + + if (font_fd >= 0) { + if (IGNORE_EINTR(close(font_fd)) < 0) + PLOG(ERROR) << "close"; + } +} + void SandboxIPCHandler::SendRendererReply( const std::vector<base::ScopedFD>& fds, const base::Pickle& reply,
diff --git a/content/browser/sandbox_ipc_linux.h b/content/browser/sandbox_ipc_linux.h index 684a6aa..06c2c604 100644 --- a/content/browser/sandbox_ipc_linux.h +++ b/content/browser/sandbox_ipc_linux.h
@@ -18,6 +18,8 @@ #include "content/common/content_export.h" #include "third_party/icu/source/common/unicode/uchar.h" +class SkString; + namespace content { class SandboxIPCHandler : public base::DelegateSimpleThread::Delegate { @@ -30,19 +32,55 @@ void Run() override; + class TestObserver { + public: + virtual void OnGetFallbackFontForChar(UChar32 c, + std::string name, + int id) = 0; + virtual void OnFontOpen(int id) = 0; + }; + CONTENT_EXPORT static void SetObserverForTests(TestObserver* observer); + private: + int FindOrAddPath(const SkString& path); + void HandleRequestFromChild(int fd); + void HandleFontMatchRequest(int fd, + base::PickleIterator iter, + const std::vector<base::ScopedFD>& fds); + + void HandleFontOpenRequest(int fd, + base::PickleIterator iter, + const std::vector<base::ScopedFD>& fds); + + void HandleGetFallbackFontForChar(int fd, + base::PickleIterator iter, + const std::vector<base::ScopedFD>& fds); + + void HandleGetStyleForStrike(int fd, + base::PickleIterator iter, + const std::vector<base::ScopedFD>& fds); + + void HandleLocaltime(int fd, + base::PickleIterator iter, + const std::vector<base::ScopedFD>& fds); + void HandleMakeSharedMemorySegment(int fd, base::PickleIterator iter, const std::vector<base::ScopedFD>& fds); + void HandleMatchWithFallback(int fd, + base::PickleIterator iter, + const std::vector<base::ScopedFD>& fds); + void SendRendererReply(const std::vector<base::ScopedFD>& fds, const base::Pickle& reply, int reply_fd); const int lifeline_fd_; const int browser_socket_; + std::vector<SkString> paths_; DISALLOW_COPY_AND_ASSIGN(SandboxIPCHandler); };
diff --git a/content/browser/service_worker/service_worker_provider_host.cc b/content/browser/service_worker/service_worker_provider_host.cc index 3a21425..59596b63 100644 --- a/content/browser/service_worker/service_worker_provider_host.cc +++ b/content/browser/service_worker/service_worker_provider_host.cc
@@ -267,13 +267,20 @@ if (context_) context_->UnregisterProviderHostByClientID(client_uuid_); - // Clear docurl so the deferred activation of a waiting worker - // won't associate the new version with a provider being destroyed. + // Stop listening to registrations. This must be done before removing the + // controllee below, otherwise it can trigger activation of a waiting worker + // and OnSkippedWaiting can be called which would associate the version + // with this provider being destroyed. + RemoveAllMatchingRegistrations(); + + // Clear |document_url_| so the activation of a waiting worker upon + // RemoveControllee() won't associate the new version with this provider being + // destroyed. + // TODO(falken): Is this still needed given that we call + // RemoveAllMatchingRegistrations? document_url_ = GURL(); if (controller_.get()) controller_->RemoveControllee(this); - - RemoveAllMatchingRegistrations(); } int ServiceWorkerProviderHost::frame_id() const {
diff --git a/content/browser/service_worker/service_worker_provider_host_unittest.cc b/content/browser/service_worker/service_worker_provider_host_unittest.cc index 1855c4ec..876ff87 100644 --- a/content/browser/service_worker/service_worker_provider_host_unittest.cc +++ b/content/browser/service_worker/service_worker_provider_host_unittest.cc
@@ -10,6 +10,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/run_loop.h" +#include "base/test/scoped_feature_list.h" #include "base/threading/thread_task_runner_handle.h" #include "content/browser/service_worker/embedded_worker_test_helper.h" #include "content/browser/service_worker/service_worker_context_core.h" @@ -29,6 +30,7 @@ #include "content/test/test_content_client.h" #include "mojo/core/embedder/embedder.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/features.h" #include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h" #include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h" @@ -73,7 +75,7 @@ } // namespace -class ServiceWorkerProviderHostTest : public testing::Test { +class ServiceWorkerProviderHostTest : public testing::TestWithParam<bool> { protected: ServiceWorkerProviderHostTest() : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP), @@ -83,6 +85,14 @@ ~ServiceWorkerProviderHostTest() override {} void SetUp() override { + if (IsServiceWorkerServicificationEnabled()) { + scoped_feature_list_.InitAndEnableFeature( + blink::features::kServiceWorkerServicification); + } else { + scoped_feature_list_.InitAndDisableFeature( + blink::features::kServiceWorkerServicification); + } + old_content_browser_client_ = SetBrowserClientForTesting(&test_content_browser_client_); ResetSchemesAndOriginsWhitelist(); @@ -253,6 +263,8 @@ return false; } + bool IsServiceWorkerServicificationEnabled() { return GetParam(); } + std::vector<std::string> bad_messages_; TestBrowserThreadBundle thread_bundle_; std::unique_ptr<EmbeddedWorkerTestHelper> helper_; @@ -266,6 +278,7 @@ ContentBrowserClient* old_content_browser_client_; int next_renderer_provided_id_; std::vector<ServiceWorkerRemoteProviderEndpoint> remote_endpoints_; + base::test::ScopedFeatureList scoped_feature_list_; private: ServiceWorkerProviderHost* CreateProviderHostInternal( @@ -297,7 +310,7 @@ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerProviderHostTest); }; -TEST_F(ServiceWorkerProviderHostTest, MatchRegistration) { +TEST_P(ServiceWorkerProviderHostTest, MatchRegistration) { ServiceWorkerProviderHost* provider_host1 = CreateProviderHost(GURL("https://www.example.com/example1.html")); @@ -323,7 +336,7 @@ ASSERT_EQ(nullptr, provider_host1->MatchRegistration()); } -TEST_F(ServiceWorkerProviderHostTest, ContextSecurity) { +TEST_P(ServiceWorkerProviderHostTest, ContextSecurity) { ServiceWorkerProviderHost* provider_host_secure_parent = CreateProviderHost(GURL("https://www.example.com/example1.html")); ServiceWorkerProviderHost* provider_host_insecure_parent = @@ -384,7 +397,7 @@ std::set<ServiceWorkerRegistration::Listener*> listeners_; }; -TEST_F(ServiceWorkerProviderHostTest, RemoveProvider) { +TEST_P(ServiceWorkerProviderHostTest, RemoveProvider) { // Create a provider host connected with the renderer process. ServiceWorkerProviderHost* provider_host = CreateProviderHost(GURL("https://www.example.com/example1.html")); @@ -423,7 +436,7 @@ mojo::AssociatedBinding<mojom::ServiceWorkerContainer> binding_; }; -TEST_F(ServiceWorkerProviderHostTest, Controller) { +TEST_P(ServiceWorkerProviderHostTest, Controller) { // Create a host. base::WeakPtr<ServiceWorkerProviderHost> host = ServiceWorkerProviderHost::PreCreateNavigationHost( @@ -460,7 +473,7 @@ EXPECT_TRUE(container->was_set_controller_called()); } -TEST_F(ServiceWorkerProviderHostTest, ActiveIsNotController) { +TEST_P(ServiceWorkerProviderHostTest, ActiveIsNotController) { // Create a host. base::WeakPtr<ServiceWorkerProviderHost> host = ServiceWorkerProviderHost::PreCreateNavigationHost( @@ -498,7 +511,7 @@ EXPECT_FALSE(container->was_set_controller_called()); } -TEST_F(ServiceWorkerProviderHostTest, +TEST_P(ServiceWorkerProviderHostTest, Register_ContentSettingsDisallowsServiceWorker) { ServiceWorkerTestContentBrowserClient test_browser_client; ContentBrowserClient* old_browser_client = @@ -539,7 +552,11 @@ SetBrowserClientForTesting(old_browser_client); } -TEST_F(ServiceWorkerProviderHostTest, AllowsServiceWorker) { +TEST_P(ServiceWorkerProviderHostTest, AllowsServiceWorker) { + // TODO(crbug.com/860380): Fails with NetS13nServiceWorker. + if (IsServiceWorkerServicificationEnabled()) + return; + // Create an active version. scoped_refptr<ServiceWorkerVersion> version = base::MakeRefCounted<ServiceWorkerVersion>( @@ -568,7 +585,7 @@ SetBrowserClientForTesting(old_browser_client); } -TEST_F(ServiceWorkerProviderHostTest, Register_HTTPS) { +TEST_P(ServiceWorkerProviderHostTest, Register_HTTPS) { ServiceWorkerRemoteProviderEndpoint remote_endpoint = PrepareServiceWorkerProviderHost(GURL("https://www.example.com/foo")); @@ -578,7 +595,7 @@ GURL("https://www.example.com/bar"))); } -TEST_F(ServiceWorkerProviderHostTest, Register_NonSecureTransportLocalhost) { +TEST_P(ServiceWorkerProviderHostTest, Register_NonSecureTransportLocalhost) { ServiceWorkerRemoteProviderEndpoint remote_endpoint = PrepareServiceWorkerProviderHost(GURL("http://127.0.0.3:81/foo")); @@ -588,7 +605,7 @@ GURL("http://127.0.0.3:81/baz"))); } -TEST_F(ServiceWorkerProviderHostTest, Register_InvalidScopeShouldFail) { +TEST_P(ServiceWorkerProviderHostTest, Register_InvalidScopeShouldFail) { ServiceWorkerRemoteProviderEndpoint remote_endpoint = PrepareServiceWorkerProviderHost(GURL("https://www.example.com/foo")); @@ -598,7 +615,7 @@ EXPECT_EQ(1u, bad_messages_.size()); } -TEST_F(ServiceWorkerProviderHostTest, Register_InvalidScriptShouldFail) { +TEST_P(ServiceWorkerProviderHostTest, Register_InvalidScriptShouldFail) { ServiceWorkerRemoteProviderEndpoint remote_endpoint = PrepareServiceWorkerProviderHost(GURL("https://www.example.com/foo")); @@ -608,7 +625,7 @@ EXPECT_EQ(1u, bad_messages_.size()); } -TEST_F(ServiceWorkerProviderHostTest, Register_NonSecureOriginShouldFail) { +TEST_P(ServiceWorkerProviderHostTest, Register_NonSecureOriginShouldFail) { ServiceWorkerRemoteProviderEndpoint remote_endpoint = PrepareServiceWorkerProviderHost(GURL("http://www.example.com/foo")); @@ -618,7 +635,7 @@ EXPECT_EQ(1u, bad_messages_.size()); } -TEST_F(ServiceWorkerProviderHostTest, Register_CrossOriginShouldFail) { +TEST_P(ServiceWorkerProviderHostTest, Register_CrossOriginShouldFail) { ServiceWorkerRemoteProviderEndpoint remote_endpoint = PrepareServiceWorkerProviderHost(GURL("https://www.example.com/foo")); @@ -653,7 +670,7 @@ EXPECT_EQ(6u, bad_messages_.size()); } -TEST_F(ServiceWorkerProviderHostTest, Register_BadCharactersShouldFail) { +TEST_P(ServiceWorkerProviderHostTest, Register_BadCharactersShouldFail) { ServiceWorkerRemoteProviderEndpoint remote_endpoint = PrepareServiceWorkerProviderHost(GURL("https://www.example.com")); @@ -686,7 +703,7 @@ EXPECT_EQ(6u, bad_messages_.size()); } -TEST_F(ServiceWorkerProviderHostTest, Register_FileSystemDocumentShouldFail) { +TEST_P(ServiceWorkerProviderHostTest, Register_FileSystemDocumentShouldFail) { ServiceWorkerRemoteProviderEndpoint remote_endpoint = PrepareServiceWorkerProviderHost( GURL("filesystem:https://www.example.com/temporary/a")); @@ -708,7 +725,7 @@ EXPECT_EQ(3u, bad_messages_.size()); } -TEST_F(ServiceWorkerProviderHostTest, +TEST_P(ServiceWorkerProviderHostTest, Register_FileSystemScriptOrScopeShouldFail) { ServiceWorkerRemoteProviderEndpoint remote_endpoint = PrepareServiceWorkerProviderHost( @@ -731,7 +748,7 @@ EXPECT_EQ(3u, bad_messages_.size()); } -TEST_F(ServiceWorkerProviderHostTest, EarlyContextDeletion) { +TEST_P(ServiceWorkerProviderHostTest, EarlyContextDeletion) { ServiceWorkerRemoteProviderEndpoint remote_endpoint = PrepareServiceWorkerProviderHost(GURL("https://www.example.com/foo")); @@ -745,7 +762,7 @@ EXPECT_TRUE(remote_endpoint.host_ptr()->encountered_error()); } -TEST_F(ServiceWorkerProviderHostTest, GetRegistration_Success) { +TEST_P(ServiceWorkerProviderHostTest, GetRegistration_Success) { ServiceWorkerRemoteProviderEndpoint remote_endpoint = PrepareServiceWorkerProviderHost(GURL("https://www.example.com/foo")); @@ -760,7 +777,7 @@ EXPECT_EQ(kScope, info->options->scope); } -TEST_F(ServiceWorkerProviderHostTest, +TEST_P(ServiceWorkerProviderHostTest, GetRegistration_NotFoundShouldReturnNull) { ServiceWorkerRemoteProviderEndpoint remote_endpoint = PrepareServiceWorkerProviderHost(GURL("https://www.example.com/foo")); @@ -772,7 +789,7 @@ EXPECT_FALSE(info); } -TEST_F(ServiceWorkerProviderHostTest, GetRegistration_CrossOriginShouldFail) { +TEST_P(ServiceWorkerProviderHostTest, GetRegistration_CrossOriginShouldFail) { ServiceWorkerRemoteProviderEndpoint remote_endpoint = PrepareServiceWorkerProviderHost(GURL("https://www.example.com/foo")); @@ -782,7 +799,7 @@ EXPECT_EQ(1u, bad_messages_.size()); } -TEST_F(ServiceWorkerProviderHostTest, GetRegistration_InvalidScopeShouldFail) { +TEST_P(ServiceWorkerProviderHostTest, GetRegistration_InvalidScopeShouldFail) { ServiceWorkerRemoteProviderEndpoint remote_endpoint = PrepareServiceWorkerProviderHost(GURL("https://www.example.com/foo")); @@ -791,7 +808,7 @@ EXPECT_EQ(1u, bad_messages_.size()); } -TEST_F(ServiceWorkerProviderHostTest, +TEST_P(ServiceWorkerProviderHostTest, GetRegistration_NonSecureOriginShouldFail) { ServiceWorkerRemoteProviderEndpoint remote_endpoint = PrepareServiceWorkerProviderHost(GURL("http://www.example.com/foo")); @@ -802,7 +819,7 @@ EXPECT_EQ(1u, bad_messages_.size()); } -TEST_F(ServiceWorkerProviderHostTest, GetRegistrations_SecureOrigin) { +TEST_P(ServiceWorkerProviderHostTest, GetRegistrations_SecureOrigin) { ServiceWorkerRemoteProviderEndpoint remote_endpoint = PrepareServiceWorkerProviderHost(GURL("https://www.example.com/foo")); @@ -810,7 +827,7 @@ GetRegistrations(remote_endpoint.host_ptr()->get())); } -TEST_F(ServiceWorkerProviderHostTest, +TEST_P(ServiceWorkerProviderHostTest, GetRegistrations_NonSecureOriginShouldFail) { ServiceWorkerRemoteProviderEndpoint remote_endpoint = PrepareServiceWorkerProviderHost(GURL("http://www.example.com/foo")); @@ -823,7 +840,7 @@ // Test that a "reserved" (i.e., not execution ready) client is not included // when iterating over client provider hosts. If it were, it'd be undesirably // exposed via the Clients API. -TEST_F(ServiceWorkerProviderHostTest, +TEST_P(ServiceWorkerProviderHostTest, ReservedClientsAreNotExposedToClientsAPI) { { auto provider_info = mojom::ServiceWorkerProviderInfoForSharedWorker::New(); @@ -857,4 +874,93 @@ } } +// Regression test for https://crbug.com/860106. When a provider host +// is destroyed, it removes itself as a controllee from its controller. +// This can trigger the waiting version starting to activate. The +// destructing host shouldn't try to change its controller to the new +// active version. +TEST_P(ServiceWorkerProviderHostTest, DontSetControllerInDestructor) { + // This test requires the idle timeout mechanism of S13nSW to exercise the + // desired code path. + if (!IsServiceWorkerServicificationEnabled()) + return; + + // Make a window. + ServiceWorkerProviderHost* provider_host1 = + CreateProviderHost(GURL("https://www.example.com/example1.html")); + + // Make an active version. + auto version1 = base::MakeRefCounted<ServiceWorkerVersion>( + registration1_.get(), GURL("https://www.example.com/sw.js"), + 1 /* version_id */, helper_->context()->AsWeakPtr()); + version1->set_fetch_handler_existence( + ServiceWorkerVersion::FetchHandlerExistence::EXISTS); + version1->SetStatus(ServiceWorkerVersion::ACTIVATED); + registration1_->SetActiveVersion(version1); + + // Make the registration findable via storage functions. This allows + // the service worker to start, which will be needed later. + base::RunLoop loop; + helper_->context()->storage()->LazyInitializeForTest(loop.QuitClosure()); + loop.Run(); + std::vector<ServiceWorkerDatabase::ResourceRecord> records; + records.push_back(WriteToDiskCacheSync( + helper_->context()->storage(), version1->script_url(), + helper_->context()->storage()->NewResourceId(), {} /* headers */, + "I'm the body", "I'm the meta data")); + version1->script_cache_map()->SetResources(records); + version1->SetMainScriptHttpResponseInfo( + EmbeddedWorkerTestHelper::CreateHttpResponseInfo()); + blink::ServiceWorkerStatusCode status; + helper_->context()->storage()->StoreRegistration( + registration1_.get(), version1.get(), + CreateReceiverOnCurrentThread(&status)); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, status); + + // Make the active worker the controller and give it an ongoing request. This + // way when a waiting worker calls SkipWaiting(), activation won't trigger + // until we're ready. + provider_host1->AssociateRegistration(registration1_.get(), false); + EXPECT_EQ(version1.get(), provider_host1->controller()); + // The worker must be running to have a request. + status = blink::ServiceWorkerStatusCode::kMax; + version1->StartWorker(ServiceWorkerMetrics::EventType::PUSH, + base::DoNothing()); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version1->running_status()); + int request = version1->StartRequest(ServiceWorkerMetrics::EventType::PUSH, + base::DoNothing()); + + // Make the waiting worker and have it call SkipWaiting(). + auto version2 = base::MakeRefCounted<ServiceWorkerVersion>( + registration1_.get(), GURL("https://www.example.com/sw.js"), + 2 /* version_id */, helper_->context()->AsWeakPtr()); + version2->set_fetch_handler_existence( + ServiceWorkerVersion::FetchHandlerExistence::EXISTS); + version2->SetStatus(ServiceWorkerVersion::INSTALLED); + registration1_->SetWaitingVersion(version2); + version2->SkipWaiting(base::DoNothing()); + + // Finish the request. Activation won't yet occur until as + // |idle_time_fired_in_renderer_| isn't true. + version1->FinishRequest(request, true, base::Time::Now()); + + // Destroy the provider host. This triggers activation, and since + // SkipWaiting() was called, the provider host is in danger + // of receiving an OnSkippedWaiting() call during destruction. + ASSERT_TRUE(remote_endpoints_.back().host_ptr()->is_bound()); + remote_endpoints_.back().host_ptr()->reset(); + base::RunLoop().RunUntilIdle(); + + // No crash should occur, and the new version should be the active + // one. + EXPECT_EQ(version2.get(), registration1_->active_version()); + EXPECT_FALSE(version2->HasControllee()); +} + +INSTANTIATE_TEST_CASE_P(IsServiceWorkerServicificationEnabled, + ServiceWorkerProviderHostTest, + ::testing::Bool();); + } // namespace content
diff --git a/content/browser/service_worker/service_worker_script_loader_factory.cc b/content/browser/service_worker/service_worker_script_loader_factory.cc index 24b89fb..8cb3c3d 100644 --- a/content/browser/service_worker/service_worker_script_loader_factory.cc +++ b/content/browser/service_worker/service_worker_script_loader_factory.cc
@@ -40,13 +40,9 @@ const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) { DCHECK(ServiceWorkerUtils::IsServicificationEnabled()); if (!CheckIfScriptRequestIsValid(resource_request)) { - // If the request should not be handled, just do a passthrough load. This - // needs a relaying as we use different associated message pipes. // TODO(kinuko): Record the reason like what we do with netlog in // ServiceWorkerContextRequestHandler. - loader_factory_->CreateLoaderAndStart( - std::move(request), routing_id, request_id, options, resource_request, - std::move(client), traffic_annotation); + client->OnComplete(network::URLLoaderCompletionStatus(net::ERR_ABORTED)); return; } @@ -116,34 +112,20 @@ // Handle only the service worker main script (RESOURCE_TYPE_SERVICE_WORKER) // or importScripts() (RESOURCE_TYPE_SCRIPT). - switch (resource_request.resource_type) { - case RESOURCE_TYPE_SERVICE_WORKER: - // The main script should be fetched only when we start a new service - // worker. - if (version->status() != ServiceWorkerVersion::NEW) - return false; - break; - case RESOURCE_TYPE_SCRIPT: - // TODO(nhiroki): In the current implementation, importScripts() can be - // called in any ServiceWorkerVersion::Status except for REDUNDANT, but - // the spec defines importScripts() works only on the initial script - // evaluation and the install event. Update this check once - // importScripts() is fixed (https://crbug.com/719052). - if (version->status() == ServiceWorkerVersion::REDUNDANT) { - // This could happen if browser-side has set the status to redundant but - // the worker has not yet stopped. The worker is already doomed so just - // reject the request. Handle it specially here because otherwise it'd - // be unclear whether "REDUNDANT" should count as installed or not - // installed when making decisions about how to handle the request and - // logging UMA. - return false; - } - break; - default: - // TODO(nhiroki): Record bad message, we shouldn't come here for other - // request types. - NOTREACHED(); - return false; + if (resource_request.resource_type != RESOURCE_TYPE_SERVICE_WORKER && + resource_request.resource_type != RESOURCE_TYPE_SCRIPT) { + mojo::ReportBadMessage("SWSLF_BAD_RESOURCE_TYPE"); + return false; + } + + if (version->status() == ServiceWorkerVersion::REDUNDANT) { + // This could happen if browser-side has set the status to redundant but + // the worker has not yet stopped. The worker is already doomed so just + // reject the request. Handle it specially here because otherwise it'd + // be unclear whether "REDUNDANT" should count as installed or not + // installed when making decisions about how to handle the request and + // logging UMA. + return false; } // TODO(falken): Make sure we don't handle a redirected request.
diff --git a/content/browser/service_worker/service_worker_version.h b/content/browser/service_worker/service_worker_version.h index ef3d042..620d0e4 100644 --- a/content/browser/service_worker/service_worker_version.h +++ b/content/browser/service_worker/service_worker_version.h
@@ -492,6 +492,8 @@ FRIEND_TEST_ALL_PREFIXES(service_worker_controllee_request_handler_unittest:: ServiceWorkerControlleeRequestHandlerTest, FallbackWithNoFetchHandler); + FRIEND_TEST_ALL_PREFIXES(ServiceWorkerProviderHostTest, + DontSetControllerInDestructor); FRIEND_TEST_ALL_PREFIXES(ServiceWorkerJobTest, Register); FRIEND_TEST_ALL_PREFIXES( service_worker_version_unittest::ServiceWorkerVersionTest,
diff --git a/content/browser/webui/web_ui_mojo_browsertest.cc b/content/browser/webui/web_ui_mojo_browsertest.cc index 59d693f..7a01eabf 100644 --- a/content/browser/webui/web_ui_mojo_browsertest.cc +++ b/content/browser/webui/web_ui_mojo_browsertest.cc
@@ -283,9 +283,9 @@ // Disabled due to flakiness: crbug.com/860385. #if defined(OS_ANDROID) -#define MAYGE_NativeMojoAvailable DISABLED_NativeMojoAvailable +#define MAYBE_NativeMojoAvailable DISABLED_NativeMojoAvailable #else -#define MAYGE_NativeMojoAvailable NativeMojoAvailable +#define MAYBE_NativeMojoAvailable NativeMojoAvailable #endif IN_PROC_BROWSER_TEST_F(WebUIMojoTest, MAYBE_NativeMojoAvailable) { // Mojo bindings should be enabled. @@ -311,9 +311,9 @@ // Disabled due to flakiness: crbug.com/860385. #if defined(OS_ANDROID) -#define MAYGE_ChromeSendAvailable DISABLED_ChromeSendAvailable +#define MAYBE_ChromeSendAvailable DISABLED_ChromeSendAvailable #else -#define MAYGE_ChromeSendAvailable ChromeSendAvailable +#define MAYBE_ChromeSendAvailable ChromeSendAvailable #endif IN_PROC_BROWSER_TEST_F(WebUIMojoTest, MAYBE_ChromeSendAvailable) { // chrome.send is not available on mojo-only WebUIs.
diff --git a/content/child/BUILD.gn b/content/child/BUILD.gn index 23214a9e..f8190e6 100644 --- a/content/child/BUILD.gn +++ b/content/child/BUILD.gn
@@ -140,13 +140,6 @@ ] } - if (is_linux && !is_android) { - deps += [ - "//components/services/font:lib", - "//components/services/font/public/cpp", - ] - } - if (is_android) { deps += [ "//third_party/android_tools:cpu_features" ] }
diff --git a/content/child/DEPS b/content/child/DEPS index e280e35f..c6e3f2d 100644 --- a/content/child/DEPS +++ b/content/child/DEPS
@@ -4,7 +4,6 @@ "+components/tracing", "+components/variations/child_process_field_trial_syncer.h", "+components/webcrypto", - "+components/services/font", "+content/app/strings/grit", # For generated headers "+content/public/child",
diff --git a/content/child/child_process_sandbox_support_impl_linux.cc b/content/child/child_process_sandbox_support_impl_linux.cc index 32dfe1a..046e064 100644 --- a/content/child/child_process_sandbox_support_impl_linux.cc +++ b/content/child/child_process_sandbox_support_impl_linux.cc
@@ -15,10 +15,6 @@ #include "base/posix/unix_domain_socket.h" #include "base/sys_byteorder.h" #include "base/trace_event/trace_event.h" -#include "components/services/font/public/cpp/font_loader.h" -#include "components/services/font/public/interfaces/constants.mojom.h" -#include "components/services/font/public/interfaces/font_service.mojom.h" -#include "content/public/common/common_sandbox_support_linux.h" #include "services/service_manager/sandbox/linux/sandbox_linux.h" #include "services/service_manager/zygote/common/common_sandbox_support_linux.h" #include "third_party/blink/public/platform/linux/web_fallback_font.h" @@ -28,64 +24,111 @@ namespace content { -void GetFallbackFontForCharacter(sk_sp<font_service::FontLoader> font_loader, - int32_t character, +void GetFallbackFontForCharacter(int32_t character, const char* preferred_locale, - blink::WebFallbackFont* fallback_font) { - DCHECK(font_loader.get()); - font_service::mojom::FontIdentityPtr font_identity; - bool is_bold = false; - bool is_italic = false; - std::string family_name; - if (!font_loader->FallbackFontForCharacter(character, preferred_locale, - &font_identity, &family_name, - &is_bold, &is_italic)) { - LOG(ERROR) << "FontService fallback request does not receive a response."; - return; - } + blink::WebFallbackFont* fallbackFont) { + TRACE_EVENT0("sandbox_ipc", "GetFontFamilyForCharacter"); - // TODO(drott): Perhaps take WebFallbackFont out of the picture here and pass - // mojo FontIdentityPtr directly? - fallback_font->name = - blink::WebString::FromUTF8(family_name.c_str(), family_name.length()); - fallback_font->fontconfig_interface_id = font_identity->id; - fallback_font->filename.Assign(font_identity->str_representation.c_str(), - font_identity->str_representation.length()); - fallback_font->ttc_index = font_identity->ttc_index; - fallback_font->is_bold = is_bold; - fallback_font->is_italic = is_italic; - return; + base::Pickle request; + request.WriteInt( + service_manager::SandboxLinux::METHOD_GET_FALLBACK_FONT_FOR_CHAR); + request.WriteInt(character); + request.WriteString(preferred_locale); + + uint8_t buf[512]; + const ssize_t n = base::UnixDomainSocket::SendRecvMsg( + service_manager::GetSandboxFD(), buf, sizeof(buf), nullptr, request); + + std::string family_name; + std::string filename; + int fontconfigInterfaceId = 0; + int ttcIndex = 0; + bool isBold = false; + bool isItalic = false; + if (n != -1) { + base::Pickle reply(reinterpret_cast<char*>(buf), n); + base::PickleIterator pickle_iter(reply); + if (pickle_iter.ReadString(&family_name) && + pickle_iter.ReadString(&filename) && + pickle_iter.ReadInt(&fontconfigInterfaceId) && + pickle_iter.ReadInt(&ttcIndex) && pickle_iter.ReadBool(&isBold) && + pickle_iter.ReadBool(&isItalic)) { + fallbackFont->name = blink::WebString::FromUTF8(family_name); + fallbackFont->filename = blink::WebVector<char>(filename); + fallbackFont->fontconfig_interface_id = fontconfigInterfaceId; + fallbackFont->ttc_index = ttcIndex; + fallbackFont->is_bold = isBold; + fallbackFont->is_italic = isItalic; + } + } } -void GetRenderStyleForStrike(sk_sp<font_service::FontLoader> font_loader, - const char* family, +void GetRenderStyleForStrike(const char* family, int size, bool is_bold, bool is_italic, float device_scale_factor, blink::WebFontRenderStyle* out) { - DCHECK(font_loader.get()); - font_service::mojom::FontIdentityPtr font_identity; + TRACE_EVENT0("sandbox_ipc", "GetRenderStyleForStrike"); *out = blink::WebFontRenderStyle(); if (size < 0 || size > std::numeric_limits<uint16_t>::max()) return; - font_service::mojom::FontRenderStylePtr font_render_style; - font_loader->FontRenderStyleForStrike(family, size, is_bold, is_italic, - device_scale_factor, - &font_render_style); + base::Pickle request; + request.WriteInt(service_manager::SandboxLinux::METHOD_GET_STYLE_FOR_STRIKE); + request.WriteString(family); + request.WriteBool(is_bold); + request.WriteBool(is_italic); + request.WriteUInt16(size); + request.WriteFloat(device_scale_factor); - out->use_bitmaps = static_cast<char>(font_render_style->use_bitmaps); - out->use_auto_hint = static_cast<char>(font_render_style->use_autohint); - out->use_hinting = static_cast<char>(font_render_style->use_hinting); - out->hint_style = font_render_style->hint_style; - out->use_anti_alias = static_cast<char>(font_render_style->use_antialias); - out->use_subpixel_rendering = - static_cast<char>(font_render_style->use_subpixel_rendering); - out->use_subpixel_positioning = - static_cast<char>(font_render_style->use_subpixel_positioning); + uint8_t buf[512]; + const ssize_t n = base::UnixDomainSocket::SendRecvMsg( + service_manager::GetSandboxFD(), buf, sizeof(buf), nullptr, request); + if (n == -1) + return; + + base::Pickle reply(reinterpret_cast<char*>(buf), n); + base::PickleIterator pickle_iter(reply); + int use_bitmaps, use_autohint, use_hinting, hint_style, use_antialias; + int use_subpixel_rendering, use_subpixel_positioning; + if (pickle_iter.ReadInt(&use_bitmaps) && pickle_iter.ReadInt(&use_autohint) && + pickle_iter.ReadInt(&use_hinting) && pickle_iter.ReadInt(&hint_style) && + pickle_iter.ReadInt(&use_antialias) && + pickle_iter.ReadInt(&use_subpixel_rendering) && + pickle_iter.ReadInt(&use_subpixel_positioning)) { + out->use_bitmaps = use_bitmaps; + out->use_auto_hint = use_autohint; + out->use_hinting = use_hinting; + out->hint_style = hint_style; + out->use_anti_alias = use_antialias; + out->use_subpixel_rendering = use_subpixel_rendering; + out->use_subpixel_positioning = use_subpixel_positioning; + } +} + +int MatchFontWithFallback(const std::string& face, + bool bold, + bool italic, + int charset, + PP_BrowserFont_Trusted_Family fallback_family) { + TRACE_EVENT0("sandbox_ipc", "MatchFontWithFallback"); + + base::Pickle request; + request.WriteInt(service_manager::SandboxLinux::METHOD_MATCH_WITH_FALLBACK); + request.WriteString(face); + request.WriteBool(bold); + request.WriteBool(italic); + request.WriteUInt32(charset); + request.WriteUInt32(fallback_family); + uint8_t reply_buf[64]; + int fd = -1; + base::UnixDomainSocket::SendRecvMsg(service_manager::GetSandboxFD(), + reply_buf, sizeof(reply_buf), &fd, + request); + return fd; } } // namespace content
diff --git a/content/child/child_process_sandbox_support_impl_linux.h b/content/child/child_process_sandbox_support_impl_linux.h index 140060c..293c527 100644 --- a/content/child/child_process_sandbox_support_impl_linux.h +++ b/content/child/child_process_sandbox_support_impl_linux.h
@@ -7,8 +7,7 @@ #include <stdint.h> -#include "components/services/font/public/cpp/font_loader.h" -#include "third_party/skia/include/core/SkRefCnt.h" +#include "content/public/child/child_process_sandbox_support_linux.h" namespace blink { struct WebFallbackFont; @@ -21,8 +20,7 @@ // specified by |character|, a UTF-32 character. |preferred_locale| contains the // preferred locale identifier for |character|. The instance has an empty font // name if the request could not be satisfied. -void GetFallbackFontForCharacter(sk_sp<font_service::FontLoader> font_loader, - const int32_t character, +void GetFallbackFontForCharacter(const int32_t character, const char* preferred_locale, blink::WebFallbackFont* family); @@ -30,8 +28,7 @@ // |size_and_style| stores the bold setting in its least-significant bit, the // italic setting in its second-least-significant bit, and holds the requested // size in pixels into its remaining bits. -void GetRenderStyleForStrike(sk_sp<font_service::FontLoader> font_loader, - const char* family, +void GetRenderStyleForStrike(const char* family, int size, bool is_bold, bool is_italic,
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn index 4c3fa75e1..bdda69a 100644 --- a/content/common/BUILD.gn +++ b/content/common/BUILD.gn
@@ -116,6 +116,8 @@ "fileapi/file_system_messages.h", "fileapi/webblob_messages.h", "font_cache_dispatcher_win.cc", + "font_config_ipc_linux.cc", + "font_config_ipc_linux.h", "font_list.cc", "font_list.h", "font_list_android.cc",
diff --git a/content/common/cache_storage/OWNERS b/content/common/cache_storage/OWNERS deleted file mode 100644 index 5e0c72b..0000000 --- a/content/common/cache_storage/OWNERS +++ /dev/null
@@ -1,15 +0,0 @@ -nhiroki@chromium.org -jkarlin@chromium.org -jsbell@chromium.org - -per-file *_messages*.h=set noparent -per-file *_messages*.h=file://ipc/SECURITY_OWNERS - -per-file *_mojom_traits*.*=set noparent -per-file *_mojom_traits*.*=file://ipc/SECURITY_OWNERS - -per-file *.typemap=set noparent -per-file *.typemap=file://ipc/SECURITY_OWNERS - -# TEAM: storage-dev@chromium.org -# COMPONENT: Blink>Storage>CacheStorage
diff --git a/content/common/cache_storage/cache_storage_mojom_traits.h b/content/common/cache_storage/cache_storage_mojom_traits.h deleted file mode 100644 index 764b68d..0000000 --- a/content/common/cache_storage/cache_storage_mojom_traits.h +++ /dev/null
@@ -1,80 +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 CONTENT_COMMON_CACHE_STORAGE_CACHE_STORAGE_MOJOM_TRAITS_H_ -#define CONTENT_COMMON_CACHE_STORAGE_CACHE_STORAGE_MOJOM_TRAITS_H_ - -#include <map> -#include <string> -#include <vector> - -#include "base/optional.h" -#include "base/strings/string16.h" -#include "content/common/service_worker/service_worker_fetch_request_mojom_traits.h" -#include "content/common/service_worker/service_worker_fetch_response_mojom_traits.h" -#include "content/common/service_worker/service_worker_types.h" -#include "mojo/public/cpp/base/string16_mojom_traits.h" -#include "third_party/blink/public/platform/modules/cache_storage/cache_storage.mojom.h" -#include "url/gurl.h" - -namespace mojo { - -template <> -struct EnumTraits<blink::mojom::OperationType, - content::CacheStorageCacheOperationType> { - static blink::mojom::OperationType ToMojom( - content::CacheStorageCacheOperationType input); - static bool FromMojom(blink::mojom::OperationType input, - content::CacheStorageCacheOperationType* out); -}; - -template <> -struct StructTraits<blink::mojom::QueryParamsDataView, - content::CacheStorageCacheQueryParams> { - static bool ignore_search( - const content::CacheStorageCacheQueryParams& query_params) { - return query_params.ignore_search; - } - static bool ignore_method( - const content::CacheStorageCacheQueryParams& query_params) { - return query_params.ignore_method; - } - static bool ignore_vary( - const content::CacheStorageCacheQueryParams& query_params) { - return query_params.ignore_vary; - } - static const base::Optional<base::string16>& cache_name( - const content::CacheStorageCacheQueryParams& query_params) { - return query_params.cache_name.as_optional_string16(); - } - static bool Read(blink::mojom::QueryParamsDataView, - content::CacheStorageCacheQueryParams* output); -}; - -template <> -struct StructTraits<blink::mojom::BatchOperationDataView, - content::CacheStorageBatchOperation> { - static content::CacheStorageCacheOperationType operation_type( - const content::CacheStorageBatchOperation& batch_operation) { - return batch_operation.operation_type; - } - static content::ServiceWorkerFetchRequest request( - const content::CacheStorageBatchOperation& batch_operation) { - return batch_operation.request; - } - static content::ServiceWorkerResponse response( - const content::CacheStorageBatchOperation& batch_operation) { - return batch_operation.response; - } - static content::CacheStorageCacheQueryParams match_params( - const content::CacheStorageBatchOperation& batch_operation) { - return batch_operation.match_params; - } - static bool Read(blink::mojom::BatchOperationDataView, - content::CacheStorageBatchOperation* output); -}; - -} // namespace mojo - -#endif // CONTENT_COMMON_CACHE_STORAGE_CACHE_STORAGE_MOJOM_TRAITS_H_
diff --git a/content/common/common_sandbox_support_linux.cc b/content/common/common_sandbox_support_linux.cc index 507c3558..1c05b650 100644 --- a/content/common/common_sandbox_support_linux.cc +++ b/content/common/common_sandbox_support_linux.cc
@@ -15,9 +15,6 @@ namespace content { -// TODO(drott): This should be removed once we don't need to support PPAPI -// TrueType functionality anymore, and before that, it should be replaced with -// using FreeType for the purpose instead of reimplementing table parsing. bool GetFontTable(int fd, uint32_t table_tag, off_t offset,
diff --git a/content/common/font_config_ipc_linux.cc b/content/common/font_config_ipc_linux.cc new file mode 100644 index 0000000..2596c992 --- /dev/null +++ b/content/common/font_config_ipc_linux.cc
@@ -0,0 +1,179 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/common/font_config_ipc_linux.h" + +#include <errno.h> +#include <fcntl.h> +#include <stdint.h> +#include <sys/mman.h> +#include <sys/socket.h> +#include <sys/stat.h> +#include <sys/uio.h> +#include <unistd.h> + +#include <functional> +#include <memory> +#include <utility> + +#include "base/files/file_util.h" +#include "base/files/memory_mapped_file.h" +#include "base/memory/ref_counted.h" +#include "base/pickle.h" +#include "base/posix/unix_domain_socket.h" +#include "base/threading/thread_restrictions.h" +#include "base/trace_event/trace_event.h" +#include "skia/ext/skia_utils_base.h" +#include "third_party/skia/include/core/SkData.h" +#include "third_party/skia/include/core/SkRefCnt.h" +#include "third_party/skia/include/core/SkStream.h" +#include "third_party/skia/include/core/SkTypeface.h" + +namespace content { + +std::size_t SkFontConfigInterfaceFontIdentityHash::operator()( + const SkFontConfigInterface::FontIdentity& sp) const { + std::hash<std::string> stringhash; + std::hash<int> inthash; + size_t r = inthash(sp.fID); + r = r * 41 + inthash(sp.fTTCIndex); + r = r * 41 + stringhash(sp.fString.c_str()); + r = r * 41 + inthash(sp.fStyle.weight()); + r = r * 41 + inthash(sp.fStyle.slant()); + r = r * 41 + inthash(sp.fStyle.width()); + return r; +} + +// Wikpedia's main country selection page activates 21 fallback fonts, +// doubling this we should be on the generous side as an upper bound, +// but nevertheless not have the mapped typefaces cache grow excessively. +const size_t kMaxMappedTypefaces = 42; + +void CloseFD(int fd) { + int err = IGNORE_EINTR(close(fd)); + DCHECK(!err); +} + +FontConfigIPC::FontConfigIPC(int fd) + : fd_(fd) + , mapped_typefaces_(kMaxMappedTypefaces) { +} + +FontConfigIPC::~FontConfigIPC() { + CloseFD(fd_); +} + +bool FontConfigIPC::matchFamilyName(const char familyName[], + SkFontStyle requestedStyle, + FontIdentity* outFontIdentity, + SkString* outFamilyName, + SkFontStyle* outStyle) { + TRACE_EVENT0("sandbox_ipc", "FontConfigIPC::matchFamilyName"); + size_t familyNameLen = familyName ? strlen(familyName) : 0; + if (familyNameLen > kMaxFontFamilyLength) + return false; + + base::Pickle request; + request.WriteInt(METHOD_MATCH); + request.WriteData(familyName, familyNameLen); + skia::WriteSkFontStyle(&request, requestedStyle); + + uint8_t reply_buf[2048]; + const ssize_t r = base::UnixDomainSocket::SendRecvMsg( + fd_, reply_buf, sizeof(reply_buf), nullptr, request); + if (r == -1) + return false; + + base::Pickle reply(reinterpret_cast<char*>(reply_buf), r); + base::PickleIterator iter(reply); + bool result; + if (!iter.ReadBool(&result)) + return false; + if (!result) + return false; + + SkString reply_family; + FontIdentity reply_identity; + SkFontStyle reply_style; + if (!skia::ReadSkString(&iter, &reply_family) || + !skia::ReadSkFontIdentity(&iter, &reply_identity) || + !skia::ReadSkFontStyle(&iter, &reply_style)) { + return false; + } + + if (outFontIdentity) + *outFontIdentity = reply_identity; + if (outFamilyName) + *outFamilyName = reply_family; + if (outStyle) + *outStyle = reply_style; + + return true; +} + +static void DestroyMemoryMappedFile(const void*, void* context) { + base::ThreadRestrictions::ScopedAllowIO allow_munmap; + delete static_cast<base::MemoryMappedFile*>(context); +} + +SkMemoryStream* FontConfigIPC::mapFileDescriptorToStream(int fd) { + std::unique_ptr<base::MemoryMappedFile> mapped_font_file( + new base::MemoryMappedFile); + base::ThreadRestrictions::ScopedAllowIO allow_mmap; + mapped_font_file->Initialize(base::File(fd)); + DCHECK(mapped_font_file->IsValid()); + + sk_sp<SkData> data = + SkData::MakeWithProc(mapped_font_file->data(), mapped_font_file->length(), + &DestroyMemoryMappedFile, mapped_font_file.get()); + if (!data) + return nullptr; + ignore_result(mapped_font_file.release()); // Ownership transferred to SkDataB + return new SkMemoryStream(std::move(data)); +} + +SkStreamAsset* FontConfigIPC::openStream(const FontIdentity& identity) { + TRACE_EVENT0("sandbox_ipc", "FontConfigIPC::openStream"); + + base::Pickle request; + request.WriteInt(METHOD_OPEN); + request.WriteUInt32(identity.fID); + + int result_fd = -1; + uint8_t reply_buf[256]; + const ssize_t r = base::UnixDomainSocket::SendRecvMsg( + fd_, reply_buf, sizeof(reply_buf), &result_fd, request); + if (r == -1) + return nullptr; + + base::Pickle reply(reinterpret_cast<char*>(reply_buf), r); + bool result; + base::PickleIterator iter(reply); + if (!iter.ReadBool(&result) || !result) { + if (result_fd) + CloseFD(result_fd); + return nullptr; + } + + return mapFileDescriptorToStream(result_fd); +} + +sk_sp<SkTypeface> FontConfigIPC::makeTypeface( + const SkFontConfigInterface::FontIdentity& identity) { + base::AutoLock lock(lock_); + auto mapped_typefaces_it = mapped_typefaces_.Get(identity); + if (mapped_typefaces_it != mapped_typefaces_.end()) + return mapped_typefaces_it->second; + + SkStreamAsset* typeface_stream = openStream(identity); + if (!typeface_stream) + return nullptr; + sk_sp<SkTypeface> typeface_from_stream( + SkTypeface::MakeFromStream(typeface_stream, identity.fTTCIndex)); + auto mapped_typefaces_insert_it = + mapped_typefaces_.Put(identity, std::move(typeface_from_stream)); + return mapped_typefaces_insert_it->second; +} + +} // namespace content
diff --git a/content/common/font_config_ipc_linux.h b/content/common/font_config_ipc_linux.h new file mode 100644 index 0000000..0fc85ec5 --- /dev/null +++ b/content/common/font_config_ipc_linux.h
@@ -0,0 +1,81 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_COMMON_FONT_CONFIG_IPC_LINUX_H_ +#define CONTENT_COMMON_FONT_CONFIG_IPC_LINUX_H_ + +#include "base/compiler_specific.h" +#include "base/containers/mru_cache.h" +#include "base/macros.h" +#include "base/synchronization/lock.h" +#include "third_party/skia/include/core/SkRefCnt.h" +#include "third_party/skia/include/core/SkStream.h" +#include "third_party/skia/include/core/SkTypeface.h" +#include "third_party/skia/include/ports/SkFontConfigInterface.h" + +#include <stddef.h> + +#include <string> + +class SkString; + +namespace content { + +struct SkFontConfigInterfaceFontIdentityHash { + std::size_t operator()(const SkFontConfigInterface::FontIdentity& sp) const; +}; + +// FontConfig implementation for Skia that proxies out of process to get out +// of the sandbox. See https://chromium.googlesource.com/chromium/src/+/master/docs/linux_sandbox_ipc.md +class FontConfigIPC : public SkFontConfigInterface { + public: + explicit FontConfigIPC(int fd); + ~FontConfigIPC() override; + + bool matchFamilyName(const char familyName[], + SkFontStyle requested, + FontIdentity* outFontIdentifier, + SkString* outFamilyName, + SkFontStyle* outStyle) override; + + sk_sp<SkTypeface> makeTypeface(const FontIdentity& identity) override + WARN_UNUSED_RESULT; + + enum Method { + METHOD_MATCH = 0, + METHOD_OPEN = 1, + }; + + enum { + kMaxFontFamilyLength = 2048 + }; + + private: + // Marking this private in Blink's implementation of SkFontConfigInterface + // since our caching implementation's efficacy is impaired if both + // createTypeface and openStream are used in parallel. + SkStreamAsset* openStream(const FontIdentity&) override; + + SkMemoryStream* mapFileDescriptorToStream(int fd); + + const int fd_; + // Lock preventing multiple threads from creating a typeface and removing + // an element from |mapped_typefaces_| map at the same time. + base::Lock lock_; + // Practically, this hash_map definition means that we re-map the same font + // file multiple times if we receive createTypeface requests for multiple + // ttc-indices or styles but the same fontconfig interface id. Since the usage + // frequency of ttc indices is very low, and style is not used by clients of + // this API, this seems okay. + base::HashingMRUCache<FontIdentity, + sk_sp<SkTypeface>, + SkFontConfigInterfaceFontIdentityHash> + mapped_typefaces_; + + DISALLOW_COPY_AND_ASSIGN(FontConfigIPC); +}; + +} // namespace content + +#endif // CONTENT_COMMON_FONT_CONFIG_IPC_LINUX_H_
diff --git a/content/common/service_worker/controller_service_worker.mojom b/content/common/service_worker/controller_service_worker.mojom index c8dcc1d..64684d4 100644 --- a/content/common/service_worker/controller_service_worker.mojom +++ b/content/common/service_worker/controller_service_worker.mojom
@@ -74,15 +74,3 @@ // Null if there is no controller. blink.mojom.ServiceWorkerObjectInfo? object_info; }; - -// A renderer-side interface for talking across threads. The main thread -// uses this interface to update a ControllerServiceWorkerConnector on a -// different thread with a new controller service worker. -// TODO(kinuko): Stop using mojo interface for this, we can just make -// it work via posting tasks. -interface ControllerServiceWorkerConnector { - // Resets the controller connection with the given |controller|, this - // can be called when a new controller is given, e.g. due to claim(). - // |controller| can be null if it gets no controller. - UpdateController(ControllerServiceWorker? controller); -};
diff --git a/content/ppapi_plugin/BUILD.gn b/content/ppapi_plugin/BUILD.gn index f356fcf..b34b076 100644 --- a/content/ppapi_plugin/BUILD.gn +++ b/content/ppapi_plugin/BUILD.gn
@@ -51,7 +51,6 @@ deps = [ "//base", "//components/discardable_memory/client", - "//components/services/font/public/cpp:cpp", "//content:export", "//content/child", "//content/public/child:child_sources",
diff --git a/content/ppapi_plugin/ppapi_blink_platform_impl.cc b/content/ppapi_plugin/ppapi_blink_platform_impl.cc index 6813855..9e0474e 100644 --- a/content/ppapi_plugin/ppapi_blink_platform_impl.cc +++ b/content/ppapi_plugin/ppapi_blink_platform_impl.cc
@@ -40,15 +40,11 @@ class PpapiBlinkPlatformImpl::SandboxSupport : public WebSandboxSupport { public: -#if defined(OS_LINUX) - explicit SandboxSupport(sk_sp<font_service::FontLoader> font_loader) - : font_loader_(std::move(font_loader)) {} -#endif ~SandboxSupport() override {} #if defined(OS_MACOSX) bool LoadFont(CTFontRef srcFont, CGFontRef* out, uint32_t* fontID) override; -#elif defined(OS_LINUX) +#elif defined(OS_POSIX) SandboxSupport(); void GetFallbackFontForCharacter( WebUChar32 character, @@ -68,7 +64,6 @@ std::map<int32_t, blink::WebFallbackFont> unicode_font_families_; // For debugging crbug.com/312965 base::PlatformThreadId creation_thread_; - sk_sp<font_service::FontLoader> font_loader_; #endif }; @@ -110,8 +105,8 @@ return; } - content::GetFallbackFontForCharacter(font_loader_, character, - preferred_locale, fallbackFont); + content::GetFallbackFontForCharacter(character, preferred_locale, + fallbackFont); unicode_font_families_.insert(std::make_pair(character, *fallbackFont)); } @@ -122,8 +117,8 @@ bool is_italic, float device_scale_factor, blink::WebFontRenderStyle* out) { - GetRenderStyleForStrike(font_loader_, family, size, is_bold, is_italic, - device_scale_factor, out); + GetRenderStyleForStrike(family, size, is_bold, is_italic, device_scale_factor, + out); } #endif @@ -131,14 +126,8 @@ #endif // !defined(OS_ANDROID) && !defined(OS_WIN) PpapiBlinkPlatformImpl::PpapiBlinkPlatformImpl() { -#if defined(OS_LINUX) && !defined(OS_ANDROID) - font_loader_ = - sk_make_sp<font_service::FontLoader>(ChildThread::Get()->GetConnector()); - SkFontConfigInterface::SetGlobal(font_loader_); - sandbox_support_.reset( - new PpapiBlinkPlatformImpl::SandboxSupport(font_loader_)); -#elif defined(OS_MACOSX) - sandbox_support_.reset(new PpapiBlinkPlatformImpl::SandboxSupport()); +#if !defined(OS_ANDROID) && !defined(OS_WIN) + sandbox_support_.reset(new PpapiBlinkPlatformImpl::SandboxSupport); #endif }
diff --git a/content/ppapi_plugin/ppapi_blink_platform_impl.h b/content/ppapi_plugin/ppapi_blink_platform_impl.h index aea9579..d38cfcf 100644 --- a/content/ppapi_plugin/ppapi_blink_platform_impl.h +++ b/content/ppapi_plugin/ppapi_blink_platform_impl.h
@@ -13,11 +13,6 @@ #include "build/build_config.h" #include "content/child/blink_platform_impl.h" -#if defined(OS_LINUX) -#include "components/services/font/public/cpp/font_loader.h" -#include "third_party/skia/include/core/SkRefCnt.h" -#endif - namespace content { class PpapiBlinkPlatformImpl : public BlinkPlatformImpl { @@ -58,10 +53,6 @@ std::unique_ptr<SandboxSupport> sandbox_support_; #endif -#if defined(OS_LINUX) - sk_sp<font_service::FontLoader> font_loader_; -#endif - DISALLOW_COPY_AND_ASSIGN(PpapiBlinkPlatformImpl); };
diff --git a/content/public/app/BUILD.gn b/content/public/app/BUILD.gn index 28d5f8d..e5518f5 100644 --- a/content/public/app/BUILD.gn +++ b/content/public/app/BUILD.gn
@@ -197,10 +197,6 @@ "//services/video_capture:manifest", "//services/viz:manifest", ] - - if (is_linux && !is_android) { - packaged_services += [ "//components/services/font:manifest" ] - } } service_manifest("browser_manifest") {
diff --git a/content/public/app/mojo/content_plugin_manifest.json b/content/public/app/mojo/content_plugin_manifest.json index c00ea402..44c6d2ba 100644 --- a/content/public/app/mojo/content_plugin_manifest.json +++ b/content/public/app/mojo/content_plugin_manifest.json
@@ -25,7 +25,6 @@ "plugin" ], "device": [ "device:power_monitor" ], - "font_service": [ "font_service" ], "ui": [ "discardable_memory" ] } }
diff --git a/content/public/app/mojo/content_renderer_manifest.json b/content/public/app/mojo/content_renderer_manifest.json index 70c67820..71bc81d 100644 --- a/content/public/app/mojo/content_renderer_manifest.json +++ b/content/public/app/mojo/content_renderer_manifest.json
@@ -33,7 +33,6 @@ "font_loader", "renderer" ], - "font_service": [ "font_service" ], "metrics": [ "url_keyed_metrics" ], "device": [ "device:power_monitor",
diff --git a/content/public/app/mojo/content_utility_manifest.json b/content/public/app/mojo/content_utility_manifest.json index 2c4dcb1..563c885 100644 --- a/content/public/app/mojo/content_utility_manifest.json +++ b/content/public/app/mojo/content_utility_manifest.json
@@ -29,8 +29,7 @@ "device": [ "device:power_monitor", "device:time_zone_monitor" - ], - "font_service": [ "font_service" ] + ] } } },
diff --git a/content/public/child/BUILD.gn b/content/public/child/BUILD.gn index c7f6f6a..296eca9 100644 --- a/content/public/child/BUILD.gn +++ b/content/public/child/BUILD.gn
@@ -29,6 +29,7 @@ visibility = [ "//content/*" ] sources = [ + "child_process_sandbox_support_linux.h", "child_thread.h", "dwrite_font_proxy_init_win.h", "image_decoder_utils.h",
diff --git a/content/public/child/child_process_sandbox_support_linux.h b/content/public/child/child_process_sandbox_support_linux.h new file mode 100644 index 0000000..5f0577c --- /dev/null +++ b/content/public/child/child_process_sandbox_support_linux.h
@@ -0,0 +1,33 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_PUBLIC_CHILD_CHILD_PROCESS_SANDBOX_SUPPORT_LINUX_H_ +#define CONTENT_PUBLIC_CHILD_CHILD_PROCESS_SANDBOX_SUPPORT_LINUX_H_ + +#include <stddef.h> +#include <stdint.h> +#include <string> + +#include "content/common/content_export.h" +#include "ppapi/c/trusted/ppb_browser_font_trusted.h" + +namespace content { + +// Return a read-only file descriptor to the font which best matches the given +// properties or -1 on failure. +// charset: specifies the language(s) that the font must cover. See +// render_sandbox_host_linux.cc for more information. +// fallback_family: If not set to PP_BROWSERFONT_TRUSTED_FAMILY_DEFAULT, font +// selection should fall back to generic Windows font names like Arial and +// Times New Roman. +CONTENT_EXPORT int MatchFontWithFallback( + const std::string& face, + bool bold, + bool italic, + int charset, + PP_BrowserFont_Trusted_Family fallback_family); + +}; // namespace content + +#endif // CONTENT_PUBLIC_CHILD_CHILD_PROCESS_SANDBOX_SUPPORT_LINUX_H_
diff --git a/content/public/common/web_preferences.cc b/content/public/common/web_preferences.cc index 8ecb838..8378aef 100644 --- a/content/public/common/web_preferences.cc +++ b/content/public/common/web_preferences.cc
@@ -236,7 +236,7 @@ do_not_update_selection_on_mutating_selection_range(false), autoplay_policy(AutoplayPolicy::kDocumentUserActivationRequired), low_priority_iframes_threshold(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN), - picture_in_picture_enabled(false) { + picture_in_picture_enabled(true) { standard_font_family_map[kCommonScript] = base::ASCIIToUTF16("Times New Roman"); fixed_font_family_map[kCommonScript] = base::ASCIIToUTF16("Courier New");
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index aaa4a9c..057683b 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn
@@ -401,6 +401,8 @@ "media/webrtc/rtc_rtp_receiver.h", "media/webrtc/rtc_rtp_sender.cc", "media/webrtc/rtc_rtp_sender.h", + "media/webrtc/rtc_rtp_transceiver.cc", + "media/webrtc/rtc_rtp_transceiver.h", "media/webrtc/rtc_stats.cc", "media/webrtc/rtc_stats.h", "media/webrtc/rtc_video_decoder.cc", @@ -415,6 +417,8 @@ "media/webrtc/stun_field_trial.h", "media/webrtc/track_observer.cc", "media/webrtc/track_observer.h", + "media/webrtc/transceiver_state_surfacer.cc", + "media/webrtc/transceiver_state_surfacer.h", "media/webrtc/two_keys_adapter_map.h", "media/webrtc/webrtc_audio_device_impl.cc", "media/webrtc/webrtc_audio_device_impl.h", @@ -436,6 +440,7 @@ "media/webrtc/webrtc_set_remote_description_observer.h", "media/webrtc/webrtc_uma_histograms.cc", "media/webrtc/webrtc_uma_histograms.h", + "media/webrtc/webrtc_util.h", "media/webrtc/webrtc_video_capturer_adapter.cc", "media/webrtc/webrtc_video_capturer_adapter.h", "media/webrtc/webrtc_video_frame_adapter.cc", @@ -722,6 +727,7 @@ "//third_party/opus", "//third_party/webrtc/api:libjingle_logging_api", "//third_party/webrtc/api:libjingle_peerconnection_api", + "//third_party/webrtc/api:optional", "//third_party/webrtc/api:rtc_stats_api", "//third_party/webrtc/api/audio:aec3_factory", "//third_party/webrtc/api/audio_codecs:audio_codecs_api", @@ -1018,16 +1024,6 @@ deps += [ "//sandbox:sandbox_buildflags" ] } - if (is_linux && !is_android) { - deps += [ - "//components/services/font:lib", - "//components/services/font/public/cpp", - ] - data_deps = [ - "//components/services/font:font_service", - ] - } - if (use_ozone) { deps += [ "//ui/ozone" ] }
diff --git a/content/renderer/gpu/render_widget_compositor.cc b/content/renderer/gpu/render_widget_compositor.cc index 6ae8f6f..aa95d79 100644 --- a/content/renderer/gpu/render_widget_compositor.cc +++ b/content/renderer/gpu/render_widget_compositor.cc
@@ -185,27 +185,32 @@ RenderWidgetCompositor::RenderWidgetCompositor( RenderWidgetCompositorDelegate* delegate, - CompositorDependencies* compositor_deps) + scoped_refptr<base::SingleThreadTaskRunner> main_thread, + scoped_refptr<base::SingleThreadTaskRunner> compositor_thread, + cc::TaskGraphRunner* task_graph_runner, + blink::scheduler::WebThreadScheduler* scheduler) : delegate_(delegate), - compositor_deps_(compositor_deps), - threaded_(!!compositor_deps_->GetCompositorImplThreadTaskRunner()), + main_thread_(std::move(main_thread)), + compositor_thread_(std::move(compositor_thread)), + task_graph_runner_(task_graph_runner), + web_main_thread_scheduler_(scheduler), animation_host_(cc::AnimationHost::CreateMainInstance()), weak_factory_(this) {} RenderWidgetCompositor::~RenderWidgetCompositor() = default; -void RenderWidgetCompositor::Initialize(const cc::LayerTreeSettings& settings) { - const bool is_threaded = - !!compositor_deps_->GetCompositorImplThreadTaskRunner(); +void RenderWidgetCompositor::Initialize( + const cc::LayerTreeSettings& settings, + std::unique_ptr<cc::UkmRecorderFactory> ukm_recorder_factory) { + const bool is_threaded = !!compositor_thread_; cc::LayerTreeHost::InitParams params; params.client = this; params.settings = &settings; - params.task_graph_runner = compositor_deps_->GetTaskGraphRunner(); - params.main_task_runner = - compositor_deps_->GetCompositorMainThreadTaskRunner(); + params.task_graph_runner = task_graph_runner_; + params.main_task_runner = main_thread_; params.mutator_host = animation_host_.get(); - params.ukm_recorder_factory = compositor_deps_->CreateUkmRecorderFactory(); + params.ukm_recorder_factory = std::move(ukm_recorder_factory); if (base::TaskScheduler::GetInstance()) { // The image worker thread needs to allow waiting since it makes discardable // shared memory allocations which need to make synchronous calls to the @@ -215,11 +220,11 @@ base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}); } if (!is_threaded) { - // Single-threaded layout tests. + // Single-threaded layout tests, and unit tests. layer_tree_host_ = cc::LayerTreeHost::CreateSingleThreaded(this, ¶ms); } else { - layer_tree_host_ = cc::LayerTreeHost::CreateThreaded( - compositor_deps_->GetCompositorImplThreadTaskRunner(), ¶ms); + layer_tree_host_ = + cc::LayerTreeHost::CreateThreaded(compositor_thread_, ¶ms); } } @@ -477,7 +482,7 @@ } bool RenderWidgetCompositor::CompositeIsSynchronous() const { - if (!threaded_) { + if (!compositor_thread_) { DCHECK(!layer_tree_host_->GetSettings().single_thread_proxy_scheduler); return true; } @@ -682,18 +687,17 @@ void RenderWidgetCompositor::DidBeginMainFrame() {} void RenderWidgetCompositor::BeginMainFrame(const viz::BeginFrameArgs& args) { - compositor_deps_->GetWebMainThreadScheduler()->WillBeginFrame(args); + web_main_thread_scheduler_->WillBeginFrame(args); delegate_->BeginMainFrame(args.frame_time); } void RenderWidgetCompositor::BeginMainFrameNotExpectedSoon() { - compositor_deps_->GetWebMainThreadScheduler()->BeginFrameNotExpectedSoon(); + web_main_thread_scheduler_->BeginFrameNotExpectedSoon(); } void RenderWidgetCompositor::BeginMainFrameNotExpectedUntil( base::TimeTicks time) { - compositor_deps_->GetWebMainThreadScheduler()->BeginMainFrameNotExpectedUntil( - time); + web_main_thread_scheduler_->BeginMainFrameNotExpectedUntil(time); } void RenderWidgetCompositor::UpdateLayerTreeHost( @@ -751,7 +755,7 @@ void RenderWidgetCompositor::DidCommit() { delegate_->DidCommitCompositorFrame(); - compositor_deps_->GetWebMainThreadScheduler()->DidCommitFrameToCompositor(); + web_main_thread_scheduler_->DidCommitFrameToCompositor(); } void RenderWidgetCompositor::DidCommitAndDrawFrame() { @@ -819,6 +823,11 @@ layer_tree_host_->RequestBeginMainFrameNotExpected(new_state); } +const cc::LayerTreeSettings& RenderWidgetCompositor::GetLayerTreeSettings() + const { + return layer_tree_host_->GetSettings(); +} + void RenderWidgetCompositor::SetRenderFrameObserver( std::unique_ptr<cc::RenderFrameMetadataObserver> observer) { layer_tree_host_->SetRenderFrameObserver(std::move(observer));
diff --git a/content/renderer/gpu/render_widget_compositor.h b/content/renderer/gpu/render_widget_compositor.h index 45e430f..4cfa450 100644 --- a/content/renderer/gpu/render_widget_compositor.h +++ b/content/renderer/gpu/render_widget_compositor.h
@@ -10,19 +10,26 @@ #include "base/callback.h" #include "base/containers/circular_deque.h" #include "base/memory/weak_ptr.h" +#include "base/single_thread_task_runner.h" #include "base/time/time.h" #include "base/values.h" #include "cc/input/browser_controls_state.h" -#include "cc/trees/layer_tree_host.h" #include "cc/trees/layer_tree_host_client.h" #include "cc/trees/layer_tree_host_single_thread_client.h" #include "cc/trees/swap_promise.h" #include "cc/trees/swap_promise_monitor.h" #include "content/common/content_export.h" -#include "content/renderer/gpu/compositor_dependencies.h" #include "third_party/blink/public/platform/web_layer_tree_view.h" #include "ui/gfx/geometry/rect.h" +class GURL; + +namespace blink { +namespace scheduler { +class WebThreadScheduler; +} +} // namespace blink + namespace cc { class AnimationHost; class InputHandler; @@ -31,6 +38,8 @@ class LayerTreeHost; class LayerTreeSettings; class RenderFrameMetadataObserver; +class TaskGraphRunner; +class UkmRecorderFactory; } namespace gfx { @@ -49,11 +58,22 @@ public cc::LayerTreeHostClient, public cc::LayerTreeHostSingleThreadClient { public: - RenderWidgetCompositor(RenderWidgetCompositorDelegate* delegate, - CompositorDependencies* compositor_deps); + // The |main_thread| is the task runner that the compositor will use for the + // main thread (where it is constructed). The |compositor_thread| is the task + // runner for the compositor thread, but is null if the compositor will run in + // single-threaded mode (in tests only). + RenderWidgetCompositor( + RenderWidgetCompositorDelegate* delegate, + scoped_refptr<base::SingleThreadTaskRunner> main_thread, + scoped_refptr<base::SingleThreadTaskRunner> compositor_thread, + cc::TaskGraphRunner* task_graph_runner, + blink::scheduler::WebThreadScheduler* scheduler); ~RenderWidgetCompositor() override; - void Initialize(const cc::LayerTreeSettings& settings); + // The |ukm_recorder_factory| may be null to disable recording (in tests + // only). + void Initialize(const cc::LayerTreeSettings& settings, + std::unique_ptr<cc::UkmRecorderFactory> ukm_recorder_factory); void SetNeverVisible(); const base::WeakPtr<cc::InputHandler>& GetInputHandler(); @@ -188,9 +208,7 @@ void DidLoseLayerTreeFrameSink() override; void RequestBeginMainFrameNotExpected(bool new_state) override; - const cc::LayerTreeSettings& GetLayerTreeSettings() const { - return layer_tree_host_->GetSettings(); - } + const cc::LayerTreeSettings& GetLayerTreeSettings() const; // Sets the RenderFrameMetadataObserver, which is sent to the compositor // thread for binding. @@ -215,9 +233,11 @@ std::unique_ptr<cc::SwapPromise> swap_promise); RenderWidgetCompositorDelegate* const delegate_; - CompositorDependencies* const compositor_deps_; - const bool threaded_; - std::unique_ptr<cc::AnimationHost> animation_host_; + const scoped_refptr<base::SingleThreadTaskRunner> main_thread_; + const scoped_refptr<base::SingleThreadTaskRunner> compositor_thread_; + cc::TaskGraphRunner* const task_graph_runner_; + blink::scheduler::WebThreadScheduler* const web_main_thread_scheduler_; + const std::unique_ptr<cc::AnimationHost> animation_host_; std::unique_ptr<cc::LayerTreeHost> layer_tree_host_; bool never_visible_ = false;
diff --git a/content/renderer/gpu/render_widget_compositor_unittest.cc b/content/renderer/gpu/render_widget_compositor_unittest.cc index 43b49e2..9d7e80b 100644 --- a/content/renderer/gpu/render_widget_compositor_unittest.cc +++ b/content/renderer/gpu/render_widget_compositor_unittest.cc
@@ -13,8 +13,9 @@ #include "base/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" -#include "cc/animation/animation_host.h" #include "cc/test/fake_layer_tree_frame_sink.h" +#include "cc/test/test_task_graph_runner.h" +#include "cc/test/test_ukm_recorder_factory.h" #include "cc/trees/layer_tree_host.h" #include "components/viz/common/frame_sinks/copy_output_request.h" #include "components/viz/test/test_context_provider.h" @@ -26,6 +27,7 @@ #include "gpu/GLES2/gl2extchromium.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/platform/scheduler/test/fake_renderer_scheduler.h" #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h" using testing::AllOf; @@ -121,13 +123,19 @@ // the compositor (couldn't bind the output surface) are handled identically. class RenderWidgetLayerTreeFrameSink : public RenderWidgetCompositor { public: - RenderWidgetLayerTreeFrameSink(FakeRenderWidgetCompositorDelegate* delegate, - CompositorDependencies* compositor_deps) - : RenderWidgetCompositor(delegate, compositor_deps), + RenderWidgetLayerTreeFrameSink( + FakeRenderWidgetCompositorDelegate* delegate, + scoped_refptr<base::SingleThreadTaskRunner> main_thread, + scoped_refptr<base::SingleThreadTaskRunner> compositor_thread, + cc::TaskGraphRunner* task_graph_runner, + blink::scheduler::WebThreadScheduler* scheduler) + : RenderWidgetCompositor(delegate, + std::move(main_thread), + std::move(compositor_thread), + task_graph_runner, + scheduler), delegate_(delegate) {} - using RenderWidgetCompositor::Initialize; - // Force a new output surface to be created. void SynchronousComposite() { layer_tree_host()->SetVisible(false); @@ -202,13 +210,16 @@ class RenderWidgetLayerTreeFrameSinkTest : public testing::Test { public: RenderWidgetLayerTreeFrameSinkTest() - : render_widget_compositor_(&compositor_delegate_, &compositor_deps_) { - auto animation_host = cc::AnimationHost::CreateMainInstance(); - - ScreenInfo dummy_screen_info; + : render_widget_compositor_( + &compositor_delegate_, + blink::scheduler::GetSingleThreadTaskRunnerForTesting(), + /*compositor_thread=*/nullptr, + &test_task_graph_runner_, + &fake_renderer_scheduler_) { cc::LayerTreeSettings settings; settings.single_thread_proxy_scheduler = false; - render_widget_compositor_.Initialize(settings); + render_widget_compositor_.Initialize( + settings, std::make_unique<cc::TestUkmRecorderFactory>()); } void RunTest(int expected_successes, FailureMode failure_mode) { @@ -248,7 +259,8 @@ protected: base::MessageLoop ye_olde_message_loope_; MockRenderThread render_thread_; - FakeCompositorDependencies compositor_deps_; + cc::TestTaskGraphRunner test_task_graph_runner_; + blink::scheduler::FakeRendererScheduler fake_renderer_scheduler_; FakeRenderWidgetCompositorDelegate compositor_delegate_; RenderWidgetLayerTreeFrameSink render_widget_compositor_; @@ -292,8 +304,15 @@ public: VisibilityTestRenderWidgetCompositor( StubRenderWidgetCompositorDelegate* delegate, - CompositorDependencies* compositor_deps) - : RenderWidgetCompositor(delegate, compositor_deps) {} + scoped_refptr<base::SingleThreadTaskRunner> main_thread, + scoped_refptr<base::SingleThreadTaskRunner> compositor_thread, + cc::TaskGraphRunner* task_graph_runner, + blink::scheduler::WebThreadScheduler* scheduler) + : RenderWidgetCompositor(delegate, + std::move(main_thread), + std::move(compositor_thread), + task_graph_runner, + scheduler) {} void RequestNewLayerTreeFrameSink() override { RenderWidgetCompositor::RequestNewLayerTreeFrameSink(); @@ -316,15 +335,18 @@ base::MessageLoop message_loop; - FakeCompositorDependencies compositor_deps; + cc::TestTaskGraphRunner test_task_graph_runner; + blink::scheduler::FakeRendererScheduler fake_renderer_scheduler; // Synchronously callback with null FrameSink. StubRenderWidgetCompositorDelegate compositor_delegate; VisibilityTestRenderWidgetCompositor render_widget_compositor( - &compositor_delegate, &compositor_deps); + &compositor_delegate, + blink::scheduler::GetSingleThreadTaskRunnerForTesting(), + /*compositor_thread=*/nullptr, &test_task_graph_runner, + &fake_renderer_scheduler); - auto animation_host = cc::AnimationHost::CreateMainInstance(); - ScreenInfo dummy_screen_info; - render_widget_compositor.Initialize(cc::LayerTreeSettings()); + render_widget_compositor.Initialize( + cc::LayerTreeSettings(), std::make_unique<cc::TestUkmRecorderFactory>()); { // Make one request and stop immediately while invisible.
diff --git a/content/renderer/media/media_factory.cc b/content/renderer/media/media_factory.cc index e0707810..60d25bd 100644 --- a/content/renderer/media/media_factory.cc +++ b/content/renderer/media/media_factory.cc
@@ -136,16 +136,25 @@ std::move(set_context_provider_callback))); } -// Whether videos should use SurfaceLayers. -bool VideoSurfaceLayerEnabled() { - return base::FeatureList::IsEnabled(media::kUseSurfaceLayerForVideo) && - features::IsAshInBrowserProcess(); -} - } // namespace namespace content { +// static +bool MediaFactory::VideoSurfaceLayerEnabled() { + // LayoutTests do not support SurfaceLayer by default at the moment. + // See https://crbug.com/838128 + content::RenderThreadImpl* render_thread = + content::RenderThreadImpl::current(); + if (render_thread && render_thread->layout_test_mode() && + !render_thread->LayoutTestModeUsesDisplayCompositorPixelDump()) { + return false; + } + + return base::FeatureList::IsEnabled(media::kUseSurfaceLayerForVideo) && + features::IsAshInBrowserProcess(); +} + MediaFactory::MediaFactory( RenderFrameImpl* render_frame, media::RequestRoutingTokenCallback request_routing_token_cb)
diff --git a/content/renderer/media/media_factory.h b/content/renderer/media/media_factory.h index 1d5aeece..77187b2 100644 --- a/content/renderer/media/media_factory.h +++ b/content/renderer/media/media_factory.h
@@ -72,6 +72,9 @@ // Assist to RenderFrameImpl in creating various media clients. class MediaFactory { public: + // Helper function returning whether VideoSurfaceLayer should be enabled. + static bool VideoSurfaceLayerEnabled(); + // Create a MediaFactory to assist the |render_frame| with media tasks. // |request_routing_token_cb| bound to |render_frame| IPC functions for // obtaining overlay tokens.
diff --git a/content/renderer/media/webrtc/mock_peer_connection_impl.cc b/content/renderer/media/webrtc/mock_peer_connection_impl.cc index 28b9294..3e92c50 100644 --- a/content/renderer/media/webrtc/mock_peer_connection_impl.cc +++ b/content/renderer/media/webrtc/mock_peer_connection_impl.cc
@@ -9,6 +9,7 @@ #include <vector> #include "base/logging.h" +#include "base/stl_util.h" #include "content/renderer/media/webrtc/mock_data_channel_impl.h" #include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h" #include "third_party/webrtc/api/rtpreceiverinterface.h" @@ -58,19 +59,6 @@ } return nullptr; } - std::vector<webrtc::MediaStreamInterface*> FindStreamsOfTrack( - webrtc::MediaStreamTrackInterface* track) { - std::vector<webrtc::MediaStreamInterface*> streams_of_track; - if (!track) - return streams_of_track; - for (size_t i = 0; i < streams_.size(); ++i) { - if (streams_.at(i)->FindAudioTrack(track->id()) || - streams_.at(i)->FindVideoTrack(track->id())) { - streams_of_track.push_back(streams_.at(i)); - } - } - return streams_of_track; - } void AddStream(MediaStreamInterface* stream) { streams_.push_back(stream); } @@ -120,8 +108,9 @@ }; FakeRtpSender::FakeRtpSender( - rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track) - : track_(std::move(track)) {} + rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track, + std::vector<std::string> stream_ids) + : track_(std::move(track)), stream_ids_(std::move(stream_ids)) {} FakeRtpSender::~FakeRtpSender() {} @@ -151,8 +140,7 @@ } std::vector<std::string> FakeRtpSender::stream_ids() const { - NOTIMPLEMENTED(); - return {}; + return stream_ids_; } webrtc::RtpParameters FakeRtpSender::GetParameters() { @@ -218,6 +206,61 @@ return std::vector<webrtc::RtpSource>(); } +FakeRtpTransceiver::FakeRtpTransceiver( + cricket::MediaType media_type, + rtc::scoped_refptr<webrtc::RtpSenderInterface> sender, + rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver) + : media_type_(media_type), + sender_(std::move(sender)), + receiver_(std::move(receiver)) {} + +FakeRtpTransceiver::~FakeRtpTransceiver() {} + +cricket::MediaType FakeRtpTransceiver::media_type() const { + return media_type_; +} + +rtc::Optional<std::string> FakeRtpTransceiver::mid() const { + return rtc::nullopt; +} + +rtc::scoped_refptr<webrtc::RtpSenderInterface> FakeRtpTransceiver::sender() + const { + return sender_; +} + +rtc::scoped_refptr<webrtc::RtpReceiverInterface> FakeRtpTransceiver::receiver() + const { + return receiver_; +} + +bool FakeRtpTransceiver::stopped() const { + return false; +} + +webrtc::RtpTransceiverDirection FakeRtpTransceiver::direction() const { + return webrtc::RtpTransceiverDirection::kSendRecv; +} + +void FakeRtpTransceiver::SetDirection( + webrtc::RtpTransceiverDirection new_direction) { + NOTIMPLEMENTED(); +} + +rtc::Optional<webrtc::RtpTransceiverDirection> +FakeRtpTransceiver::current_direction() const { + return rtc::nullopt; +} + +void FakeRtpTransceiver::Stop() { + NOTIMPLEMENTED(); +} + +void FakeRtpTransceiver::SetCodecPreferences( + rtc::ArrayView<webrtc::RtpCodecCapability> codecs) { + NOTIMPLEMENTED(); +} + const char MockPeerConnectionImpl::kDummyOffer[] = "dummy offer"; const char MockPeerConnectionImpl::kDummyAnswer[] = "dummy answer"; @@ -225,7 +268,6 @@ MockPeerConnectionDependencyFactory* factory, webrtc::PeerConnectionObserver* observer) : dependency_factory_(factory), - local_streams_(new rtc::RefCountedObject<MockStreamCollection>), remote_streams_(new rtc::RefCountedObject<MockStreamCollection>), hint_audio_(false), hint_video_(false), @@ -249,63 +291,40 @@ MockPeerConnectionImpl::~MockPeerConnectionImpl() {} -rtc::scoped_refptr<webrtc::StreamCollectionInterface> -MockPeerConnectionImpl::local_streams() { - return local_streams_; -} - -rtc::scoped_refptr<webrtc::StreamCollectionInterface> -MockPeerConnectionImpl::remote_streams() { - return remote_streams_; -} - -rtc::scoped_refptr<webrtc::RtpSenderInterface> MockPeerConnectionImpl::AddTrack( - webrtc::MediaStreamTrackInterface* track, - std::vector<webrtc::MediaStreamInterface*> streams) { +webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpSenderInterface>> +MockPeerConnectionImpl::AddTrack( + rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track, + const std::vector<std::string>& stream_ids) { DCHECK(track); - DCHECK_EQ(1u, streams.size()); + DCHECK_EQ(1u, stream_ids.size()); for (const auto& sender : senders_) { if (sender->track() == track) - return nullptr; + return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER); } - for (auto* stream : streams) { - if (!local_streams_->find(stream->id())) { - stream_label_ = stream->id(); - local_streams_->AddStream(stream); + for (const auto& stream_id : stream_ids) { + if (!base::ContainsValue(local_stream_ids_, stream_id)) { + stream_label_ = stream_id; + local_stream_ids_.push_back(stream_id); } } - auto* sender = new rtc::RefCountedObject<FakeRtpSender>(track); + auto* sender = new rtc::RefCountedObject<FakeRtpSender>(track, stream_ids); senders_.push_back(sender); - return sender; + return rtc::scoped_refptr<webrtc::RtpSenderInterface>(sender); } -bool MockPeerConnectionImpl::RemoveTrack(webrtc::RtpSenderInterface* sender) { - auto it = std::find(senders_.begin(), senders_.end(), - static_cast<FakeRtpSender*>(sender)); +bool MockPeerConnectionImpl::RemoveTrack(webrtc::RtpSenderInterface* s) { + rtc::scoped_refptr<FakeRtpSender> sender = static_cast<FakeRtpSender*>(s); + auto it = std::find(senders_.begin(), senders_.end(), sender); if (it == senders_.end()) return false; senders_.erase(it); auto track = sender->track(); - for (auto* stream : local_streams_->FindStreamsOfTrack(track)) { - bool stream_has_senders = false; - for (const auto& track : stream->GetAudioTracks()) { - for (const auto& sender : senders_) { - if (sender->track() == track) { - stream_has_senders = true; - break; - } - } - } - for (const auto& track : stream->GetVideoTracks()) { - for (const auto& sender : senders_) { - if (sender->track() == track) { - stream_has_senders = true; - break; - } - } - } - if (!stream_has_senders) - local_streams_->RemoveStream(stream); + + for (const auto& stream_id : sender->stream_ids()) { + auto local_stream_it = std::find(local_stream_ids_.begin(), + local_stream_ids_.end(), stream_id); + if (local_stream_it != local_stream_ids_.end()) + local_stream_ids_.erase(local_stream_it); } return true; }
diff --git a/content/renderer/media/webrtc/mock_peer_connection_impl.h b/content/renderer/media/webrtc/mock_peer_connection_impl.h index 6905b97..fb8c0aa 100644 --- a/content/renderer/media/webrtc/mock_peer_connection_impl.h +++ b/content/renderer/media/webrtc/mock_peer_connection_impl.h
@@ -22,7 +22,8 @@ class FakeRtpSender : public webrtc::RtpSenderInterface { public: - FakeRtpSender(rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track); + FakeRtpSender(rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track, + std::vector<std::string> stream_ids); ~FakeRtpSender() override; bool SetTrack(webrtc::MediaStreamTrackInterface* track) override; @@ -39,6 +40,7 @@ private: rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track_; + std::vector<std::string> stream_ids_; }; class FakeRtpReceiver : public webrtc::RtpReceiverInterface { @@ -63,6 +65,32 @@ std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>> streams_; }; +class FakeRtpTransceiver : public webrtc::RtpTransceiverInterface { + public: + FakeRtpTransceiver(cricket::MediaType media_type, + rtc::scoped_refptr<webrtc::RtpSenderInterface> sender, + rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver); + ~FakeRtpTransceiver() override; + + cricket::MediaType media_type() const override; + rtc::Optional<std::string> mid() const override; + rtc::scoped_refptr<webrtc::RtpSenderInterface> sender() const override; + rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver() const override; + bool stopped() const override; + webrtc::RtpTransceiverDirection direction() const override; + void SetDirection(webrtc::RtpTransceiverDirection new_direction) override; + rtc::Optional<webrtc::RtpTransceiverDirection> current_direction() + const override; + void Stop() override; + void SetCodecPreferences( + rtc::ArrayView<webrtc::RtpCodecCapability> codecs) override; + + private: + cricket::MediaType media_type_; + rtc::scoped_refptr<webrtc::RtpSenderInterface> sender_; + rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver_; +}; + // TODO(hbos): The use of fakes and mocks is the wrong approach for testing of // this. It introduces complexity, is error prone (not testing the right thing // and bugs in the mocks). This class is a maintenance burden and should be @@ -73,10 +101,16 @@ webrtc::PeerConnectionObserver* observer); // PeerConnectionInterface implementation. - rtc::scoped_refptr<webrtc::StreamCollectionInterface> - local_streams() override; - rtc::scoped_refptr<webrtc::StreamCollectionInterface> - remote_streams() override; + rtc::scoped_refptr<webrtc::StreamCollectionInterface> local_streams() + override { + NOTIMPLEMENTED(); + return nullptr; + } + rtc::scoped_refptr<webrtc::StreamCollectionInterface> remote_streams() + override { + NOTIMPLEMENTED(); + return nullptr; + } bool AddStream(webrtc::MediaStreamInterface* local_stream) override { NOTIMPLEMENTED(); return false; @@ -84,11 +118,9 @@ void RemoveStream(webrtc::MediaStreamInterface* local_stream) override { NOTIMPLEMENTED(); } - // TODO(hbos): Use AddTrack() taking stream labels instead of stream pointers. - // https://crbug.com/810708 - rtc::scoped_refptr<webrtc::RtpSenderInterface> AddTrack( - webrtc::MediaStreamTrackInterface* track, - std::vector<webrtc::MediaStreamInterface*> streams) override; + webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpSenderInterface>> AddTrack( + rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track, + const std::vector<std::string>& stream_ids) override; bool RemoveTrack(webrtc::RtpSenderInterface* sender) override; std::vector<rtc::scoped_refptr<webrtc::RtpSenderInterface>> GetSenders() const override; @@ -205,7 +237,7 @@ MockPeerConnectionDependencyFactory* dependency_factory_; std::string stream_label_; - rtc::scoped_refptr<MockStreamCollection> local_streams_; + std::vector<std::string> local_stream_ids_; rtc::scoped_refptr<MockStreamCollection> remote_streams_; std::vector<rtc::scoped_refptr<FakeRtpSender>> senders_; std::unique_ptr<webrtc::SessionDescriptionInterface> local_desc_;
diff --git a/content/renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.cc b/content/renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.cc index 6d8afca2..6c0fcf6 100644 --- a/content/renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.cc +++ b/content/renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.cc
@@ -20,14 +20,13 @@ .WillByDefault( testing::Invoke(this, &MockWebRTCPeerConnectionHandlerClient:: didGenerateICECandidateWorker)); - ON_CALL(*this, DidAddRemoteTrackForMock(_)) + ON_CALL(*this, DidAddReceiverForMock(_)) + .WillByDefault(testing::Invoke( + this, &MockWebRTCPeerConnectionHandlerClient::didAddReceiverWorker)); + ON_CALL(*this, DidRemoveReceiverForMock(_)) .WillByDefault(testing::Invoke( this, - &MockWebRTCPeerConnectionHandlerClient::didAddRemoteTrackWorker)); - ON_CALL(*this, DidRemoveRemoteTrackForMock(_)) - .WillByDefault(testing::Invoke( - this, - &MockWebRTCPeerConnectionHandlerClient::didRemoveRemoteTrackWorker)); + &MockWebRTCPeerConnectionHandlerClient::didRemoveReceiverWorker)); } MockWebRTCPeerConnectionHandlerClient:: @@ -40,17 +39,17 @@ candidate_mid_ = candidate->SdpMid().Utf8(); } -void MockWebRTCPeerConnectionHandlerClient::didAddRemoteTrackWorker( +void MockWebRTCPeerConnectionHandlerClient::didAddReceiverWorker( std::unique_ptr<blink::WebRTCRtpReceiver>* web_rtp_receiver) { - blink::WebVector<blink::WebMediaStream> web_streams = - (*web_rtp_receiver)->Streams(); - DCHECK_EQ(1u, web_streams.size()); - remote_stream_ = web_streams[0]; + blink::WebVector<blink::WebString> stream_ids = + (*web_rtp_receiver)->StreamIds(); + DCHECK_EQ(1u, stream_ids.size()); + remote_stream_id_ = stream_ids[0]; } -void MockWebRTCPeerConnectionHandlerClient::didRemoveRemoteTrackWorker( +void MockWebRTCPeerConnectionHandlerClient::didRemoveReceiverWorker( std::unique_ptr<blink::WebRTCRtpReceiver>* web_rtp_receiver) { - remote_stream_.Reset(); + remote_stream_id_ = blink::WebString(); } } // namespace content
diff --git a/content/renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.h b/content/renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.h index 1c6c9c7..cafe3bc 100644 --- a/content/renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.h +++ b/content/renderer/media/webrtc/mock_web_rtc_peer_connection_handler_client.h
@@ -31,29 +31,29 @@ void(webrtc::PeerConnectionInterface::SignalingState state)); MOCK_METHOD1(DidChangeICEGatheringState, void(ICEGatheringState state)); MOCK_METHOD1(DidChangeICEConnectionState, void(ICEConnectionState state)); - void DidAddRemoteTrack( + void DidAddReceiver( std::unique_ptr<blink::WebRTCRtpReceiver> web_rtp_receiver) override { - DidAddRemoteTrackForMock(&web_rtp_receiver); + DidAddReceiverForMock(&web_rtp_receiver); } - void DidRemoveRemoteTrack( + void DidRemoveReceiver( std::unique_ptr<blink::WebRTCRtpReceiver> web_rtp_receiver) override { - DidRemoveRemoteTrackForMock(&web_rtp_receiver); + DidRemoveReceiverForMock(&web_rtp_receiver); } MOCK_METHOD1(DidAddRemoteDataChannel, void(blink::WebRTCDataChannelHandler*)); MOCK_METHOD0(ReleasePeerConnectionHandler, void()); // Move-only arguments do not play nicely with MOCK, the workaround is to // EXPECT_CALL with these instead. - MOCK_METHOD1(DidAddRemoteTrackForMock, + MOCK_METHOD1(DidAddReceiverForMock, void(std::unique_ptr<blink::WebRTCRtpReceiver>*)); - MOCK_METHOD1(DidRemoveRemoteTrackForMock, + MOCK_METHOD1(DidRemoveReceiverForMock, void(std::unique_ptr<blink::WebRTCRtpReceiver>*)); void didGenerateICECandidateWorker( scoped_refptr<blink::WebRTCICECandidate> candidate); - void didAddRemoteTrackWorker( + void didAddReceiverWorker( std::unique_ptr<blink::WebRTCRtpReceiver>* stream_web_rtp_receivers); - void didRemoveRemoteTrackWorker( + void didRemoveReceiverWorker( std::unique_ptr<blink::WebRTCRtpReceiver>* stream_web_rtp_receivers); const std::string& candidate_sdp() const { return candidate_sdp_; } @@ -61,10 +61,10 @@ return candidate_mline_index_; } const std::string& candidate_mid() const { return candidate_mid_ ; } - const blink::WebMediaStream& remote_stream() const { return remote_stream_; } + const blink::WebString& remote_stream_id() const { return remote_stream_id_; } private: - blink::WebMediaStream remote_stream_; + blink::WebString remote_stream_id_; std::string candidate_sdp_; int candidate_mline_index_; std::string candidate_mid_;
diff --git a/content/renderer/media/webrtc/peer_connection_tracker.cc b/content/renderer/media/webrtc/peer_connection_tracker.cc index 1fd8e5f..a0e9f34 100644 --- a/content/renderer/media/webrtc/peer_connection_tracker.cc +++ b/content/renderer/media/webrtc/peer_connection_tracker.cc
@@ -92,27 +92,23 @@ return component.Source().Id().Utf8(); } -static std::string SerializeMediaStream(const blink::WebMediaStream& stream) { - return stream.Id().Utf8(); -} - -static std::string SerializeMediaStreamVector( - const blink::WebVector<blink::WebMediaStream> streams) { - if (!streams.size()) +static std::string SerializeMediaStreamIds( + const blink::WebVector<blink::WebString>& stream_ids) { + if (!stream_ids.size()) return "[]"; std::string result = "[ "; - for (const auto& stream : streams) { + for (const auto& stream_id : stream_ids) { if (result.size() > 2u) result += ", "; - result += SerializeMediaStream(stream); + result += stream_id.Utf8(); } result += " ]"; return result; } static std::string SerializeTransceiver( - const std::unique_ptr<blink::WebRTCRtpSender>& sender, - const std::unique_ptr<blink::WebRTCRtpReceiver>& receiver) { + const blink::WebRTCRtpSender* sender, + const blink::WebRTCRtpReceiver* receiver) { DCHECK((sender != nullptr) != (receiver != nullptr)); std::string result; if (sender) { @@ -121,14 +117,14 @@ result += "track: null"; else result += "track: " + SerializeMediaStreamComponent(sender->Track()); - result += ", streams: " + SerializeMediaStreamVector(sender->Streams()); + result += ", streams: " + SerializeMediaStreamIds(sender->StreamIds()); result += " }"; } else { DCHECK(receiver); result += "receiver: { "; DCHECK(!receiver->Track().IsNull()); result += "track: " + SerializeMediaStreamComponent(receiver->Track()); - result += ", streams: " + SerializeMediaStreamVector(receiver->Streams()); + result += ", streams: " + SerializeMediaStreamIds(receiver->StreamIds()); result += " }"; } return result; @@ -650,24 +646,24 @@ void PeerConnectionTracker::TrackAddTransceiver( RTCPeerConnectionHandler* pc_handler, PeerConnectionTracker::TransceiverUpdatedReason reason, - const std::unique_ptr<blink::WebRTCRtpSender>& sender, - const std::unique_ptr<blink::WebRTCRtpReceiver>& receiver) { + const blink::WebRTCRtpSender* sender, + const blink::WebRTCRtpReceiver* receiver) { TrackTransceiver("Added", pc_handler, reason, sender, receiver); } void PeerConnectionTracker::TrackModifyTransceiver( RTCPeerConnectionHandler* pc_handler, PeerConnectionTracker::TransceiverUpdatedReason reason, - const std::unique_ptr<blink::WebRTCRtpSender>& sender, - const std::unique_ptr<blink::WebRTCRtpReceiver>& receiver) { + const blink::WebRTCRtpSender* sender, + const blink::WebRTCRtpReceiver* receiver) { TrackTransceiver("Modified", pc_handler, reason, sender, receiver); } void PeerConnectionTracker::TrackRemoveTransceiver( RTCPeerConnectionHandler* pc_handler, PeerConnectionTracker::TransceiverUpdatedReason reason, - const std::unique_ptr<blink::WebRTCRtpSender>& sender, - const std::unique_ptr<blink::WebRTCRtpReceiver>& receiver) { + const blink::WebRTCRtpSender* sender, + const blink::WebRTCRtpReceiver* receiver) { TrackTransceiver("Removed", pc_handler, reason, sender, receiver); } @@ -675,8 +671,8 @@ const char* callback_type_ending, RTCPeerConnectionHandler* pc_handler, PeerConnectionTracker::TransceiverUpdatedReason reason, - const std::unique_ptr<blink::WebRTCRtpSender>& sender, - const std::unique_ptr<blink::WebRTCRtpReceiver>& receiver) { + const blink::WebRTCRtpSender* sender, + const blink::WebRTCRtpReceiver* receiver) { DCHECK(main_thread_.CalledOnValidThread()); int id = GetLocalIDForHandler(pc_handler); if (id == -1)
diff --git a/content/renderer/media/webrtc/peer_connection_tracker.h b/content/renderer/media/webrtc/peer_connection_tracker.h index 69db5d3f..0aeac83 100644 --- a/content/renderer/media/webrtc/peer_connection_tracker.h +++ b/content/renderer/media/webrtc/peer_connection_tracker.h
@@ -135,23 +135,20 @@ // In Unified Plan: "Transceiver" refers to RTCRtpTransceiver. // TODO(hbos): When we support transceivers, take blink::WebRTCRtpTransceiver // as the argument. https://crbug.com/777617 - virtual void TrackAddTransceiver( - RTCPeerConnectionHandler* pc_handler, - TransceiverUpdatedReason reason, - const std::unique_ptr<blink::WebRTCRtpSender>& sender, - const std::unique_ptr<blink::WebRTCRtpReceiver>& receiver); - virtual void TrackModifyTransceiver( - RTCPeerConnectionHandler* pc_handler, - TransceiverUpdatedReason reason, - const std::unique_ptr<blink::WebRTCRtpSender>& sender, - const std::unique_ptr<blink::WebRTCRtpReceiver>& receiver); + virtual void TrackAddTransceiver(RTCPeerConnectionHandler* pc_handler, + TransceiverUpdatedReason reason, + const blink::WebRTCRtpSender* sender, + const blink::WebRTCRtpReceiver* receiver); + virtual void TrackModifyTransceiver(RTCPeerConnectionHandler* pc_handler, + TransceiverUpdatedReason reason, + const blink::WebRTCRtpSender* sender, + const blink::WebRTCRtpReceiver* receiver); // TODO(hbos): When Plan B is removed this is no longer applicable. // https://crbug.com/857004 - virtual void TrackRemoveTransceiver( - RTCPeerConnectionHandler* pc_handler, - TransceiverUpdatedReason reason, - const std::unique_ptr<blink::WebRTCRtpSender>& sender, - const std::unique_ptr<blink::WebRTCRtpReceiver>& receiver); + virtual void TrackRemoveTransceiver(RTCPeerConnectionHandler* pc_handler, + TransceiverUpdatedReason reason, + const blink::WebRTCRtpSender* sender, + const blink::WebRTCRtpReceiver* receiver); // Sends an update when a DataChannel is created. virtual void TrackCreateDataChannel( @@ -207,12 +204,11 @@ // is not registered, the return value will be -1. int GetLocalIDForHandler(RTCPeerConnectionHandler* handler) const; - void TrackTransceiver( - const char* callback_type_ending, - RTCPeerConnectionHandler* pc_handler, - PeerConnectionTracker::TransceiverUpdatedReason reason, - const std::unique_ptr<blink::WebRTCRtpSender>& sender, - const std::unique_ptr<blink::WebRTCRtpReceiver>& receiver); + void TrackTransceiver(const char* callback_type_ending, + RTCPeerConnectionHandler* pc_handler, + PeerConnectionTracker::TransceiverUpdatedReason reason, + const blink::WebRTCRtpSender* sender, + const blink::WebRTCRtpReceiver* receiver); // IPC Message handler for getting all stats. void OnGetAllStats();
diff --git a/content/renderer/media/webrtc/rtc_peer_connection_handler.cc b/content/renderer/media/webrtc/rtc_peer_connection_handler.cc index bd092e8..c616b620 100644 --- a/content/renderer/media/webrtc/rtc_peer_connection_handler.cc +++ b/content/renderer/media/webrtc/rtc_peer_connection_handler.cc
@@ -18,6 +18,7 @@ #include "base/logging.h" #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" +#include "base/stl_util.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/threading/thread_task_runner_handle.h" @@ -842,15 +843,14 @@ return handlers; } -// Counts the number of senders that have |web_stream| as an associated stream. +// Counts the number of senders that have |stream_id| as an associated stream. size_t GetLocalStreamUsageCount( const std::vector<std::unique_ptr<RTCRtpSender>>& rtp_senders, - const blink::WebMediaStream& web_stream) { + const std::string stream_id) { size_t usage_count = 0; for (const auto& sender : rtp_senders) { - for (const auto& stream_ref : sender->stream_refs()) { - if (stream_ref->adapter().web_stream().UniqueId() == - web_stream.UniqueId()) { + for (const auto& sender_stream_id : sender->state().stream_ids()) { + if (sender_stream_id == stream_id) { ++usage_count; break; } @@ -859,17 +859,17 @@ return usage_count; } -// Counts the number of receivers that have |webrtc_stream| as an associated -// stream. -size_t GetRemoteStreamUsageCount( +bool IsRemoteStream( const std::map<uintptr_t, std::unique_ptr<RTCRtpReceiver>>& rtp_receivers, - const webrtc::MediaStreamInterface* webrtc_stream) { - size_t usage_count = 0; + const std::string& stream_id) { for (const auto& receiver_entry : rtp_receivers) { - if (receiver_entry.second->HasStream(webrtc_stream)) - ++usage_count; + for (const auto& receiver_stream_id : + receiver_entry.second->state().stream_ids()) { + if (stream_id == receiver_stream_id) + return true; + } } - return usage_count; + return false; } enum SdpSemanticRequested { @@ -1048,23 +1048,17 @@ removed_receivers.push_back(it->second.get()); } - // Update stream states (which tracks belong to which streams). - for (auto& stream_state : GetStreamStates(states, removed_receivers)) { - stream_state.stream_ref->adapter().SetTracks( - std::move(stream_state.track_refs)); - } - // Process the addition of remote receivers/tracks. for (auto& receiver_state : states.receiver_states) { if (ReceiverWasAdded(receiver_state)) { - handler_->OnAddRemoteTrack(receiver_state.receiver, - std::move(receiver_state.track_ref), - std::move(receiver_state.stream_refs)); + handler_->OnAddReceiver(std::move(receiver_state)); } } // Process the removal of remote receivers/tracks. - for (auto* removed_receiver : removed_receivers) - handler_->OnRemoveRemoteTrack(removed_receiver->webrtc_receiver()); + for (auto* removed_receiver : removed_receivers) { + handler_->OnRemoveReceiver(RTCRtpReceiver::getId( + removed_receiver->state().webrtc_receiver().get())); + } if (tracker_) { tracker_->TrackSessionDescriptionCallback( handler_.get(), @@ -1089,89 +1083,29 @@ private: ~WebRtcSetRemoteDescriptionObserverImpl() override {} - // Describes which tracks belong to a stream in terms of AdapterRefs. - struct StreamState { - StreamState( - std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef> stream_ref) - : stream_ref(std::move(stream_ref)) {} - - std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef> stream_ref; - std::vector<std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>> - track_refs; - }; - void ResolvePromise() { web_request_.RequestSucceeded(); web_request_.Reset(); } - bool ReceiverWasAdded(const WebRtcReceiverState& receiver_state) { - return handler_->rtp_receivers_.find( - RTCRtpReceiver::getId(receiver_state.receiver.get())) == - handler_->rtp_receivers_.end(); + bool ReceiverWasAdded(const RtpReceiverState& receiver_state) { + return !base::ContainsKey( + handler_->rtp_receivers_, + RTCRtpReceiver::getId(receiver_state.webrtc_receiver().get())); } bool ReceiverWasRemoved( const RTCRtpReceiver& receiver, - const std::vector<WebRtcReceiverState>& receiver_states) { + const std::vector<RtpReceiverState>& receiver_states) { for (const auto& receiver_state : receiver_states) { - if (receiver_state.receiver == receiver.webrtc_receiver()) + if (receiver_state.webrtc_receiver() == + receiver.state().webrtc_receiver()) { return false; + } } return true; } - // Determines the stream states from the current state of receivers and the - // receivers that are about to be removed. Produces a stable order of streams. - std::vector<StreamState> GetStreamStates( - const WebRtcSetRemoteDescriptionObserver::States& states, - const std::vector<RTCRtpReceiver*>& removed_receivers) { - states.CheckInvariants(); - std::vector<StreamState> stream_states; - // The receiver's track belongs to all of its streams. A stream may be - // associated with multiple tracks (multiple receivers). - for (auto& receiver_state : states.receiver_states) { - for (auto& stream_ref : receiver_state.stream_refs) { - CHECK(stream_ref); - CHECK(stream_ref->adapter().is_initialized()); - CHECK(!stream_ref->adapter().web_stream().IsNull()); - CHECK(stream_ref->adapter().webrtc_stream()); - auto* stream_state = - GetOrAddStreamStateForStream(*stream_ref, &stream_states); - auto track_ref = receiver_state.track_ref->Copy(); - CHECK(!track_ref->web_track().IsNull()); - CHECK(track_ref->webrtc_track()); - stream_state->track_refs.push_back(std::move(track_ref)); - } - } - // The track of removed receivers do not belong to any stream. Make sure we - // have a stream state for any streams belonging to receivers about to be - // removed in case it was the last receiver referencing that stream. - for (auto* removed_receiver : removed_receivers) { - for (auto& stream_ref : removed_receiver->StreamAdapterRefs()) { - CHECK(!stream_ref->adapter().web_stream().IsNull()); - CHECK(stream_ref->adapter().webrtc_stream()); - GetOrAddStreamStateForStream(*stream_ref, &stream_states); - } - } - states.CheckInvariants(); - return stream_states; - } - - StreamState* GetOrAddStreamStateForStream( - const WebRtcMediaStreamAdapterMap::AdapterRef& stream_ref, - std::vector<StreamState>* stream_states) { - auto* webrtc_stream = stream_ref.adapter().webrtc_stream().get(); - for (auto& stream_state : *stream_states) { - if (stream_state.stream_ref->adapter().webrtc_stream().get() == - webrtc_stream) { - return &stream_state; - } - } - stream_states->push_back(StreamState(stream_ref.Copy())); - return &stream_states->back(); - } - base::WeakPtr<RTCPeerConnectionHandler> handler_; scoped_refptr<base::SequencedTaskRunner> main_thread_; blink::WebRTCVoidRequest web_request_; @@ -1617,8 +1551,9 @@ rtc::scoped_refptr<webrtc::SetRemoteDescriptionObserverInterface> webrtc_observer(WebRtcSetRemoteDescriptionObserverHandler::Create( - task_runner_, native_peer_connection_, - stream_adapter_map_, content_observer) + task_runner_, signaling_thread(), + native_peer_connection_, track_adapter_map_, + content_observer) .get()); signaling_thread()->PostTask( @@ -1816,39 +1751,37 @@ DCHECK(task_runner_->RunsTasksInCurrentSequence()); TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::AddTrack"); - // Get or create the associated track and stream adapters. - std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_adapter = + std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref = track_adapter_map_->GetOrCreateLocalTrackAdapter(track); - std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>> - stream_adapters(streams.size()); - std::vector<webrtc::MediaStreamInterface*> webrtc_streams(streams.size()); - for (size_t i = 0; i < streams.size(); ++i) { - stream_adapters[i] = - stream_adapter_map_->GetOrCreateLocalStreamAdapter(streams[i]); - webrtc_streams[i] = stream_adapters[i]->adapter().webrtc_stream().get(); - } + std::vector<std::string> stream_ids(streams.size()); + for (size_t i = 0; i < streams.size(); ++i) + stream_ids[i] = streams[i].Id().Utf8(); - rtc::scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender = - native_peer_connection_->AddTrack(track_adapter->webrtc_track(), - webrtc_streams); - if (!webrtc_sender) + // Native addTrack(). + auto error_or_sender = + native_peer_connection_->AddTrack(track_ref->webrtc_track(), stream_ids); + if (!error_or_sender.ok()) return nullptr; + rtc::scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender = + error_or_sender.value(); + DCHECK(FindSender(RTCRtpSender::getId(webrtc_sender)) == rtp_senders_.end()); track_metrics_.AddTrack(MediaStreamTrackMetrics::Direction::kSend, MediaStreamTrackMetricsKind(track), track.Id().Utf8()); - DCHECK(FindSender(RTCRtpSender::getId(webrtc_sender)) == rtp_senders_.end()); + RtpSenderState sender_state(task_runner_, signaling_thread(), + webrtc_sender.get(), std::move(track_ref), + std::move(stream_ids)); + sender_state.Initialize(); rtp_senders_.push_back(std::make_unique<RTCRtpSender>( - native_peer_connection_, task_runner_, signaling_thread(), - stream_adapter_map_, std::move(webrtc_sender), std::move(track_adapter), - std::move(stream_adapters))); + native_peer_connection_, stream_adapter_map_, std::move(sender_state))); if (peer_connection_tracker_) { peer_connection_tracker_->TrackAddTransceiver( this, PeerConnectionTracker::TransceiverUpdatedReason::kAddTrack, - rtp_senders_.back()->ShallowCopy(), nullptr); + rtp_senders_.back().get(), nullptr); } - for (const auto& stream_ref : rtp_senders_.back()->stream_refs()) { - if (GetLocalStreamUsageCount(rtp_senders_, - stream_ref->adapter().web_stream()) == 1u) { + for (const auto& stream_id : rtp_senders_.back()->state().stream_ids()) { + if (GetLocalStreamUsageCount(rtp_senders_, stream_id) == 1u) { + // This is the first occurrence of this stream. PerSessionWebRTCAPIMetrics::GetInstance()->IncrementStreamCounter(); } } @@ -1867,19 +1800,19 @@ track_metrics_.RemoveTrack(MediaStreamTrackMetrics::Direction::kSend, MediaStreamTrackMetricsKind(web_track), web_track.Id().Utf8()); - auto stream_refs = (*it)->stream_refs(); if (peer_connection_tracker_) { peer_connection_tracker_->TrackRemoveTransceiver( this, PeerConnectionTracker::TransceiverUpdatedReason::kRemoveTrack, - (*it)->ShallowCopy(), nullptr); + (*it).get(), nullptr); } // TODO(hbos): In Unified Plan, senders are never removed. The lower layer // needs to tell us what to do with the sender: Update its states and/or // remove it. https://crbug.com/799030 + std::vector<std::string> stream_ids = (*it)->state().stream_ids(); rtp_senders_.erase(it); - for (const auto& stream_ref : stream_refs) { - if (GetLocalStreamUsageCount(rtp_senders_, - stream_ref->adapter().web_stream()) == 0u) { + for (const auto& stream_id : stream_ids) { + if (GetLocalStreamUsageCount(rtp_senders_, stream_id) == 0u) { + // This was the last occurrence of this stream. PerSessionWebRTCAPIMetrics::GetInstance()->DecrementStreamCounter(); } } @@ -2064,86 +1997,64 @@ client_->NegotiationNeeded(); } -void RTCPeerConnectionHandler::OnAddRemoteTrack( - scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver, - std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> - remote_track_adapter_ref, - std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>> - remote_stream_adapter_refs) { +void RTCPeerConnectionHandler::OnAddReceiver(RtpReceiverState receiver_state) { DCHECK(task_runner_->RunsTasksInCurrentSequence()); + DCHECK(receiver_state.is_initialized()); TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnAddRemoteTrack"); - auto web_track = remote_track_adapter_ref->web_track(); + auto web_track = receiver_state.track_ref()->web_track(); + // Update metrics. track_metrics_.AddTrack(MediaStreamTrackMetrics::Direction::kReceive, MediaStreamTrackMetricsKind(web_track), web_track.Id().Utf8()); - for (const auto& remote_stream_adapter_ref : remote_stream_adapter_refs) { + for (const auto& stream_id : receiver_state.stream_ids()) { // New remote stream? - if (GetRemoteStreamUsageCount( - rtp_receivers_, - remote_stream_adapter_ref->adapter().webrtc_stream().get()) == 0) { - // Update metrics. + if (!IsRemoteStream(rtp_receivers_, stream_id)) PerSessionWebRTCAPIMetrics::GetInstance()->IncrementStreamCounter(); - } } - - uintptr_t receiver_id = RTCRtpReceiver::getId(webrtc_receiver.get()); + uintptr_t receiver_id = + RTCRtpReceiver::getId(receiver_state.webrtc_receiver().get()); DCHECK(rtp_receivers_.find(receiver_id) == rtp_receivers_.end()); const std::unique_ptr<RTCRtpReceiver>& rtp_receiver = rtp_receivers_ - .insert(std::make_pair( - receiver_id, - std::make_unique<RTCRtpReceiver>( - native_peer_connection_, task_runner_, signaling_thread(), - webrtc_receiver.get(), std::move(remote_track_adapter_ref), - std::move(remote_stream_adapter_refs)))) + .insert(std::make_pair(receiver_id, std::make_unique<RTCRtpReceiver>( + native_peer_connection_, + std::move(receiver_state)))) .first->second; if (peer_connection_tracker_) { peer_connection_tracker_->TrackAddTransceiver( this, PeerConnectionTracker::TransceiverUpdatedReason::kSetRemoteDescription, - nullptr, rtp_receiver->ShallowCopy()); + nullptr, rtp_receiver.get()); } if (!is_closed_) - client_->DidAddRemoteTrack(rtp_receiver->ShallowCopy()); + client_->DidAddReceiver(rtp_receiver->ShallowCopy()); } -void RTCPeerConnectionHandler::OnRemoveRemoteTrack( - scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver) { +void RTCPeerConnectionHandler::OnRemoveReceiver(uintptr_t receiver_id) { DCHECK(task_runner_->RunsTasksInCurrentSequence()); TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::OnRemoveRemoteTrack"); - std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>> - remote_stream_adapter_refs; - { - uintptr_t receiver_id = RTCRtpReceiver::getId(webrtc_receiver.get()); - auto it = rtp_receivers_.find(receiver_id); - DCHECK(it != rtp_receivers_.end()); - if (peer_connection_tracker_) { - peer_connection_tracker_->TrackRemoveTransceiver( - this, - PeerConnectionTracker::TransceiverUpdatedReason:: - kSetRemoteDescription, - nullptr /* sender */, it->second->ShallowCopy() /* receiver */); - } - remote_stream_adapter_refs = it->second->StreamAdapterRefs(); - auto receiver = it->second->ShallowCopy(); - track_metrics_.RemoveTrack(MediaStreamTrackMetrics::Direction::kReceive, - MediaStreamTrackMetricsKind(receiver->Track()), - receiver->Track().Id().Utf8()); - if (!is_closed_) - client_->DidRemoveRemoteTrack(std::move(receiver)); - rtp_receivers_.erase(it); + auto it = rtp_receivers_.find(receiver_id); + DCHECK(it != rtp_receivers_.end()); + auto receiver = it->second->ShallowCopy(); + rtp_receivers_.erase(it); + // Update metrics. + track_metrics_.RemoveTrack(MediaStreamTrackMetrics::Direction::kReceive, + MediaStreamTrackMetricsKind(receiver->Track()), + receiver->Track().Id().Utf8()); + if (peer_connection_tracker_) { + peer_connection_tracker_->TrackRemoveTransceiver( + this, + PeerConnectionTracker::TransceiverUpdatedReason::kSetRemoteDescription, + nullptr /* sender */, receiver.get() /* receiver */); } - - for (const auto& remote_stream_adapter_ref : remote_stream_adapter_refs) { - // Was this the last usage of the remote stream? - if (GetRemoteStreamUsageCount( - rtp_receivers_, - remote_stream_adapter_ref->adapter().webrtc_stream().get()) == 0) { - // Update metrics. - PerSessionWebRTCAPIMetrics::GetInstance()->DecrementStreamCounter(); - } + for (const auto& stream_id : receiver->state().stream_ids()) { + // This was the last occurence of the stream? + if (!IsRemoteStream(rtp_receivers_, stream_id)) + PerSessionWebRTCAPIMetrics::GetInstance()->IncrementStreamCounter(); } + if (!is_closed_) + client_->DidRemoveReceiver(std::move(receiver)); } void RTCPeerConnectionHandler::OnDataChannel(
diff --git a/content/renderer/media/webrtc/rtc_peer_connection_handler.h b/content/renderer/media/webrtc/rtc_peer_connection_handler.h index 285cf3d..3322701 100644 --- a/content/renderer/media/webrtc/rtc_peer_connection_handler.h +++ b/content/renderer/media/webrtc/rtc_peer_connection_handler.h
@@ -197,14 +197,8 @@ void OnIceGatheringChange( webrtc::PeerConnectionInterface::IceGatheringState new_state); void OnRenegotiationNeeded(); - void OnAddRemoteTrack( - scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver, - std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> - remote_track_adapter_ref, - std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>> - remote_stream_adapter_refs); - void OnRemoveRemoteTrack( - scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver); + void OnAddReceiver(RtpReceiverState receiver_state); + void OnRemoveReceiver(uintptr_t receiver_id); void OnDataChannel(std::unique_ptr<RtcDataChannelHandler> handler); void OnIceCandidate(const std::string& sdp, const std::string& sdp_mid,
diff --git a/content/renderer/media/webrtc/rtc_peer_connection_handler_unittest.cc b/content/renderer/media/webrtc/rtc_peer_connection_handler_unittest.cc index df5e352..42f3085 100644 --- a/content/renderer/media/webrtc/rtc_peer_connection_handler_unittest.cc +++ b/content/renderer/media/webrtc/rtc_peer_connection_handler_unittest.cc
@@ -174,18 +174,18 @@ MOCK_METHOD4(TrackAddTransceiver, void(RTCPeerConnectionHandler* pc_handler, PeerConnectionTracker::TransceiverUpdatedReason reason, - const std::unique_ptr<blink::WebRTCRtpSender>& sender, - const std::unique_ptr<blink::WebRTCRtpReceiver>& receiver)); + const blink::WebRTCRtpSender* sender, + const blink::WebRTCRtpReceiver* receiver)); MOCK_METHOD4(TrackModifyTransceiver, void(RTCPeerConnectionHandler* pc_handler, PeerConnectionTracker::TransceiverUpdatedReason reason, - const std::unique_ptr<blink::WebRTCRtpSender>& sender, - const std::unique_ptr<blink::WebRTCRtpReceiver>& receiver)); + const blink::WebRTCRtpSender* sender, + const blink::WebRTCRtpReceiver* receiver)); MOCK_METHOD4(TrackRemoveTransceiver, void(RTCPeerConnectionHandler* pc_handler, PeerConnectionTracker::TransceiverUpdatedReason reason, - const std::unique_ptr<blink::WebRTCRtpSender>& sender, - const std::unique_ptr<blink::WebRTCRtpReceiver>& receiver)); + const blink::WebRTCRtpSender* sender, + const blink::WebRTCRtpReceiver* receiver)); MOCK_METHOD1(TrackOnIceComplete, void(RTCPeerConnectionHandler* pc_handler)); MOCK_METHOD3(TrackCreateDataChannel, @@ -601,12 +601,12 @@ pc_handler_->observer()->OnIceConnectionChange( webrtc::PeerConnectionInterface::kIceConnectionDisconnected); - EXPECT_CALL(*mock_client_.get(), DidAddRemoteTrackForMock(_)).Times(0); + EXPECT_CALL(*mock_client_.get(), DidAddReceiverForMock(_)).Times(0); rtc::scoped_refptr<webrtc::MediaStreamInterface> remote_stream( AddRemoteMockMediaStream("remote_stream", "video", "audio")); InvokeOnAddStream(remote_stream); - EXPECT_CALL(*mock_client_.get(), DidRemoveRemoteTrackForMock(_)).Times(0); + EXPECT_CALL(*mock_client_.get(), DidRemoveReceiverForMock(_)).Times(0); InvokeOnRemoveStream(remote_stream); EXPECT_CALL(*mock_client_.get(), DidAddRemoteDataChannel(_)).Times(0); @@ -810,14 +810,11 @@ .Times(2); EXPECT_TRUE(AddStream(local_stream)); EXPECT_EQ(stream_label, mock_peer_connection_->stream_label()); - EXPECT_EQ(1u, - mock_peer_connection_->local_streams()->at(0)->GetAudioTracks().size()); - EXPECT_EQ(1u, - mock_peer_connection_->local_streams()->at(0)->GetVideoTracks().size()); + EXPECT_EQ(2u, mock_peer_connection_->GetSenders().size()); EXPECT_FALSE(AddStream(local_stream)); EXPECT_TRUE(RemoveStream(local_stream)); - EXPECT_EQ(0u, mock_peer_connection_->local_streams()->count()); + EXPECT_EQ(0u, mock_peer_connection_->GetSenders().size()); StopAllTracks(local_stream); } @@ -842,12 +839,7 @@ EXPECT_TRUE(AddStream(local_stream)); EXPECT_EQ(stream_label, mock_peer_connection_->stream_label()); - EXPECT_EQ( - 1u, - mock_peer_connection_->local_streams()->at(0)->GetAudioTracks().size()); - EXPECT_EQ( - 1u, - mock_peer_connection_->local_streams()->at(0)->GetVideoTracks().size()); + EXPECT_EQ(2u, mock_peer_connection_->GetSenders().size()); StopAllTracks(local_stream); } @@ -890,37 +882,6 @@ StopAllTracks(local_stream); } -// TODO(hbos): Enable when not mocking or remove test. https://crbug.com/788659 -TEST_F(RTCPeerConnectionHandlerTest, DISABLED_GetStatsWithRemoteSelector) { - rtc::scoped_refptr<webrtc::MediaStreamInterface> remote_stream( - AddRemoteMockMediaStream("remote_stream", "video", "audio")); - std::vector<std::unique_ptr<blink::WebRTCRtpReceiver>> receivers; - // Grab the added receivers and media stream when it's been successfully added - // to the PC. - blink::WebMediaStream webkit_stream; - EXPECT_CALL(*mock_client_.get(), DidAddRemoteTrackForMock(_)) - .WillRepeatedly( - Invoke([&webkit_stream, &receivers]( - std::unique_ptr<blink::WebRTCRtpReceiver>* receiver) { - webkit_stream = (*receiver)->Streams()[0]; - receivers.push_back(std::move(*receiver)); - })); - InvokeOnAddStream(remote_stream); - RunMessageLoopsUntilIdle(); - EXPECT_TRUE(HasReceiverForEveryTrack(remote_stream, receivers)); - - blink::WebVector<blink::WebMediaStreamTrack> tracks = - webkit_stream.AudioTracks(); - ASSERT_LE(1ul, tracks.size()); - - scoped_refptr<MockRTCStatsRequest> request( - new rtc::RefCountedObject<MockRTCStatsRequest>()); - request->setSelector(tracks[0]); - pc_handler_->getStats(request.get()); - RunMessageLoopsUntilIdle(); - EXPECT_EQ(1, request->result()->report_count()); -} - TEST_F(RTCPeerConnectionHandlerTest, GetStatsWithBadSelector) { // The setup is the same as GetStatsWithLocalSelector, but the stream is not // added to the PeerConnection. @@ -1201,7 +1162,7 @@ AddRemoteMockMediaStream("remote_stream", "video", "audio")); // Grab the added receivers when it's been successfully added to the PC. std::vector<std::unique_ptr<blink::WebRTCRtpReceiver>> receivers_added; - EXPECT_CALL(*mock_client_.get(), DidAddRemoteTrackForMock(_)) + EXPECT_CALL(*mock_client_.get(), DidAddReceiverForMock(_)) .WillRepeatedly( Invoke([&receivers_added]( std::unique_ptr<blink::WebRTCRtpReceiver>* receiver) { @@ -1221,7 +1182,7 @@ pc_handler_.get(), PeerConnectionTracker::TransceiverUpdatedReason::kRemoveTrack, _, _)) .Times(2); - EXPECT_CALL(*mock_client_.get(), DidRemoveRemoteTrackForMock(_)) + EXPECT_CALL(*mock_client_.get(), DidRemoveReceiverForMock(_)) .WillRepeatedly( Invoke([&receivers_removed]( std::unique_ptr<blink::WebRTCRtpReceiver>* receiver) { @@ -1240,165 +1201,6 @@ EXPECT_EQ(receivers_added[1]->Id(), receivers_removed[1]->Id()); } -// This test that WebKit is notified about remote track state changes. -// TODO(hbos): Enable when not mocking or remove test. https://crbug.com/788659 -TEST_F(RTCPeerConnectionHandlerTest, DISABLED_RemoteTrackState) { - rtc::scoped_refptr<webrtc::MediaStreamInterface> remote_stream( - AddRemoteMockMediaStream("remote_stream", "video", "audio")); - std::vector<std::unique_ptr<blink::WebRTCRtpReceiver>> receivers; - // Grab the added receivers and media stream when it's been successfully added - // to the PC. - blink::WebMediaStream webkit_stream; - EXPECT_CALL(*mock_client_.get(), DidAddRemoteTrackForMock(_)) - .WillRepeatedly( - Invoke([&webkit_stream, &receivers]( - std::unique_ptr<blink::WebRTCRtpReceiver>* receiver) { - webkit_stream = (*receiver)->Streams()[0]; - receivers.push_back(std::move(*receiver)); - })); - InvokeOnAddStream(remote_stream); - RunMessageLoopsUntilIdle(); - EXPECT_TRUE(HasReceiverForEveryTrack(remote_stream, receivers)); - - blink::WebVector<blink::WebMediaStreamTrack> audio_tracks = - webkit_stream.AudioTracks(); - EXPECT_EQ(blink::WebMediaStreamSource::kReadyStateLive, - audio_tracks[0].Source().GetReadyState()); - - blink::WebVector<blink::WebMediaStreamTrack> video_tracks = - webkit_stream.VideoTracks(); - EXPECT_EQ(blink::WebMediaStreamSource::kReadyStateLive, - video_tracks[0].Source().GetReadyState()); - - InvokeOnSignalingThread( - base::Bind(&MockWebRtcAudioTrack::SetEnded, - base::Unretained(static_cast<MockWebRtcAudioTrack*>( - remote_stream->GetAudioTracks()[0].get())))); - EXPECT_EQ(blink::WebMediaStreamSource::kReadyStateEnded, - audio_tracks[0].Source().GetReadyState()); - - InvokeOnSignalingThread( - base::Bind(&MockWebRtcVideoTrack::SetEnded, - base::Unretained(static_cast<MockWebRtcVideoTrack*>( - remote_stream->GetVideoTracks()[0].get())))); - EXPECT_EQ(blink::WebMediaStreamSource::kReadyStateEnded, - video_tracks[0].Source().GetReadyState()); -} - -// TODO(hbos): Enable when not mocking or remove test. https://crbug.com/788659 -TEST_F(RTCPeerConnectionHandlerTest, - DISABLED_RemoveAndAddAudioTrackFromRemoteStream) { - rtc::scoped_refptr<webrtc::MediaStreamInterface> remote_stream( - AddRemoteMockMediaStream("remote_stream", "video", "audio")); - std::vector<std::unique_ptr<blink::WebRTCRtpReceiver>> receivers; - // Grab the added receivers and media stream when it's been successfully added - // to the PC. - blink::WebMediaStream webkit_stream; - EXPECT_CALL(*mock_client_.get(), DidAddRemoteTrackForMock(_)) - .WillRepeatedly( - Invoke([&webkit_stream, &receivers]( - std::unique_ptr<blink::WebRTCRtpReceiver>* receiver) { - webkit_stream = (*receiver)->Streams()[0]; - receivers.push_back(std::move(*receiver)); - })); - InvokeOnAddStream(remote_stream); - RunMessageLoopsUntilIdle(); - EXPECT_TRUE(HasReceiverForEveryTrack(remote_stream, receivers)); - - EXPECT_EQ(1u, webkit_stream.AudioTracks().size()); - - // Remove the Webrtc audio track from the Webrtc MediaStream. - scoped_refptr<webrtc::AudioTrackInterface> webrtc_track = - remote_stream->GetAudioTracks()[0].get(); - InvokeRemoveTrack(remote_stream, webrtc_track.get()); - EXPECT_EQ(0u, webkit_stream.AudioTracks().size()); - - blink::WebHeap::CollectGarbageForTesting(); - - // Add the WebRtc audio track again. - InvokeAddTrack(remote_stream, webrtc_track.get()); - EXPECT_EQ(1u, webkit_stream.AudioTracks().size()); -} - -// TODO(hbos): Enable when not mocking or remove test. https://crbug.com/788659 -TEST_F(RTCPeerConnectionHandlerTest, - DISABLED_RemoveAndAddVideoTrackFromRemoteStream) { - rtc::scoped_refptr<webrtc::MediaStreamInterface> remote_stream( - AddRemoteMockMediaStream("remote_stream", "video", "audio")); - std::vector<std::unique_ptr<blink::WebRTCRtpReceiver>> receivers; - // Grab the added receivers and media stream when it's been successfully added - // to the PC. - blink::WebMediaStream webkit_stream; - EXPECT_CALL(*mock_client_.get(), DidAddRemoteTrackForMock(_)) - .WillRepeatedly( - Invoke([&webkit_stream, &receivers]( - std::unique_ptr<blink::WebRTCRtpReceiver>* receiver) { - webkit_stream = (*receiver)->Streams()[0]; - receivers.push_back(std::move(*receiver)); - })); - InvokeOnAddStream(remote_stream); - RunMessageLoopsUntilIdle(); - EXPECT_TRUE(HasReceiverForEveryTrack(remote_stream, receivers)); - EXPECT_EQ(1u, webkit_stream.VideoTracks().size()); - - // Remove the Webrtc video track from the Webrtc MediaStream. - scoped_refptr<webrtc::VideoTrackInterface> webrtc_track = - remote_stream->GetVideoTracks()[0].get(); - InvokeRemoveTrack(remote_stream, webrtc_track.get()); - RunMessageLoopsUntilIdle(); - EXPECT_EQ(0u, webkit_stream.VideoTracks().size()); - - blink::WebHeap::CollectGarbageForTesting(); - - // Add the WebRtc video track again. - InvokeAddTrack(remote_stream, webrtc_track.get()); - RunMessageLoopsUntilIdle(); - EXPECT_EQ(1u, webkit_stream.VideoTracks().size()); -} - -// TODO(hbos): Enable when not mocking or remove test. https://crbug.com/788659 -TEST_F(RTCPeerConnectionHandlerTest, - DISABLED_RemoveAndAddTracksFromRemoteStream) { - rtc::scoped_refptr<webrtc::MediaStreamInterface> remote_stream( - AddRemoteMockMediaStream("remote_stream", "video", "audio")); - std::vector<std::unique_ptr<blink::WebRTCRtpReceiver>> receivers; - // Grab the added receivers and media stream when it's been successfully added - // to the PC. - blink::WebMediaStream webkit_stream; - EXPECT_CALL(*mock_client_.get(), DidAddRemoteTrackForMock(_)) - .WillRepeatedly( - Invoke([&webkit_stream, &receivers]( - std::unique_ptr<blink::WebRTCRtpReceiver>* receiver) { - webkit_stream = (*receiver)->Streams()[0]; - receivers.push_back(std::move(*receiver)); - })); - InvokeOnAddStream(remote_stream); - RunMessageLoopsUntilIdle(); - EXPECT_TRUE(HasReceiverForEveryTrack(remote_stream, receivers)); - EXPECT_EQ(1u, webkit_stream.AudioTracks().size()); - EXPECT_EQ(1u, webkit_stream.VideoTracks().size()); - - // Remove the Webrtc tracks from the MediaStream. - auto audio_track = remote_stream->GetAudioTracks()[0]; - InvokeRemoveTrack(remote_stream, audio_track.get()); - auto video_track = remote_stream->GetVideoTracks()[0]; - InvokeRemoveTrack(remote_stream, video_track.get()); - RunMessageLoopsUntilIdle(); - EXPECT_EQ(0u, webkit_stream.AudioTracks().size()); - EXPECT_EQ(0u, webkit_stream.VideoTracks().size()); - - blink::WebHeap::CollectGarbageForTesting(); - - // Add the tracks again. - InvokeAddTrack(remote_stream, audio_track.get()); - InvokeAddTrack(remote_stream, video_track.get()); - - blink::WebHeap::CollectGarbageForTesting(); - - EXPECT_EQ(1u, webkit_stream.AudioTracks().size()); - EXPECT_EQ(1u, webkit_stream.VideoTracks().size()); -} - TEST_F(RTCPeerConnectionHandlerTest, OnIceCandidate) { testing::InSequence sequence; EXPECT_CALL(*mock_tracker_.get(),
diff --git a/content/renderer/media/webrtc/rtc_rtp_receiver.cc b/content/renderer/media/webrtc/rtc_rtp_receiver.cc index a988bd1..336e709 100644 --- a/content/renderer/media/webrtc/rtc_rtp_receiver.cc +++ b/content/renderer/media/webrtc/rtc_rtp_receiver.cc
@@ -11,6 +11,96 @@ namespace content { +RtpReceiverState::RtpReceiverState( + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner, + scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver, + std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref, + std::vector<std::string> stream_id) + : main_task_runner_(std::move(main_task_runner)), + signaling_task_runner_(std::move(signaling_task_runner)), + webrtc_receiver_(std::move(webrtc_receiver)), + is_initialized_(false), + track_ref_(std::move(track_ref)), + stream_ids_(std::move(stream_id)) { + DCHECK(main_task_runner_); + DCHECK(signaling_task_runner_); + DCHECK(webrtc_receiver_); + DCHECK(track_ref_); +} + +RtpReceiverState::RtpReceiverState(RtpReceiverState&& other) + : main_task_runner_(other.main_task_runner_), + signaling_task_runner_(other.signaling_task_runner_), + webrtc_receiver_(std::move(other.webrtc_receiver_)), + is_initialized_(other.is_initialized_), + track_ref_(std::move(other.track_ref_)), + stream_ids_(std::move(other.stream_ids_)) { + // Explicitly null |other|'s task runners for use in destructor. + other.main_task_runner_ = nullptr; + other.signaling_task_runner_ = nullptr; +} + +RtpReceiverState::~RtpReceiverState() { + // It's OK to not be on the main thread if this state has been moved, in which + // case |main_task_runner_| is null. + DCHECK(!main_task_runner_ || main_task_runner_->BelongsToCurrentThread()); +} + +RtpReceiverState& RtpReceiverState::operator=(RtpReceiverState&& other) { + DCHECK_EQ(main_task_runner_, other.main_task_runner_); + DCHECK_EQ(signaling_task_runner_, other.signaling_task_runner_); + // Explicitly null |other|'s task runners for use in destructor. + other.main_task_runner_ = nullptr; + other.signaling_task_runner_ = nullptr; + webrtc_receiver_ = std::move(other.webrtc_receiver_); + track_ref_ = std::move(other.track_ref_); + stream_ids_ = std::move(other.stream_ids_); + return *this; +} + +bool RtpReceiverState::is_initialized() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return is_initialized_; +} + +void RtpReceiverState::Initialize() { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + if (is_initialized_) + return; + track_ref_->InitializeOnMainThread(); + is_initialized_ = true; +} + +scoped_refptr<base::SingleThreadTaskRunner> RtpReceiverState::main_task_runner() + const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return main_task_runner_; +} + +scoped_refptr<base::SingleThreadTaskRunner> +RtpReceiverState::signaling_task_runner() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return signaling_task_runner_; +} + +scoped_refptr<webrtc::RtpReceiverInterface> RtpReceiverState::webrtc_receiver() + const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return webrtc_receiver_; +} + +const std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>& +RtpReceiverState::track_ref() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return track_ref_; +} + +const std::vector<std::string>& RtpReceiverState::stream_ids() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return stream_ids_; +} + class RTCRtpReceiver::RTCRtpReceiverInternal : public base::RefCountedThreadSafe< RTCRtpReceiver::RTCRtpReceiverInternal, @@ -18,37 +108,34 @@ public: RTCRtpReceiverInternal( scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection, - scoped_refptr<base::SingleThreadTaskRunner> main_thread, - scoped_refptr<base::SingleThreadTaskRunner> signaling_thread, - rtc::scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver, - std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> - track_adapter, - std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>> - stream_adapter_refs) + RtpReceiverState state) : native_peer_connection_(std::move(native_peer_connection)), - main_thread_(std::move(main_thread)), - signaling_thread_(std::move(signaling_thread)), - webrtc_receiver_(std::move(webrtc_receiver)), - track_adapter_(std::move(track_adapter)), - stream_adapter_refs_(std::move(stream_adapter_refs)) { - DCHECK(webrtc_receiver_); - DCHECK(track_adapter_); + main_task_runner_(state.main_task_runner()), + signaling_task_runner_(state.signaling_task_runner()), + webrtc_receiver_(state.webrtc_receiver()), + state_(std::move(state)) { + DCHECK(native_peer_connection_); + DCHECK(state_.is_initialized()); } - const blink::WebMediaStreamTrack& Track() const { - return track_adapter_->web_track(); + const RtpReceiverState& state() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return state_; } - blink::WebVector<blink::WebMediaStream> Streams() const { - blink::WebVector<blink::WebMediaStream> web_streams( - stream_adapter_refs_.size()); - for (size_t i = 0; i < stream_adapter_refs_.size(); ++i) - web_streams[i] = stream_adapter_refs_[i]->adapter().web_stream(); - return web_streams; + void SetState(RtpReceiverState state) { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + DCHECK(state.main_task_runner() == main_task_runner_); + DCHECK(state.signaling_task_runner() == signaling_task_runner_); + DCHECK(state.webrtc_receiver() == webrtc_receiver_); + DCHECK(state.is_initialized()); + state_ = std::move(state); } blink::WebVector<std::unique_ptr<blink::WebRTCRtpContributingSource>> GetSources() { + // The webrtc_recever_ is a proxy, so this is a blocking call to the webrtc + // signalling thread. auto webrtc_sources = webrtc_receiver_->GetSources(); blink::WebVector<std::unique_ptr<blink::WebRTCRtpContributingSource>> sources(webrtc_sources.size()); @@ -60,64 +147,34 @@ } void GetStats(std::unique_ptr<blink::WebRTCStatsReportCallback> callback) { - signaling_thread_->PostTask( + signaling_task_runner_->PostTask( FROM_HERE, base::BindOnce(&RTCRtpReceiverInternal::GetStatsOnSignalingThread, this, std::move(callback))); } - webrtc::RtpReceiverInterface* webrtc_receiver() const { - return webrtc_receiver_.get(); - } - - const webrtc::MediaStreamTrackInterface& webrtc_track() const { - DCHECK(track_adapter_->webrtc_track()); - return *track_adapter_->webrtc_track(); - } - - bool HasStream(const webrtc::MediaStreamInterface* webrtc_stream) const { - for (const auto& stream_adapter : stream_adapter_refs_) { - if (webrtc_stream == stream_adapter->adapter().webrtc_stream().get()) - return true; - } - return false; - } - - std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>> - StreamAdapterRefs() const { - std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>> - stream_adapter_copies; - stream_adapter_copies.reserve(stream_adapter_refs_.size()); - for (const auto& stream_adapter : stream_adapter_refs_) { - stream_adapter_copies.push_back(stream_adapter->Copy()); - } - return stream_adapter_copies; - } - private: friend struct RTCRtpReceiver::RTCRtpReceiverInternalTraits; - ~RTCRtpReceiverInternal() { DCHECK(main_thread_->BelongsToCurrentThread()); } + ~RTCRtpReceiverInternal() { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + } void GetStatsOnSignalingThread( std::unique_ptr<blink::WebRTCStatsReportCallback> callback) { - native_peer_connection_->GetStats(webrtc_receiver_, - RTCStatsCollectorCallbackImpl::Create( - main_thread_, std::move(callback))); + native_peer_connection_->GetStats( + webrtc_receiver_.get(), RTCStatsCollectorCallbackImpl::Create( + main_task_runner_, std::move(callback))); } const scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection_; - const scoped_refptr<base::SingleThreadTaskRunner> main_thread_; - const scoped_refptr<base::SingleThreadTaskRunner> signaling_thread_; - const rtc::scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver_; - // The track adapter is the glue between blink and webrtc layer tracks. - // Keeping a reference to the adapter ensures it is not disposed, as is - // required as long as the webrtc layer track is in use by the receiver. - std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_adapter_; - // Similarly, references needs to be kept to the stream adapters of streams - // associated with the receiver. - std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>> - stream_adapter_refs_; + // Task runners and webrtc receiver: Same information as stored in + // |state_| but const and safe to touch on the signaling thread to + // avoid race with SetState(). + const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; + const scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner_; + const scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver_; + RtpReceiverState state_; }; struct RTCRtpReceiver::RTCRtpReceiverInternalTraits { @@ -128,8 +185,8 @@ static void Destruct(const RTCRtpReceiverInternal* receiver) { // RTCRtpReceiverInternal owns AdapterRefs which have to be destroyed on the // main thread, this ensures delete always happens there. - if (!receiver->main_thread_->BelongsToCurrentThread()) { - receiver->main_thread_->PostTask( + if (!receiver->main_task_runner_->BelongsToCurrentThread()) { + receiver->main_task_runner_->PostTask( FROM_HERE, base::BindOnce( &RTCRtpReceiver::RTCRtpReceiverInternalTraits::Destruct, @@ -147,18 +204,9 @@ RTCRtpReceiver::RTCRtpReceiver( scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection, - scoped_refptr<base::SingleThreadTaskRunner> main_thread, - scoped_refptr<base::SingleThreadTaskRunner> signaling_thread, - rtc::scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver, - std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_adapter, - std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>> - stream_adapter_refs) + RtpReceiverState state) : internal_(new RTCRtpReceiverInternal(std::move(native_peer_connection), - std::move(main_thread), - std::move(signaling_thread), - std::move(webrtc_receiver), - std::move(track_adapter), - std::move(stream_adapter_refs))) {} + std::move(state))) {} RTCRtpReceiver::RTCRtpReceiver(const RTCRtpReceiver& other) : internal_(other.internal_) {} @@ -174,16 +222,28 @@ return std::make_unique<RTCRtpReceiver>(*this); } +const RtpReceiverState& RTCRtpReceiver::state() const { + return internal_->state(); +} + +void RTCRtpReceiver::SetState(RtpReceiverState state) { + internal_->SetState(std::move(state)); +} + uintptr_t RTCRtpReceiver::Id() const { - return getId(internal_->webrtc_receiver()); + return getId(internal_->state().webrtc_receiver().get()); } const blink::WebMediaStreamTrack& RTCRtpReceiver::Track() const { - return internal_->Track(); + return internal_->state().track_ref()->web_track(); } -blink::WebVector<blink::WebMediaStream> RTCRtpReceiver::Streams() const { - return internal_->Streams(); +blink::WebVector<blink::WebString> RTCRtpReceiver::StreamIds() const { + const auto& stream_ids = internal_->state().stream_ids(); + blink::WebVector<blink::WebString> web_stream_ids(stream_ids.size()); + for (size_t i = 0; i < stream_ids.size(); ++i) + web_stream_ids[i] = blink::WebString::FromUTF8(stream_ids[i]); + return web_stream_ids; } blink::WebVector<std::unique_ptr<blink::WebRTCRtpContributingSource>> @@ -196,22 +256,4 @@ internal_->GetStats(std::move(callback)); } -webrtc::RtpReceiverInterface* RTCRtpReceiver::webrtc_receiver() const { - return internal_->webrtc_receiver(); -} - -const webrtc::MediaStreamTrackInterface& RTCRtpReceiver::webrtc_track() const { - return internal_->webrtc_track(); -} - -bool RTCRtpReceiver::HasStream( - const webrtc::MediaStreamInterface* webrtc_stream) const { - return internal_->HasStream(webrtc_stream); -} - -std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>> -RTCRtpReceiver::StreamAdapterRefs() const { - return internal_->StreamAdapterRefs(); -} - } // namespace content
diff --git a/content/renderer/media/webrtc/rtc_rtp_receiver.h b/content/renderer/media/webrtc/rtc_rtp_receiver.h index 29420ae5..a651320 100644 --- a/content/renderer/media/webrtc/rtc_rtp_receiver.h +++ b/content/renderer/media/webrtc/rtc_rtp_receiver.h
@@ -20,6 +20,77 @@ namespace content { +// This class represents the state of a receiver; a snapshot of what a +// webrtc-layer receiver looked like when it was inspected on the signaling +// thread such that this information can be moved to the main thread in a single +// PostTask. It is used to surface state changes to make the blink-layer +// receiver up-to-date. +// +// Blink objects live on the main thread and webrtc objects live on the +// signaling thread. If multiple asynchronous operations begin execution on the +// main thread they are posted and executed in order on the signaling thread. +// For example, operation A and operation B are called in JavaScript. When A is +// done on the signaling thread, webrtc object states will be updated. A +// callback is posted to the main thread so that blink objects can be updated to +// match the result of operation A. But if callback A tries to inspect the +// webrtc objects from the main thread this requires posting back to the +// signaling thread and waiting, which also includes waiting for the previously +// posted task: operation B. Inspecting the webrtc object like this does not +// guarantee you to get the state of operation A. +// +// As such, all state changes associated with an operation have to be surfaced +// in the same callback. This includes copying any states into a separate object +// so that it can be inspected on the main thread without any additional thread +// hops. +// +// The RtpReceiverState is a snapshot of what the webrtc::RtpReceiverInterface +// looked like when the RtpReceiverState was created on the signaling thread. It +// also takes care of initializing track adapters, such that we have access to a +// blink track corresponding to the webrtc track of the receiver. +// +// Except for initialization logic and operator=(), the RtpReceiverState is +// immutable and only accessible on the main thread. +// +// TODO(hbos): [Onion Soup] When the sender implementation is moved to blink +// this will be part of the blink sender instead of the content sender. +// https://crbug.com/787254 +class CONTENT_EXPORT RtpReceiverState { + public: + RtpReceiverState( + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner, + scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver, + std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref, + std::vector<std::string> stream_ids); + RtpReceiverState(RtpReceiverState&&); + RtpReceiverState(const RtpReceiverState&) = delete; + ~RtpReceiverState(); + + // This is intended to be used for moving the object from the signaling thread + // to the main thread and as such has no thread checks. Once moved to the main + // this should only be invoked on the main thread. + RtpReceiverState& operator=(RtpReceiverState&&); + RtpReceiverState& operator=(const RtpReceiverState&) = delete; + + bool is_initialized() const; + void Initialize(); + + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner() const; + scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner() const; + scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver() const; + const std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>& + track_ref() const; + const std::vector<std::string>& stream_ids() const; + + private: + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; + scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner_; + scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver_; + bool is_initialized_; + std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref_; + std::vector<std::string> stream_ids_; +}; + // Used to surface |webrtc::RtpReceiverInterface| to blink. Multiple // |RTCRtpReceiver|s could reference the same webrtc receiver; |id| is the value // of the pointer to the webrtc receiver. @@ -30,13 +101,7 @@ RTCRtpReceiver( scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection, - scoped_refptr<base::SingleThreadTaskRunner> main_thread, - scoped_refptr<base::SingleThreadTaskRunner> signaling_thread, - rtc::scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver, - std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> - track_adapter, - std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>> - stream_adapter_refs); + RtpReceiverState state); RTCRtpReceiver(const RTCRtpReceiver& other); ~RTCRtpReceiver() override; @@ -46,19 +111,16 @@ // webrtc receiver as the original. std::unique_ptr<RTCRtpReceiver> ShallowCopy() const; + const RtpReceiverState& state() const; + void SetState(RtpReceiverState state); + uintptr_t Id() const override; const blink::WebMediaStreamTrack& Track() const override; - blink::WebVector<blink::WebMediaStream> Streams() const override; + blink::WebVector<blink::WebString> StreamIds() const override; blink::WebVector<std::unique_ptr<blink::WebRTCRtpContributingSource>> GetSources() override; void GetStats(std::unique_ptr<blink::WebRTCStatsReportCallback>) override; - webrtc::RtpReceiverInterface* webrtc_receiver() const; - const webrtc::MediaStreamTrackInterface& webrtc_track() const; - bool HasStream(const webrtc::MediaStreamInterface* webrtc_stream) const; - std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>> - StreamAdapterRefs() const; - private: class RTCRtpReceiverInternal; struct RTCRtpReceiverInternalTraits;
diff --git a/content/renderer/media/webrtc/rtc_rtp_receiver_unittest.cc b/content/renderer/media/webrtc/rtc_rtp_receiver_unittest.cc index f55c2b22..07e6d51b 100644 --- a/content/renderer/media/webrtc/rtc_rtp_receiver_unittest.cc +++ b/content/renderer/media/webrtc/rtc_rtp_receiver_unittest.cc
@@ -63,23 +63,23 @@ std::unique_ptr<RTCRtpReceiver> CreateReceiver( scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track) { - std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_adapter; + std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref; base::RunLoop run_loop; dependency_factory_->GetWebRtcSignalingThread()->PostTask( FROM_HERE, base::BindOnce(&RTCRtpReceiverTest::CreateReceiverOnSignalingThread, base::Unretained(this), std::move(webrtc_track), - base::Unretained(&track_adapter), + base::Unretained(&track_ref), base::Unretained(&run_loop))); run_loop.Run(); DCHECK(mock_webrtc_receiver_); - DCHECK(track_adapter); - return std::make_unique<RTCRtpReceiver>( - peer_connection_.get(), main_thread_, - dependency_factory_->GetWebRtcSignalingThread(), - mock_webrtc_receiver_.get(), std::move(track_adapter), - std::vector< - std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>>()); + DCHECK(track_ref); + RtpReceiverState state( + main_thread_, dependency_factory_->GetWebRtcSignalingThread(), + mock_webrtc_receiver_.get(), std::move(track_ref), {}); + state.Initialize(); + return std::make_unique<RTCRtpReceiver>(peer_connection_.get(), + std::move(state)); } scoped_refptr<WebRTCStatsReportObtainer> GetStats() { @@ -92,12 +92,11 @@ protected: void CreateReceiverOnSignalingThread( scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track, - std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>* - track_adapter, + std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>* track_ref, base::RunLoop* run_loop) { mock_webrtc_receiver_ = new rtc::RefCountedObject<webrtc::MockRtpReceiver>(); - *track_adapter = + *track_ref = stream_map_->track_adapter_map()->GetOrCreateRemoteTrackAdapter( webrtc_track); run_loop->Quit(); @@ -122,7 +121,7 @@ receiver_ = CreateReceiver(webrtc_track); EXPECT_FALSE(receiver_->Track().IsNull()); EXPECT_EQ(receiver_->Track().Id().Utf8(), webrtc_track->id()); - EXPECT_EQ(&receiver_->webrtc_track(), webrtc_track); + EXPECT_EQ(receiver_->state().track_ref()->webrtc_track(), webrtc_track); } TEST_F(RTCRtpReceiverTest, ShallowCopy) { @@ -130,17 +129,17 @@ MockWebRtcAudioTrack::Create("webrtc_track"); receiver_ = CreateReceiver(webrtc_track); auto copy = receiver_->ShallowCopy(); - EXPECT_EQ(&receiver_->webrtc_track(), webrtc_track); - auto* webrtc_receiver = receiver_->webrtc_receiver(); + EXPECT_EQ(receiver_->state().track_ref()->webrtc_track(), webrtc_track); + const auto& webrtc_receiver = receiver_->state().webrtc_receiver(); auto web_track_unique_id = receiver_->Track().UniqueId(); // Copy is identical to original. - EXPECT_EQ(copy->webrtc_receiver(), webrtc_receiver); - EXPECT_EQ(©->webrtc_track(), webrtc_track); + EXPECT_EQ(copy->state().webrtc_receiver(), webrtc_receiver); + EXPECT_EQ(copy->state().track_ref()->webrtc_track(), webrtc_track); EXPECT_EQ(copy->Track().UniqueId(), web_track_unique_id); // Copy keeps the internal state alive. receiver_.reset(); - EXPECT_EQ(copy->webrtc_receiver(), webrtc_receiver); - EXPECT_EQ(©->webrtc_track(), webrtc_track); + EXPECT_EQ(copy->state().webrtc_receiver(), webrtc_receiver); + EXPECT_EQ(copy->state().track_ref()->webrtc_track(), webrtc_track); EXPECT_EQ(copy->Track().UniqueId(), web_track_unique_id); }
diff --git a/content/renderer/media/webrtc/rtc_rtp_sender.cc b/content/renderer/media/webrtc/rtc_rtp_sender.cc index c93d405..64643fc 100644 --- a/content/renderer/media/webrtc/rtc_rtp_sender.cc +++ b/content/renderer/media/webrtc/rtc_rtp_sender.cc
@@ -36,6 +36,100 @@ } // namespace +RtpSenderState::RtpSenderState( + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner, + scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender, + std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref, + std::vector<std::string> stream_ids) + : main_task_runner_(std::move(main_task_runner)), + signaling_task_runner_(std::move(signaling_task_runner)), + webrtc_sender_(std::move(webrtc_sender)), + is_initialized_(false), + track_ref_(std::move(track_ref)), + stream_ids_(std::move(stream_ids)) { + DCHECK(main_task_runner_); + DCHECK(signaling_task_runner_); + DCHECK(webrtc_sender_); +} + +RtpSenderState::RtpSenderState(RtpSenderState&& other) + : main_task_runner_(other.main_task_runner_), + signaling_task_runner_(other.signaling_task_runner_), + webrtc_sender_(std::move(other.webrtc_sender_)), + is_initialized_(other.is_initialized_), + track_ref_(std::move(other.track_ref_)), + stream_ids_(std::move(other.stream_ids_)) { + other.main_task_runner_ = nullptr; + other.signaling_task_runner_ = nullptr; +} + +RtpSenderState::~RtpSenderState() { + // It's OK to not be on the main thread if this state has been moved, in which + // case |main_task_runner_| is null. + DCHECK(!main_task_runner_ || main_task_runner_->BelongsToCurrentThread()); +} + +RtpSenderState& RtpSenderState::operator=(RtpSenderState&& other) { + DCHECK_EQ(main_task_runner_, other.main_task_runner_); + DCHECK_EQ(signaling_task_runner_, other.signaling_task_runner_); + other.main_task_runner_ = nullptr; + other.signaling_task_runner_ = nullptr; + webrtc_sender_ = std::move(other.webrtc_sender_); + is_initialized_ = other.is_initialized_; + track_ref_ = std::move(other.track_ref_); + stream_ids_ = std::move(other.stream_ids_); + return *this; +} + +bool RtpSenderState::is_initialized() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return is_initialized_; +} + +void RtpSenderState::Initialize() { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + if (track_ref_) + track_ref_->InitializeOnMainThread(); + is_initialized_ = true; +} + +scoped_refptr<base::SingleThreadTaskRunner> RtpSenderState::main_task_runner() + const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return main_task_runner_; +} + +scoped_refptr<base::SingleThreadTaskRunner> +RtpSenderState::signaling_task_runner() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return signaling_task_runner_; +} + +scoped_refptr<webrtc::RtpSenderInterface> RtpSenderState::webrtc_sender() + const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return webrtc_sender_; +} + +const std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>& +RtpSenderState::track_ref() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return track_ref_; +} + +void RtpSenderState::set_track_ref( + std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref) { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + DCHECK(!is_initialized_ || !track_ref || track_ref->is_initialized()); + track_ref_ = std::move(track_ref); +} + +std::vector<std::string> RtpSenderState::stream_ids() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return stream_ids_; +} + class RTCRtpSender::RTCRtpSenderInternal : public base::RefCountedThreadSafe< RTCRtpSender::RTCRtpSenderInternal, @@ -43,77 +137,35 @@ public: RTCRtpSenderInternal( scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection, - scoped_refptr<base::SingleThreadTaskRunner> main_thread, - scoped_refptr<base::SingleThreadTaskRunner> signaling_thread, scoped_refptr<WebRtcMediaStreamAdapterMap> stream_map, - rtc::scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender, - blink::WebMediaStreamTrack web_track, - std::vector<blink::WebMediaStream> web_streams) + RtpSenderState state) : native_peer_connection_(std::move(native_peer_connection)), - main_thread_(std::move(main_thread)), - signaling_thread_(std::move(signaling_thread)), stream_map_(std::move(stream_map)), - webrtc_sender_(std::move(webrtc_sender)) { - DCHECK(main_thread_); - DCHECK(signaling_thread_); + main_task_runner_(state.main_task_runner()), + signaling_task_runner_(state.signaling_task_runner()), + webrtc_sender_(state.webrtc_sender()), + state_(std::move(state)) { DCHECK(stream_map_); - DCHECK(webrtc_sender_); - if (!web_track.IsNull()) { - track_ref_ = - stream_map_->track_adapter_map()->GetOrCreateLocalTrackAdapter( - web_track); - } - for (size_t i = 0; i < web_streams.size(); ++i) { - if (!web_streams[i].IsNull()) { - stream_refs_.push_back( - stream_map_->GetOrCreateLocalStreamAdapter(web_streams[i])); - } - } + DCHECK(state_.is_initialized()); } - RTCRtpSenderInternal( - scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection, - scoped_refptr<base::SingleThreadTaskRunner> main_thread, - scoped_refptr<base::SingleThreadTaskRunner> signaling_thread, - scoped_refptr<WebRtcMediaStreamAdapterMap> stream_map, - rtc::scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender, - std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref, - std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>> - stream_refs) - : native_peer_connection_(std::move(native_peer_connection)), - main_thread_(std::move(main_thread)), - signaling_thread_(std::move(signaling_thread)), - stream_map_(std::move(stream_map)), - webrtc_sender_(std::move(webrtc_sender)), - track_ref_(std::move(track_ref)), - stream_refs_(std::move(stream_refs)) { - DCHECK(main_thread_); - DCHECK(signaling_thread_); - DCHECK(stream_map_); - DCHECK(webrtc_sender_); + const RtpSenderState& state() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return state_; } - webrtc::RtpSenderInterface* webrtc_sender() const { - return webrtc_sender_.get(); - } - - std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref() - const { - return track_ref_ ? track_ref_->Copy() : nullptr; - } - - std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>> - stream_refs() const { - std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>> - stream_ref_copies(stream_refs_.size()); - for (size_t i = 0; i < stream_refs_.size(); ++i) - stream_ref_copies[i] = stream_refs_[i]->Copy(); - return stream_ref_copies; + void set_state(RtpSenderState state) { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + DCHECK_EQ(state.main_task_runner(), main_task_runner_); + DCHECK_EQ(state.signaling_task_runner(), signaling_task_runner_); + DCHECK(state.webrtc_sender() == webrtc_sender_); + DCHECK(state.is_initialized()); + state_ = std::move(state); } void ReplaceTrack(blink::WebMediaStreamTrack with_track, base::OnceCallback<void(bool)> callback) { - DCHECK(main_thread_->BelongsToCurrentThread()); + DCHECK(main_task_runner_->BelongsToCurrentThread()); std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref; webrtc::MediaStreamTrackInterface* webrtc_track = nullptr; if (!with_track.IsNull()) { @@ -122,7 +174,7 @@ with_track); webrtc_track = track_ref->webrtc_track(); } - signaling_thread_->PostTask( + signaling_task_runner_->PostTask( FROM_HERE, base::BindOnce( &RTCRtpSender::RTCRtpSenderInternal::ReplaceTrackOnSignalingThread, @@ -131,14 +183,16 @@ } std::unique_ptr<blink::WebRTCDTMFSenderHandler> GetDtmfSender() const { - // The webrtc_sender is a proxy, so this is a blocking call to the + // The webrtc_sender() is a proxy, so this is a blocking call to the // webrtc signalling thread. - DCHECK(main_thread_->BelongsToCurrentThread()); - auto dtmf_sender = webrtc_sender()->GetDtmfSender(); + DCHECK(main_task_runner_->BelongsToCurrentThread()); + auto dtmf_sender = webrtc_sender_->GetDtmfSender(); return std::make_unique<RtcDtmfSenderHandler>(dtmf_sender); } std::unique_ptr<webrtc::RtpParameters> GetParameters() { + // The webrtc_sender() is a proxy, so this is a blocking call to the + // webrtc signalling thread. parameters_ = webrtc_sender_->GetParameters(); return std::make_unique<webrtc::RtpParameters>(parameters_); } @@ -146,7 +200,7 @@ void SetParameters(blink::WebVector<webrtc::RtpEncodingParameters> encodings, webrtc::DegradationPreference degradation_preference, base::OnceCallback<void(webrtc::RTCError)> callback) { - DCHECK(main_thread_->BelongsToCurrentThread()); + DCHECK(main_task_runner_->BelongsToCurrentThread()); webrtc::RtpParameters new_parameters = parameters_; @@ -171,7 +225,7 @@ encoding.scale_resolution_down_by; } - signaling_thread_->PostTask( + signaling_task_runner_->PostTask( FROM_HERE, base::BindOnce( &RTCRtpSender::RTCRtpSenderInternal::SetParametersOnSignalingThread, @@ -179,7 +233,7 @@ } void GetStats(std::unique_ptr<blink::WebRTCStatsReportCallback> callback) { - signaling_thread_->PostTask( + signaling_task_runner_->PostTask( FROM_HERE, base::BindOnce( &RTCRtpSender::RTCRtpSenderInternal::GetStatsOnSignalingThread, @@ -187,13 +241,14 @@ } bool RemoveFromPeerConnection(webrtc::PeerConnectionInterface* pc) { - if (!pc->RemoveTrack(webrtc_sender_)) + DCHECK(main_task_runner_->BelongsToCurrentThread()); + if (!pc->RemoveTrack(webrtc_sender_.get())) return false; // TODO(hbos): Removing the track should null the sender's track, or we // should do |webrtc_sender_->SetTrack(null)| but that is not allowed on a // stopped sender. In the meantime, there is a discrepancy between layers. // https://crbug.com/webrtc/7945 - track_ref_.reset(); + state_.set_track_ref(nullptr); return true; } @@ -202,7 +257,7 @@ ~RTCRtpSenderInternal() { // Ensured by destructor traits. - DCHECK(main_thread_->BelongsToCurrentThread()); + DCHECK(main_task_runner_->BelongsToCurrentThread()); } // |webrtc_track| is passed as an argument because |track_ref->webrtc_track()| @@ -211,9 +266,9 @@ std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref, webrtc::MediaStreamTrackInterface* webrtc_track, base::OnceCallback<void(bool)> callback) { - DCHECK(signaling_thread_->BelongsToCurrentThread()); + DCHECK(signaling_task_runner_->BelongsToCurrentThread()); bool result = webrtc_sender_->SetTrack(webrtc_track); - main_thread_->PostTask( + main_task_runner_->PostTask( FROM_HERE, base::BindOnce( &RTCRtpSender::RTCRtpSenderInternal::ReplaceTrackCallback, this, @@ -224,25 +279,25 @@ bool result, std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref, base::OnceCallback<void(bool)> callback) { - DCHECK(main_thread_->BelongsToCurrentThread()); + DCHECK(main_task_runner_->BelongsToCurrentThread()); if (result) - track_ref_ = std::move(track_ref); + state_.set_track_ref(std::move(track_ref)); std::move(callback).Run(result); } void GetStatsOnSignalingThread( std::unique_ptr<blink::WebRTCStatsReportCallback> callback) { - native_peer_connection_->GetStats(webrtc_sender_, - RTCStatsCollectorCallbackImpl::Create( - main_thread_, std::move(callback))); + native_peer_connection_->GetStats( + webrtc_sender_.get(), RTCStatsCollectorCallbackImpl::Create( + main_task_runner_, std::move(callback))); } void SetParametersOnSignalingThread( webrtc::RtpParameters parameters, base::OnceCallback<void(webrtc::RTCError)> callback) { - DCHECK(signaling_thread_->BelongsToCurrentThread()); + DCHECK(signaling_task_runner_->BelongsToCurrentThread()); webrtc::RTCError result = webrtc_sender_->SetParameters(parameters); - main_thread_->PostTask( + main_task_runner_->PostTask( FROM_HERE, base::BindOnce( &RTCRtpSender::RTCRtpSenderInternal::SetParametersCallback, this, @@ -252,23 +307,19 @@ void SetParametersCallback( webrtc::RTCError result, base::OnceCallback<void(webrtc::RTCError)> callback) { - DCHECK(main_thread_->BelongsToCurrentThread()); + DCHECK(main_task_runner_->BelongsToCurrentThread()); std::move(callback).Run(std::move(result)); } const scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection_; - const scoped_refptr<base::SingleThreadTaskRunner> main_thread_; - const scoped_refptr<base::SingleThreadTaskRunner> signaling_thread_; const scoped_refptr<WebRtcMediaStreamAdapterMap> stream_map_; - const rtc::scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender_; - // The track adapter is the glue between blink and webrtc layer tracks. - // Keeping a reference to the adapter ensures it is not disposed, as is - // required as long as the webrtc layer track is in use by the sender. - std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref_; - // Similarly, reference needs to be kept to the stream adapters of the - // sender's associated set of streams. - std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>> - stream_refs_; + // Task runners and webrtc sender: Same information as stored in + // |state_| but const and safe to touch on the signaling thread to + // avoid race with set_state(). + const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; + const scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner_; + const scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender_; + RtpSenderState state_; webrtc::RtpParameters parameters_; }; @@ -280,8 +331,8 @@ static void Destruct(const RTCRtpSenderInternal* sender) { // RTCRtpSenderInternal owns AdapterRefs which have to be destroyed on the // main thread, this ensures delete always happens there. - if (!sender->main_thread_->BelongsToCurrentThread()) { - sender->main_thread_->PostTask( + if (!sender->main_task_runner_->BelongsToCurrentThread()) { + sender->main_task_runner_->PostTask( FROM_HERE, base::BindOnce(&RTCRtpSender::RTCRtpSenderInternalTraits::Destruct, base::Unretained(sender))); @@ -297,36 +348,11 @@ RTCRtpSender::RTCRtpSender( scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection, - scoped_refptr<base::SingleThreadTaskRunner> main_thread, - scoped_refptr<base::SingleThreadTaskRunner> signaling_thread, scoped_refptr<WebRtcMediaStreamAdapterMap> stream_map, - rtc::scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender, - blink::WebMediaStreamTrack web_track, - std::vector<blink::WebMediaStream> web_streams) + RtpSenderState state) : internal_(new RTCRtpSenderInternal(std::move(native_peer_connection), - std::move(main_thread), - std::move(signaling_thread), std::move(stream_map), - std::move(webrtc_sender), - std::move(web_track), - std::move(web_streams))) {} - -RTCRtpSender::RTCRtpSender( - scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection, - scoped_refptr<base::SingleThreadTaskRunner> main_thread, - scoped_refptr<base::SingleThreadTaskRunner> signaling_thread, - scoped_refptr<WebRtcMediaStreamAdapterMap> stream_map, - rtc::scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender, - std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref, - std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>> - stream_refs) - : internal_(new RTCRtpSenderInternal(std::move(native_peer_connection), - std::move(main_thread), - std::move(signaling_thread), - std::move(stream_map), - std::move(webrtc_sender), - std::move(track_ref), - std::move(stream_refs))) {} + std::move(state))) {} RTCRtpSender::RTCRtpSender(const RTCRtpSender& other) : internal_(other.internal_) {} @@ -342,21 +368,30 @@ return std::make_unique<RTCRtpSender>(*this); } +const RtpSenderState& RTCRtpSender::state() const { + return internal_->state(); +} + +void RTCRtpSender::set_state(RtpSenderState state) { + internal_->set_state(std::move(state)); +} + uintptr_t RTCRtpSender::Id() const { - return getId(internal_->webrtc_sender()); + return getId(internal_->state().webrtc_sender().get()); } blink::WebMediaStreamTrack RTCRtpSender::Track() const { - auto track_ref = internal_->track_ref(); + const auto& track_ref = internal_->state().track_ref(); return track_ref ? track_ref->web_track() : blink::WebMediaStreamTrack(); } -blink::WebVector<blink::WebMediaStream> RTCRtpSender::Streams() const { - auto stream_refs = this->stream_refs(); - blink::WebVector<blink::WebMediaStream> web_streams(stream_refs.size()); - for (size_t i = 0; i < stream_refs.size(); ++i) - web_streams[i] = stream_refs[i]->adapter().web_stream(); - return web_streams; +blink::WebVector<blink::WebString> RTCRtpSender::StreamIds() const { + const auto& stream_ids = internal_->state().stream_ids(); + blink::WebVector<blink::WebString> web_stream_ids(stream_ids.size()); + for (size_t i = 0; i < stream_ids.size(); ++i) + web_stream_ids[i] = blink::WebString::FromUTF8(stream_ids[i]); + return web_stream_ids; + ; } void RTCRtpSender::ReplaceTrack(blink::WebMediaStreamTrack with_track, @@ -389,20 +424,6 @@ internal_->GetStats(std::move(callback)); } -webrtc::RtpSenderInterface* RTCRtpSender::webrtc_sender() const { - return internal_->webrtc_sender(); -} - -const webrtc::MediaStreamTrackInterface* RTCRtpSender::webrtc_track() const { - auto track_ref = internal_->track_ref(); - return track_ref ? track_ref->webrtc_track() : nullptr; -} - -std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>> -RTCRtpSender::stream_refs() const { - return internal_->stream_refs(); -} - void RTCRtpSender::ReplaceTrack(blink::WebMediaStreamTrack with_track, base::OnceCallback<void(bool)> callback) { internal_->ReplaceTrack(std::move(with_track), std::move(callback));
diff --git a/content/renderer/media/webrtc/rtc_rtp_sender.h b/content/renderer/media/webrtc/rtc_rtp_sender.h index b584389..66a72b1 100644 --- a/content/renderer/media/webrtc/rtc_rtp_sender.h +++ b/content/renderer/media/webrtc/rtc_rtp_sender.h
@@ -22,30 +22,96 @@ namespace content { +// This class represents the state of a sender; a snapshot of what a +// webrtc-layer sender looked like when it was inspected on the signaling thread +// such that this information can be moved to the main thread in a single +// PostTask. It is used to surface state changes to make the blink-layer sender +// up-to-date. +// +// Blink objects live on the main thread and webrtc objects live on the +// signaling thread. If multiple asynchronous operations begin execution on the +// main thread they are posted and executed in order on the signaling thread. +// For example, operation A and operation B are called in JavaScript. When A is +// done on the signaling thread, webrtc object states will be updated. A +// callback is posted to the main thread so that blink objects can be updated to +// match the result of operation A. But if callback A tries to inspect the +// webrtc objects from the main thread this requires posting back to the +// signaling thread and waiting, which also includes waiting for the previously +// posted task: operation B. Inspecting the webrtc object like this does not +// guarantee you to get the state of operation A. +// +// As such, all state changes associated with an operation have to be surfaced +// in the same callback. This includes copying any states into a separate object +// so that it can be inspected on the main thread without any additional thread +// hops. +// +// The RtpSenderState is a snapshot of what the webrtc::RtpSenderInterface +// looked like when the RtpSenderState was created on the signaling thread. It +// also takes care of initializing track adapters, such that we have access to a +// blink track corresponding to the webrtc track of the sender. +// +// Except for initialization logic and operator=(), the RtpSenderState is +// immutable and only accessible on the main thread. +// +// TODO(hbos): [Onion Soup] When the sender implementation is moved to blink +// this will be part of the blink sender instead of the content sender. +// https://crbug.com/787254 +class CONTENT_EXPORT RtpSenderState { + public: + RtpSenderState( + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner, + scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender, + std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref, + std::vector<std::string> stream_ids); + RtpSenderState(RtpSenderState&&); + RtpSenderState(const RtpSenderState&) = delete; + ~RtpSenderState(); + + // This is intended to be used for moving the object from the signaling thread + // to the main thread and as such has no thread checks. Once moved to the main + // this should only be invoked on the main thread. + RtpSenderState& operator=(RtpSenderState&&); + RtpSenderState& operator=(const RtpSenderState&) = delete; + + bool is_initialized() const; + void Initialize(); + + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner() const; + scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner() const; + scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender() const; + const std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>& + track_ref() const; + void set_track_ref( + std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref); + std::vector<std::string> stream_ids() const; + + private: + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; + scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner_; + scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender_; + bool is_initialized_; + std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref_; + std::vector<std::string> stream_ids_; +}; + // Used to surface |webrtc::RtpSenderInterface| to blink. Multiple // |RTCRtpSender|s could reference the same webrtc sender; |id| is the value // of the pointer to the webrtc sender. +// TODO(hbos): [Onion Soup] Move all of the implementation inside the blink +// object and remove this class and interface. The blink object is reference +// counted and we can get rid of this "Web"-copyable with "internal" nonsense, +// all the blink object will need is the RtpSenderState. Requires coordination +// with transceivers and receivers since these are tightly coupled. +// https://crbug.com/787254 class CONTENT_EXPORT RTCRtpSender : public blink::WebRTCRtpSender { public: static uintptr_t getId(const webrtc::RtpSenderInterface* webrtc_sender); RTCRtpSender( scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection, - scoped_refptr<base::SingleThreadTaskRunner> main_thread, - scoped_refptr<base::SingleThreadTaskRunner> signaling_thread, scoped_refptr<WebRtcMediaStreamAdapterMap> stream_map, - rtc::scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender, - blink::WebMediaStreamTrack web_track, - std::vector<blink::WebMediaStream> web_streams); - RTCRtpSender( - scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection, - scoped_refptr<base::SingleThreadTaskRunner> main_thread, - scoped_refptr<base::SingleThreadTaskRunner> signaling_thread, - scoped_refptr<WebRtcMediaStreamAdapterMap> stream_map, - rtc::scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender, - std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref, - std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>> - stream_refs); + RtpSenderState state); RTCRtpSender(const RTCRtpSender& other); ~RTCRtpSender() override; @@ -56,10 +122,13 @@ // TODO(hbos): Remove in favor of constructor. https://crbug.com/790007 std::unique_ptr<RTCRtpSender> ShallowCopy() const; + const RtpSenderState& state() const; + void set_state(RtpSenderState state); + // blink::WebRTCRtpSender. uintptr_t Id() const override; blink::WebMediaStreamTrack Track() const override; - blink::WebVector<blink::WebMediaStream> Streams() const override; + blink::WebVector<blink::WebString> StreamIds() const override; void ReplaceTrack(blink::WebMediaStreamTrack with_track, blink::WebRTCVoidRequest request) override; std::unique_ptr<blink::WebRTCDTMFSenderHandler> GetDtmfSender() @@ -70,10 +139,6 @@ blink::WebRTCVoidRequest) override; void GetStats(std::unique_ptr<blink::WebRTCStatsReportCallback>) override; - webrtc::RtpSenderInterface* webrtc_sender() const; - const webrtc::MediaStreamTrackInterface* webrtc_track() const; - std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>> - stream_refs() const; // The ReplaceTrack() that takes a blink::WebRTCVoidRequest is implemented on // top of this, which returns the result in a callback instead. Allows doing // ReplaceTrack() without having a blink::WebRTCVoidRequest, which can only be
diff --git a/content/renderer/media/webrtc/rtc_rtp_sender_unittest.cc b/content/renderer/media/webrtc/rtc_rtp_sender_unittest.cc index eb086d2..f6ff24b9 100644 --- a/content/renderer/media/webrtc/rtc_rtp_sender_unittest.cc +++ b/content/renderer/media/webrtc/rtc_rtp_sender_unittest.cc
@@ -84,11 +84,20 @@ std::unique_ptr<RTCRtpSender> CreateSender( blink::WebMediaStreamTrack web_track) { - return std::make_unique<RTCRtpSender>( - peer_connection_.get(), main_thread_, - dependency_factory_->GetWebRtcSignalingThread(), stream_map_, - mock_webrtc_sender_.get(), std::move(web_track), - std::vector<blink::WebMediaStream>()); + std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref; + if (!web_track.IsNull()) { + track_ref = + stream_map_->track_adapter_map()->GetOrCreateLocalTrackAdapter( + web_track); + DCHECK(track_ref->is_initialized()); + } + RtpSenderState sender_state(main_thread_, + dependency_factory_->GetWebRtcSignalingThread(), + mock_webrtc_sender_.get(), std::move(track_ref), + std::vector<std::string>()); + sender_state.Initialize(); + return std::make_unique<RTCRtpSender>(peer_connection_.get(), stream_map_, + std::move(sender_state)); } // Calls replaceTrack(), which is asynchronous, returning a callback that when
diff --git a/content/renderer/media/webrtc/rtc_rtp_transceiver.cc b/content/renderer/media/webrtc/rtc_rtp_transceiver.cc new file mode 100644 index 0000000..aaee9b9 --- /dev/null +++ b/content/renderer/media/webrtc/rtc_rtp_transceiver.cc
@@ -0,0 +1,159 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/renderer/media/webrtc/rtc_rtp_transceiver.h" + +#include "base/logging.h" +#include "base/memory/ref_counted.h" + +namespace content { + +RtpTransceiverState::RtpTransceiverState( + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner, + scoped_refptr<webrtc::RtpTransceiverInterface> webrtc_transceiver, + base::Optional<RtpSenderState> sender_state, + base::Optional<RtpReceiverState> receiver_state, + base::Optional<std::string> mid, + bool stopped, + webrtc::RtpTransceiverDirection direction, + base::Optional<webrtc::RtpTransceiverDirection> current_direction) + : main_task_runner_(std::move(main_task_runner)), + signaling_task_runner_(std::move(signaling_task_runner)), + webrtc_transceiver_(std::move(webrtc_transceiver)), + is_initialized_(false), + sender_state_(std::move(sender_state)), + receiver_state_(std::move(receiver_state)), + mid_(std::move(mid)), + stopped_(std::move(stopped)), + direction_(std::move(direction)), + current_direction_(std::move(current_direction)) { + DCHECK(main_task_runner_); + DCHECK(signaling_task_runner_); + DCHECK(webrtc_transceiver_); +} + +RtpTransceiverState::RtpTransceiverState(RtpTransceiverState&& other) + : main_task_runner_(other.main_task_runner_), + signaling_task_runner_(other.signaling_task_runner_), + webrtc_transceiver_(std::move(other.webrtc_transceiver_)), + is_initialized_(other.is_initialized_), + sender_state_(std::move(other.sender_state_)), + receiver_state_(std::move(other.receiver_state_)), + mid_(std::move(other.mid_)), + stopped_(std::move(other.stopped_)), + direction_(std::move(other.direction_)), + current_direction_(std::move(other.current_direction_)) { + // Explicitly null |other|'s task runners for use in destructor. + other.main_task_runner_ = nullptr; + other.signaling_task_runner_ = nullptr; +} + +RtpTransceiverState::~RtpTransceiverState() { + // It's OK to not be on the main thread if this state has been moved, in which + // case |main_task_runner_| is null. + DCHECK(!main_task_runner_ || main_task_runner_->BelongsToCurrentThread()); +} + +RtpTransceiverState& RtpTransceiverState::operator=( + RtpTransceiverState&& other) { + DCHECK_EQ(main_task_runner_, other.main_task_runner_); + DCHECK_EQ(signaling_task_runner_, other.signaling_task_runner_); + // Need to be on main thread for sender/receiver state's destructor that can + // be triggered by replacing . + DCHECK(main_task_runner_->BelongsToCurrentThread()); + // Explicitly null |other|'s task runners for use in destructor. + other.main_task_runner_ = nullptr; + other.signaling_task_runner_ = nullptr; + webrtc_transceiver_ = std::move(other.webrtc_transceiver_); + is_initialized_ = other.is_initialized_; + sender_state_ = std::move(other.sender_state_); + receiver_state_ = std::move(other.receiver_state_); + mid_ = std::move(other.mid_); + stopped_ = std::move(other.stopped_); + direction_ = std::move(other.direction_); + current_direction_ = std::move(other.current_direction_); + return *this; +} + +bool RtpTransceiverState::is_initialized() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return is_initialized_; +} + +void RtpTransceiverState::Initialize() { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + if (sender_state_) + sender_state_->Initialize(); + if (receiver_state_) + receiver_state_->Initialize(); + is_initialized_ = true; +} + +scoped_refptr<base::SingleThreadTaskRunner> +RtpTransceiverState::main_task_runner() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return main_task_runner_; +} + +scoped_refptr<base::SingleThreadTaskRunner> +RtpTransceiverState::signaling_task_runner() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return signaling_task_runner_; +} + +scoped_refptr<webrtc::RtpTransceiverInterface> +RtpTransceiverState::webrtc_transceiver() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return webrtc_transceiver_; +} + +const base::Optional<RtpSenderState>& RtpTransceiverState::sender_state() + const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return sender_state_; +} + +RtpSenderState RtpTransceiverState::MoveSenderState() { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + base::Optional<RtpSenderState> temp(base::nullopt); + sender_state_.swap(temp); + return *std::move(temp); +} + +const base::Optional<RtpReceiverState>& RtpTransceiverState::receiver_state() + const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return receiver_state_; +} + +RtpReceiverState RtpTransceiverState::MoveReceiverState() { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + base::Optional<RtpReceiverState> temp(base::nullopt); + receiver_state_.swap(temp); + return *std::move(temp); +} + +base::Optional<std::string> RtpTransceiverState::mid() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return mid_; +} + +bool RtpTransceiverState::stopped() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return stopped_; +} + +webrtc::RtpTransceiverDirection RtpTransceiverState::direction() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return direction_; +} + +base::Optional<webrtc::RtpTransceiverDirection> +RtpTransceiverState::current_direction() const { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + return current_direction_; +} + +} // namespace content
diff --git a/content/renderer/media/webrtc/rtc_rtp_transceiver.h b/content/renderer/media/webrtc/rtc_rtp_transceiver.h new file mode 100644 index 0000000..49d6315 --- /dev/null +++ b/content/renderer/media/webrtc/rtc_rtp_transceiver.h
@@ -0,0 +1,105 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_RENDERER_MEDIA_WEBRTC_RTC_RTP_TRANSCEIVER_H_ +#define CONTENT_RENDERER_MEDIA_WEBRTC_RTC_RTP_TRANSCEIVER_H_ + +#include "base/memory/scoped_refptr.h" +#include "base/optional.h" +#include "base/single_thread_task_runner.h" +#include "content/renderer/media/webrtc/rtc_rtp_receiver.h" +#include "content/renderer/media/webrtc/rtc_rtp_sender.h" +#include "third_party/webrtc/api/rtptransceiverinterface.h" + +namespace content { + +// This class represents the state of a transceiver; a snapshot of what a +// webrtc-layer transceiver looked like when it was inspected on the signaling +// thread such that this information can be moved to the main thread in a single +// PostTask. It is used to surface state changes to make the blink-layer +// transceiver up-to-date. +// +// Blink objects live on the main thread and webrtc objects live on the +// signaling thread. If multiple asynchronous operations begin execution on the +// main thread they are posted and executed in order on the signaling thread. +// For example, operation A and operation B are called in JavaScript. When A is +// done on the signaling thread, webrtc object states will be updated. A +// callback is posted to the main thread so that blink objects can be updated to +// match the result of operation A. But if callback A tries to inspect the +// webrtc objects from the main thread this requires posting back to the +// signaling thread and waiting, which also includes waiting for the previously +// posted task: operation B. Inspecting the webrtc object like this does not +// guarantee you to get the state of operation A. +// +// As such, all state changes associated with an operation have to be surfaced +// in the same callback. This includes copying any states into a separate object +// so that it can be inspected on the main thread without any additional thread +// hops. +// +// The RtpTransceiverState is a snapshot of what the +// webrtc::RtpTransceiverInterface looked like when the RtpTransceiverState was +// created on the signaling thread. It also takes care of initializing sender +// and receiver states, including their track adapters such that we have access +// to a blink track corresponding to the webrtc tracks of the sender and +// receiver. +// +// Except for initialization logic and operator=(), the RtpTransceiverState is +// immutable and only accessible on the main thread. +// +// TODO(hbos): [Onion Soup] When the transceiver implementation is moved to +// blink this will be part of the blink transceiver instead of the content +// transceiver. https://crbug.com/787254 +class CONTENT_EXPORT RtpTransceiverState { + public: + RtpTransceiverState( + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner, + scoped_refptr<webrtc::RtpTransceiverInterface> webrtc_transceiver, + base::Optional<RtpSenderState> sender_state, + base::Optional<RtpReceiverState> receiver_state, + base::Optional<std::string> mid, + bool stopped, + webrtc::RtpTransceiverDirection direction, + base::Optional<webrtc::RtpTransceiverDirection> current_direction); + RtpTransceiverState(RtpTransceiverState&&); + RtpTransceiverState(const RtpTransceiverState&) = delete; + ~RtpTransceiverState(); + + // This is intended to be used for moving the object from the signaling thread + // to the main thread and as such has no thread checks. Once moved to the main + // this should only be invoked on the main thread. + RtpTransceiverState& operator=(RtpTransceiverState&&); + RtpTransceiverState& operator=(const RtpTransceiverState&) = delete; + + bool is_initialized() const; + void Initialize(); + + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner() const; + scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner() const; + scoped_refptr<webrtc::RtpTransceiverInterface> webrtc_transceiver() const; + const base::Optional<RtpSenderState>& sender_state() const; + RtpSenderState MoveSenderState(); + const base::Optional<RtpReceiverState>& receiver_state() const; + RtpReceiverState MoveReceiverState(); + base::Optional<std::string> mid() const; + bool stopped() const; + webrtc::RtpTransceiverDirection direction() const; + base::Optional<webrtc::RtpTransceiverDirection> current_direction() const; + + private: + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; + scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner_; + scoped_refptr<webrtc::RtpTransceiverInterface> webrtc_transceiver_; + bool is_initialized_; + base::Optional<RtpSenderState> sender_state_; + base::Optional<RtpReceiverState> receiver_state_; + base::Optional<std::string> mid_; + bool stopped_; + webrtc::RtpTransceiverDirection direction_; + base::Optional<webrtc::RtpTransceiverDirection> current_direction_; +}; + +} // namespace content + +#endif // CONTENT_RENDERER_MEDIA_WEBRTC_RTC_RTP_TRANSCEIVER_H_
diff --git a/content/renderer/media/webrtc/rtc_rtp_transceiver_unittest.cc b/content/renderer/media/webrtc/rtc_rtp_transceiver_unittest.cc new file mode 100644 index 0000000..de3d32d --- /dev/null +++ b/content/renderer/media/webrtc/rtc_rtp_transceiver_unittest.cc
@@ -0,0 +1,224 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/renderer/media/webrtc/rtc_rtp_transceiver.h" + +#include <memory> + +#include "base/logging.h" +#include "base/memory/ref_counted.h" +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" +#include "base/single_thread_task_runner.h" +#include "base/synchronization/waitable_event.h" +#include "build/build_config.h" +#include "content/child/child_process.h" +#include "content/renderer/media/stream/media_stream_audio_source.h" +#include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h" +#include "content/renderer/media/webrtc/mock_peer_connection_impl.h" +#include "content/renderer/media/webrtc/webrtc_media_stream_adapter_map.h" +#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h" +#include "content/renderer/media/webrtc/webrtc_util.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h" +#include "third_party/blink/public/platform/web_media_stream_source.h" +#include "third_party/blink/public/platform/web_string.h" +#include "third_party/blink/public/web/web_heap.h" +#include "third_party/webrtc/api/test/mock_rtpreceiver.h" +#include "third_party/webrtc/api/test/mock_rtpsender.h" + +namespace content { + +class RTCRtpTransceiverTest : public ::testing::Test { + public: + void SetUp() override { + dependency_factory_.reset(new MockPeerConnectionDependencyFactory()); + main_task_runner_ = blink::scheduler::GetSingleThreadTaskRunnerForTesting(); + track_map_ = new WebRtcMediaStreamTrackAdapterMap(dependency_factory_.get(), + main_task_runner_); + peer_connection_ = new rtc::RefCountedObject<MockPeerConnectionImpl>( + dependency_factory_.get(), nullptr); + } + + void TearDown() override { + // Syncing up with the signaling thread ensures any pending operations on + // that thread are executed. If they post back to the main thread, such as + // the sender or receiver destructor traits, this is allowed to execute + // before the test shuts down the threads. + SyncWithSignalingThread(); + blink::WebHeap::CollectAllGarbageForTesting(); + } + + // Wait for the signaling thread to perform any queued tasks, executing tasks + // posted to the current thread in the meantime while waiting. + void SyncWithSignalingThread() const { + base::RunLoop run_loop; + dependency_factory_->GetWebRtcSignalingThread()->PostTask( + FROM_HERE, run_loop.QuitClosure()); + run_loop.Run(); + } + + scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner() const { + return dependency_factory_->GetWebRtcSignalingThread(); + } + + std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> + CreateLocalTrackAndAdapter(const std::string& id) { + return track_map_->GetOrCreateLocalTrackAdapter(CreateBlinkLocalTrack(id)); + } + + std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> + CreateRemoteTrackAndAdapter(const std::string& id) { + rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track = + MockWebRtcAudioTrack::Create(id).get(); + std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref; + base::RunLoop run_loop; + signaling_task_runner()->PostTask( + FROM_HERE, + base::BindOnce( + &RTCRtpTransceiverTest::CreateRemoteTrackAdapterOnSignalingThread, + base::Unretained(this), std::move(webrtc_track), + base::Unretained(&track_ref), base::Unretained(&run_loop))); + run_loop.Run(); + DCHECK(track_ref); + return track_ref; + } + + rtc::scoped_refptr<webrtc::RtpTransceiverInterface> CreateWebRtcTransceiver( + rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> local_track, + const std::string& local_stream_id, + rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> remote_track, + const std::string& remote_stream_id) { + DCHECK_EQ(local_track->kind(), remote_track->kind()); + return new rtc::RefCountedObject<FakeRtpTransceiver>( + local_track->kind() == webrtc::MediaStreamTrackInterface::kAudioKind + ? cricket::MEDIA_TYPE_AUDIO + : cricket::MEDIA_TYPE_VIDEO, + CreateWebRtcSender(local_track, local_stream_id), + CreateWebRtcReceiver(remote_track, remote_stream_id)); + } + + rtc::scoped_refptr<webrtc::RtpSenderInterface> CreateWebRtcSender( + rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track, + const std::string& stream_id) { + return new rtc::RefCountedObject<FakeRtpSender>( + std::move(track), std::vector<std::string>({stream_id})); + } + + rtc::scoped_refptr<webrtc::RtpReceiverInterface> CreateWebRtcReceiver( + rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track, + const std::string& stream_id) { + rtc::scoped_refptr<webrtc::MediaStreamInterface> remote_stream( + new rtc::RefCountedObject<MockMediaStream>(stream_id)); + return new rtc::RefCountedObject<FakeRtpReceiver>( + track.get(), + std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>( + {remote_stream})); + } + + RtpTransceiverState CreateTransceiverState( + rtc::scoped_refptr<webrtc::RtpTransceiverInterface> webrtc_transceiver, + std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> + sender_track_ref, + std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> + receiver_track_ref) { + std::vector<std::string> receiver_stream_ids; + for (const auto& stream : webrtc_transceiver->receiver()->streams()) { + receiver_stream_ids.push_back(stream->id()); + } + return RtpTransceiverState( + main_task_runner_, signaling_task_runner(), webrtc_transceiver.get(), + RtpSenderState(main_task_runner_, signaling_task_runner(), + webrtc_transceiver->sender().get(), + std::move(sender_track_ref), + webrtc_transceiver->sender()->stream_ids()), + RtpReceiverState(main_task_runner_, signaling_task_runner(), + webrtc_transceiver->receiver().get(), + std::move(receiver_track_ref), + std::move(receiver_stream_ids)), + ToBaseOptional(webrtc_transceiver->mid()), + webrtc_transceiver->stopped(), webrtc_transceiver->direction(), + ToBaseOptional(webrtc_transceiver->current_direction())); + } + + protected: + blink::WebMediaStreamTrack CreateBlinkLocalTrack(const std::string& id) { + blink::WebMediaStreamSource web_source; + web_source.Initialize( + blink::WebString::FromUTF8(id), blink::WebMediaStreamSource::kTypeAudio, + blink::WebString::FromUTF8("local_audio_track"), false); + MediaStreamAudioSource* audio_source = new MediaStreamAudioSource(true); + // Takes ownership of |audio_source|. + web_source.SetExtraData(audio_source); + + blink::WebMediaStreamTrack web_track; + web_track.Initialize(web_source.Id(), web_source); + audio_source->ConnectToTrack(web_track); + return web_track; + } + + void CreateRemoteTrackAdapterOnSignalingThread( + rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track, + std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>* track_ref, + base::RunLoop* run_loop) { + *track_ref = track_map_->GetOrCreateRemoteTrackAdapter(webrtc_track.get()); + run_loop->Quit(); + } + + private: + base::MessageLoop message_loop_; + + protected: + std::unique_ptr<MockPeerConnectionDependencyFactory> dependency_factory_; + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; + scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_map_; + rtc::scoped_refptr<MockPeerConnectionImpl> peer_connection_; +}; + +TEST_F(RTCRtpTransceiverTest, InitializeTransceiverState) { + auto local_track_adapter = CreateLocalTrackAndAdapter("local_track"); + auto remote_track_adapter = CreateRemoteTrackAndAdapter("remote_track"); + auto webrtc_transceiver = CreateWebRtcTransceiver( + local_track_adapter->webrtc_track(), "local_stream", + remote_track_adapter->webrtc_track(), "remote_stream"); + RtpTransceiverState transceiver_state = + CreateTransceiverState(webrtc_transceiver, std::move(local_track_adapter), + std::move(remote_track_adapter)); + EXPECT_FALSE(transceiver_state.is_initialized()); + transceiver_state.Initialize(); + + EXPECT_TRUE(transceiver_state.is_initialized()); + // Inspect sender states. + const auto& sender_state = transceiver_state.sender_state(); + EXPECT_TRUE(sender_state); + EXPECT_TRUE(sender_state->is_initialized()); + const auto& webrtc_sender = webrtc_transceiver->sender(); + EXPECT_EQ(sender_state->webrtc_sender().get(), webrtc_sender.get()); + EXPECT_TRUE(sender_state->track_ref()->is_initialized()); + EXPECT_EQ(sender_state->track_ref()->webrtc_track(), + webrtc_sender->track().get()); + EXPECT_EQ(sender_state->stream_ids(), webrtc_sender->stream_ids()); + // Inspect receiver states. + const auto& receiver_state = transceiver_state.receiver_state(); + EXPECT_TRUE(receiver_state); + EXPECT_TRUE(receiver_state->is_initialized()); + const auto& webrtc_receiver = webrtc_transceiver->receiver(); + EXPECT_EQ(receiver_state->webrtc_receiver().get(), webrtc_receiver.get()); + EXPECT_TRUE(receiver_state->track_ref()->is_initialized()); + EXPECT_EQ(receiver_state->track_ref()->webrtc_track(), + webrtc_receiver->track().get()); + std::vector<std::string> receiver_stream_ids; + for (const auto& stream : webrtc_receiver->streams()) { + receiver_stream_ids.push_back(stream->id()); + } + EXPECT_EQ(receiver_state->stream_ids(), receiver_stream_ids); + // Inspect transceiver states. + EXPECT_TRUE(transceiver_state.mid() == webrtc_transceiver->mid()); + EXPECT_EQ(transceiver_state.stopped(), webrtc_transceiver->stopped()); + EXPECT_TRUE(transceiver_state.direction() == webrtc_transceiver->direction()); + EXPECT_TRUE(transceiver_state.current_direction() == + webrtc_transceiver->current_direction()); +} + +} // namespace content
diff --git a/content/renderer/media/webrtc/transceiver_state_surfacer.cc b/content/renderer/media/webrtc/transceiver_state_surfacer.cc new file mode 100644 index 0000000..8caf864 --- /dev/null +++ b/content/renderer/media/webrtc/transceiver_state_surfacer.cc
@@ -0,0 +1,217 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/renderer/media/webrtc/transceiver_state_surfacer.h" + +#include "content/renderer/media/webrtc/webrtc_util.h" +#include "third_party/webrtc/api/optional.h" +#include "third_party/webrtc/api/rtptransceiverinterface.h" + +namespace content { + +TransceiverStateSurfacer::TransceiverStateSurfacer( + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner) + : main_task_runner_(std::move(main_task_runner)), + signaling_task_runner_(std::move(signaling_task_runner)), + is_initialized_(false), + states_obtained_(false) { + DCHECK(main_task_runner_); + DCHECK(signaling_task_runner_); +} + +TransceiverStateSurfacer::TransceiverStateSurfacer( + TransceiverStateSurfacer&& other) + : main_task_runner_(other.main_task_runner_), + signaling_task_runner_(other.signaling_task_runner_), + is_initialized_(other.is_initialized_), + states_obtained_(other.states_obtained_) { + // Explicitly null |other|'s task runners for use in destructor. + other.main_task_runner_ = nullptr; + other.signaling_task_runner_ = nullptr; +} + +TransceiverStateSurfacer::~TransceiverStateSurfacer() { + // It's OK to not be on the main thread if this object has been moved, in + // which case |main_task_runner_| is null. + DCHECK(!main_task_runner_ || main_task_runner_->BelongsToCurrentThread()); +} + +TransceiverStateSurfacer& TransceiverStateSurfacer::operator=( + TransceiverStateSurfacer&& other) { + main_task_runner_ = other.main_task_runner_; + signaling_task_runner_ = other.signaling_task_runner_; + states_obtained_ = other.states_obtained_; + // Explicitly null |other|'s task runners for use in destructor. + other.main_task_runner_ = nullptr; + other.signaling_task_runner_ = nullptr; + return *this; +} + +void TransceiverStateSurfacer::Initialize( + scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map, + std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> + webrtc_transceivers) { + DCHECK(signaling_task_runner_->BelongsToCurrentThread()); + DCHECK(!is_initialized_); + for (auto& webrtc_transceiver : webrtc_transceivers) { + // Create the sender state. + base::Optional<RtpSenderState> sender_state; + auto webrtc_sender = webrtc_transceiver->sender(); + if (webrtc_sender) { + std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> + sender_track_ref; + if (webrtc_sender->track()) { + sender_track_ref = + track_adapter_map->GetLocalTrackAdapter(webrtc_sender->track()); + DCHECK(sender_track_ref); + } + sender_state = RtpSenderState( + main_task_runner_, signaling_task_runner_, webrtc_sender.get(), + std::move(sender_track_ref), webrtc_sender->stream_ids()); + } + // Create the receiver state. + base::Optional<RtpReceiverState> receiver_state; + auto webrtc_receiver = webrtc_transceiver->receiver(); + if (webrtc_receiver) { + DCHECK(webrtc_receiver->track()); + auto receiver_track_ref = + track_adapter_map->GetOrCreateRemoteTrackAdapter( + webrtc_receiver->track().get()); + DCHECK(receiver_track_ref); + std::vector<std::string> receiver_stream_ids; + for (auto& stream : webrtc_receiver->streams()) { + receiver_stream_ids.push_back(stream->id()); + } + receiver_state = RtpReceiverState( + main_task_runner_, signaling_task_runner_, webrtc_receiver.get(), + std::move(receiver_track_ref), std::move(receiver_stream_ids)); + } + // Create the transceiver state. + transceiver_states_.push_back(RtpTransceiverState( + main_task_runner_, signaling_task_runner_, webrtc_transceiver.get(), + std::move(sender_state), std::move(receiver_state), + ToBaseOptional(webrtc_transceiver->mid()), + webrtc_transceiver->stopped(), webrtc_transceiver->direction(), + ToBaseOptional(webrtc_transceiver->current_direction()))); + } + is_initialized_ = true; +} + +std::vector<RtpTransceiverState> TransceiverStateSurfacer::ObtainStates() { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + DCHECK(is_initialized_); + for (auto& transceiver_state : transceiver_states_) + transceiver_state.Initialize(); + states_obtained_ = true; + return std::move(transceiver_states_); +} + +SurfaceSenderStateOnly::SurfaceSenderStateOnly( + rtc::scoped_refptr<webrtc::RtpSenderInterface> sender) + : sender_(std::move(sender)) { + DCHECK(sender_); +} + +SurfaceSenderStateOnly::~SurfaceSenderStateOnly() {} + +cricket::MediaType SurfaceSenderStateOnly::media_type() const { + return sender_->media_type(); +} + +absl::optional<std::string> SurfaceSenderStateOnly::mid() const { + return absl::nullopt; +} + +rtc::scoped_refptr<webrtc::RtpSenderInterface> SurfaceSenderStateOnly::sender() + const { + return sender_; +} + +rtc::scoped_refptr<webrtc::RtpReceiverInterface> +SurfaceSenderStateOnly::receiver() const { + return nullptr; +} + +bool SurfaceSenderStateOnly::stopped() const { + return false; +} + +webrtc::RtpTransceiverDirection SurfaceSenderStateOnly::direction() const { + return webrtc::RtpTransceiverDirection::kSendOnly; +} + +void SurfaceSenderStateOnly::SetDirection( + webrtc::RtpTransceiverDirection new_direction) { + NOTIMPLEMENTED(); +} + +absl::optional<webrtc::RtpTransceiverDirection> +SurfaceSenderStateOnly::current_direction() const { + return absl::nullopt; +} + +void SurfaceSenderStateOnly::Stop() { + NOTIMPLEMENTED(); +} + +void SurfaceSenderStateOnly::SetCodecPreferences( + rtc::ArrayView<webrtc::RtpCodecCapability> codecs) { + NOTIMPLEMENTED(); +} + +SurfaceReceiverStateOnly::SurfaceReceiverStateOnly( + rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver) + : receiver_(std::move(receiver)) { + DCHECK(receiver_); +} + +SurfaceReceiverStateOnly::~SurfaceReceiverStateOnly() {} + +cricket::MediaType SurfaceReceiverStateOnly::media_type() const { + return receiver_->media_type(); +} + +absl::optional<std::string> SurfaceReceiverStateOnly::mid() const { + return absl::nullopt; +} + +rtc::scoped_refptr<webrtc::RtpSenderInterface> +SurfaceReceiverStateOnly::sender() const { + return nullptr; +} + +rtc::scoped_refptr<webrtc::RtpReceiverInterface> +SurfaceReceiverStateOnly::receiver() const { + return receiver_; +} + +bool SurfaceReceiverStateOnly::stopped() const { + return false; +} + +webrtc::RtpTransceiverDirection SurfaceReceiverStateOnly::direction() const { + return webrtc::RtpTransceiverDirection::kRecvOnly; +} + +void SurfaceReceiverStateOnly::SetDirection( + webrtc::RtpTransceiverDirection new_direction) { + NOTIMPLEMENTED(); +} + +absl::optional<webrtc::RtpTransceiverDirection> +SurfaceReceiverStateOnly::current_direction() const { + return absl::nullopt; +} + +void SurfaceReceiverStateOnly::Stop() { + NOTIMPLEMENTED(); +} + +void SurfaceReceiverStateOnly::SetCodecPreferences( + rtc::ArrayView<webrtc::RtpCodecCapability> codecs) { + NOTIMPLEMENTED(); +} + +} // namespace content
diff --git a/content/renderer/media/webrtc/transceiver_state_surfacer.h b/content/renderer/media/webrtc/transceiver_state_surfacer.h new file mode 100644 index 0000000..ab7cdfeb --- /dev/null +++ b/content/renderer/media/webrtc/transceiver_state_surfacer.h
@@ -0,0 +1,112 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_RENDERER_MEDIA_WEBRTC_TRANSCEIVER_STATE_SURFACER_H_ +#define CONTENT_RENDERER_MEDIA_WEBRTC_TRANSCEIVER_STATE_SURFACER_H_ + +#include "content/renderer/media/webrtc/rtc_rtp_transceiver.h" +#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h" +#include "third_party/webrtc/api/rtptransceiverinterface.h" +#include "third_party/webrtc/rtc_base/refcount.h" +#include "third_party/webrtc/rtc_base/refcountedobject.h" + +namespace content { + +// Takes care of creating and initializing transceiver states (including sender +// and receiver states). This is usable for both blocking and non-blocking calls +// to the webrtc signaling thread. +// +// The surfacer is initialized on the signaling thread and states are obtained +// on the main thread. It is designed to be initialized and handed off; it is +// not thread safe for concurrent thread usage. +class CONTENT_EXPORT TransceiverStateSurfacer { + public: + TransceiverStateSurfacer( + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner); + TransceiverStateSurfacer(TransceiverStateSurfacer&&); + TransceiverStateSurfacer(const TransceiverStateSurfacer&) = delete; + ~TransceiverStateSurfacer(); + + // This is intended to be used for moving the object from the signaling thread + // to the main thread and as such has no thread checks. Once moved to the main + // this should only be invoked on the main thread. + TransceiverStateSurfacer& operator=(TransceiverStateSurfacer&&); + TransceiverStateSurfacer& operator=(const TransceiverStateSurfacer&) = delete; + + bool is_initialized() const { return is_initialized_; } + + // Must be invoked on the signaling thread. + void Initialize( + scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map, + std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> + transceivers); + + // Must be invoked on the main thread. + std::vector<RtpTransceiverState> ObtainStates(); + + protected: + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; + scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner_; + bool is_initialized_; + bool states_obtained_; + std::vector<RtpTransceiverState> transceiver_states_; +}; + +// A dummy implementation of a transceiver used to surface sender state +// information only. It is not thread safe, only designed to be passed on to +// TransceiverStateSurfacer::Initialize(). +class CONTENT_EXPORT SurfaceSenderStateOnly + : public rtc::RefCountedObject<webrtc::RtpTransceiverInterface> { + public: + SurfaceSenderStateOnly(rtc::scoped_refptr<webrtc::RtpSenderInterface> sender); + ~SurfaceSenderStateOnly() override; + + cricket::MediaType media_type() const override; + absl::optional<std::string> mid() const override; + rtc::scoped_refptr<webrtc::RtpSenderInterface> sender() const override; + rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver() const override; + bool stopped() const override; + webrtc::RtpTransceiverDirection direction() const override; + void SetDirection(webrtc::RtpTransceiverDirection new_direction) override; + absl::optional<webrtc::RtpTransceiverDirection> current_direction() + const override; + void Stop() override; + void SetCodecPreferences( + rtc::ArrayView<webrtc::RtpCodecCapability> codecs) override; + + private: + rtc::scoped_refptr<webrtc::RtpSenderInterface> sender_; +}; + +// A dummy implementation of a transceiver used to surface receiver state +// information only. It is not thread safe, only designed to be passed on to +// TransceiverStateSurfacer::Initialize(). +class CONTENT_EXPORT SurfaceReceiverStateOnly + : public rtc::RefCountedObject<webrtc::RtpTransceiverInterface> { + public: + SurfaceReceiverStateOnly( + rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver); + ~SurfaceReceiverStateOnly() override; + + cricket::MediaType media_type() const override; + absl::optional<std::string> mid() const override; + rtc::scoped_refptr<webrtc::RtpSenderInterface> sender() const override; + rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver() const override; + bool stopped() const override; + webrtc::RtpTransceiverDirection direction() const override; + void SetDirection(webrtc::RtpTransceiverDirection new_direction) override; + absl::optional<webrtc::RtpTransceiverDirection> current_direction() + const override; + void Stop() override; + void SetCodecPreferences( + rtc::ArrayView<webrtc::RtpCodecCapability> codecs) override; + + private: + rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver_; +}; + +} // namespace content + +#endif // CONTENT_RENDERER_MEDIA_WEBRTC_TRANSCEIVER_STATE_SURFACER_H_
diff --git a/content/renderer/media/webrtc/transceiver_state_surfacer_unittest.cc b/content/renderer/media/webrtc/transceiver_state_surfacer_unittest.cc new file mode 100644 index 0000000..8ff8abcd --- /dev/null +++ b/content/renderer/media/webrtc/transceiver_state_surfacer_unittest.cc
@@ -0,0 +1,292 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/renderer/media/webrtc/transceiver_state_surfacer.h" + +#include <memory> +#include <tuple> + +#include "base/memory/ref_counted.h" +#include "base/run_loop.h" +#include "base/single_thread_task_runner.h" +#include "base/synchronization/waitable_event.h" +#include "base/test/scoped_task_environment.h" +#include "content/child/child_process.h" +#include "content/renderer/media/stream/media_stream_audio_source.h" +#include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h" +#include "content/renderer/media/webrtc/mock_peer_connection_impl.h" +#include "content/renderer/media/webrtc/webrtc_util.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h" +#include "third_party/blink/public/platform/web_media_stream_source.h" +#include "third_party/blink/public/platform/web_media_stream_track.h" +#include "third_party/blink/public/platform/web_string.h" +#include "third_party/blink/public/web/web_heap.h" + +namespace content { + +class TransceiverStateSurfacerTest : public ::testing::Test { + public: + void SetUp() override { + dependency_factory_.reset(new MockPeerConnectionDependencyFactory()); + main_task_runner_ = blink::scheduler::GetSingleThreadTaskRunnerForTesting(); + track_adapter_map_ = new WebRtcMediaStreamTrackAdapterMap( + dependency_factory_.get(), main_task_runner_); + surfacer_.reset(new TransceiverStateSurfacer(main_task_runner_, + signaling_task_runner())); + } + + void TearDown() override { + // Make sure posted tasks get a chance to execute or else the stuff is + // teared down while things are in flight. + base::RunLoop().RunUntilIdle(); + blink::WebHeap::CollectAllGarbageForTesting(); + } + + scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner() const { + return dependency_factory_->GetWebRtcSignalingThread(); + } + + std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> + CreateLocalTrackAndAdapter(const std::string& id) { + return track_adapter_map_->GetOrCreateLocalTrackAdapter( + CreateBlinkLocalTrack(id)); + } + + rtc::scoped_refptr<webrtc::RtpTransceiverInterface> CreateWebRtcTransceiver( + rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> local_track, + const std::string& local_stream_id, + const std::string& remote_track_id, + const std::string& remote_stream_id) { + return new rtc::RefCountedObject<FakeRtpTransceiver>( + local_track->kind() == webrtc::MediaStreamTrackInterface::kAudioKind + ? cricket::MEDIA_TYPE_AUDIO + : cricket::MEDIA_TYPE_VIDEO, + CreateWebRtcSender(local_track, local_stream_id), + CreateWebRtcReceiver(remote_track_id, remote_stream_id)); + } + + rtc::scoped_refptr<webrtc::RtpSenderInterface> CreateWebRtcSender( + rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> track, + const std::string& stream_id) { + return new rtc::RefCountedObject<FakeRtpSender>( + std::move(track), std::vector<std::string>({stream_id})); + } + + rtc::scoped_refptr<webrtc::RtpReceiverInterface> CreateWebRtcReceiver( + const std::string& track_id, + const std::string& stream_id) { + rtc::scoped_refptr<webrtc::AudioTrackInterface> remote_track = + MockWebRtcAudioTrack::Create(track_id).get(); + rtc::scoped_refptr<webrtc::MediaStreamInterface> remote_stream( + new rtc::RefCountedObject<MockMediaStream>(stream_id)); + return new rtc::RefCountedObject<FakeRtpReceiver>( + remote_track.get(), + std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>( + {remote_stream})); + } + + // Initializes the surfacer on the signaling thread and signals the waitable + // event when done. The WaitableEvent's Wait() blocks the main thread until + // initialization occurs. + std::unique_ptr<base::WaitableEvent> AsyncInitializeSurfacerWithWaitableEvent( + std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> + transceivers) { + std::unique_ptr<base::WaitableEvent> waitable_event(new base::WaitableEvent( + base::WaitableEvent::ResetPolicy::MANUAL, + base::WaitableEvent::InitialState::NOT_SIGNALED)); + signaling_task_runner()->PostTask( + FROM_HERE, + base::BindOnce( + &TransceiverStateSurfacerTest:: + AsyncInitializeSurfacerWithWaitableEventOnSignalingThread, + base::Unretained(this), std::move(transceivers), + waitable_event.get())); + return waitable_event; + } + + // Initializes the surfacer on the signaling thread and posts back to the main + // thread to execute the callback when done. The RunLoop quits after the + // callback is executed. Use the RunLoop's Run() method to allow the posted + // task (such as the callback) to be executed while waiting. The caller must + // let the loop Run() before destroying it. + std::unique_ptr<base::RunLoop> AsyncInitializeSurfacerWithCallback( + std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> + transceivers, + base::OnceCallback<void()> callback) { + std::unique_ptr<base::RunLoop> run_loop(new base::RunLoop()); + signaling_task_runner()->PostTask( + FROM_HERE, + base::BindOnce(&TransceiverStateSurfacerTest:: + AsyncInitializeSurfacerWithCallbackOnSignalingThread, + base::Unretained(this), std::move(transceivers), + std::move(callback), run_loop.get())); + return run_loop; + } + + void ObtainStatesAndExpectInitialized( + rtc::scoped_refptr<webrtc::RtpTransceiverInterface> webrtc_transceiver) { + auto transceiver_states = surfacer_->ObtainStates(); + EXPECT_EQ(1u, transceiver_states.size()); + auto& transceiver_state = transceiver_states[0]; + EXPECT_EQ(transceiver_state.webrtc_transceiver().get(), + webrtc_transceiver.get()); + // Inspect sender states. + const auto& sender_state = transceiver_state.sender_state(); + EXPECT_TRUE(sender_state); + EXPECT_TRUE(sender_state->is_initialized()); + const auto& webrtc_sender = webrtc_transceiver->sender(); + EXPECT_EQ(sender_state->webrtc_sender().get(), webrtc_sender.get()); + EXPECT_TRUE(sender_state->track_ref()->is_initialized()); + EXPECT_EQ(sender_state->track_ref()->webrtc_track(), + webrtc_sender->track().get()); + EXPECT_EQ(sender_state->stream_ids(), webrtc_sender->stream_ids()); + // Inspect receiver states. + const auto& receiver_state = transceiver_state.receiver_state(); + EXPECT_TRUE(receiver_state); + EXPECT_TRUE(receiver_state->is_initialized()); + const auto& webrtc_receiver = webrtc_transceiver->receiver(); + EXPECT_EQ(receiver_state->webrtc_receiver().get(), webrtc_receiver.get()); + EXPECT_TRUE(receiver_state->track_ref()->is_initialized()); + EXPECT_EQ(receiver_state->track_ref()->webrtc_track(), + webrtc_receiver->track().get()); + std::vector<std::string> receiver_stream_ids; + for (const auto& stream : webrtc_receiver->streams()) { + receiver_stream_ids.push_back(stream->id()); + } + EXPECT_EQ(receiver_state->stream_ids(), receiver_stream_ids); + // Inspect transceiver states. + EXPECT_TRUE(transceiver_state.mid() == webrtc_transceiver->mid()); + EXPECT_EQ(transceiver_state.stopped(), webrtc_transceiver->stopped()); + EXPECT_TRUE(transceiver_state.direction() == + webrtc_transceiver->direction()); + EXPECT_TRUE(transceiver_state.current_direction() == + webrtc_transceiver->current_direction()); + } + + private: + blink::WebMediaStreamTrack CreateBlinkLocalTrack(const std::string& id) { + blink::WebMediaStreamSource web_source; + web_source.Initialize( + blink::WebString::FromUTF8(id), blink::WebMediaStreamSource::kTypeAudio, + blink::WebString::FromUTF8("local_audio_track"), false); + MediaStreamAudioSource* audio_source = new MediaStreamAudioSource(true); + // Takes ownership of |audio_source|. + web_source.SetExtraData(audio_source); + + blink::WebMediaStreamTrack web_track; + web_track.Initialize(web_source.Id(), web_source); + audio_source->ConnectToTrack(web_track); + return web_track; + } + + void AsyncInitializeSurfacerWithWaitableEventOnSignalingThread( + std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> + transceivers, + base::WaitableEvent* waitable_event) { + DCHECK(signaling_task_runner()->BelongsToCurrentThread()); + surfacer_->Initialize(track_adapter_map_, std::move(transceivers)); + waitable_event->Signal(); + } + + void AsyncInitializeSurfacerWithCallbackOnSignalingThread( + std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> + transceivers, + base::OnceCallback<void()> callback, + base::RunLoop* run_loop) { + DCHECK(signaling_task_runner()->BelongsToCurrentThread()); + surfacer_->Initialize(track_adapter_map_, std::move(transceivers)); + main_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&TransceiverStateSurfacerTest:: + AsyncInitializeSurfacerWithCallbackOnMainThread, + base::Unretained(this), std::move(callback), run_loop)); + } + + void AsyncInitializeSurfacerWithCallbackOnMainThread( + base::OnceCallback<void()> callback, + base::RunLoop* run_loop) { + DCHECK(main_task_runner_->BelongsToCurrentThread()); + DCHECK(surfacer_->is_initialized()); + std::move(callback).Run(); + run_loop->Quit(); + } + + base::test::ScopedTaskEnvironment scoped_task_environment_; + + protected: + std::unique_ptr<MockPeerConnectionDependencyFactory> dependency_factory_; + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; + scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map_; + std::unique_ptr<TransceiverStateSurfacer> surfacer_; +}; + +TEST_F(TransceiverStateSurfacerTest, SurfaceTransceiverBlockingly) { + auto local_track_adapter = CreateLocalTrackAndAdapter("local_track"); + auto webrtc_transceiver = + CreateWebRtcTransceiver(local_track_adapter->webrtc_track(), + "local_stream", "remote_track", "remote_stream"); + auto waitable_event = + AsyncInitializeSurfacerWithWaitableEvent({webrtc_transceiver}); + waitable_event->Wait(); + ObtainStatesAndExpectInitialized(webrtc_transceiver); +} + +TEST_F(TransceiverStateSurfacerTest, SurfaceTransceiverInCallback) { + auto local_track_adapter = CreateLocalTrackAndAdapter("local_track"); + auto webrtc_transceiver = + CreateWebRtcTransceiver(local_track_adapter->webrtc_track(), + "local_stream", "remote_track", "remote_stream"); + auto run_loop = AsyncInitializeSurfacerWithCallback( + {webrtc_transceiver}, + base::BindOnce( + &TransceiverStateSurfacerTest::ObtainStatesAndExpectInitialized, + base::Unretained(this), webrtc_transceiver)); + run_loop->Run(); +} + +TEST_F(TransceiverStateSurfacerTest, SurfaceSenderStateOnly) { + auto local_track_adapter = CreateLocalTrackAndAdapter("local_track"); + auto webrtc_sender = + CreateWebRtcSender(local_track_adapter->webrtc_track(), "local_stream"); + auto waitable_event = AsyncInitializeSurfacerWithWaitableEvent( + {new SurfaceSenderStateOnly(webrtc_sender)}); + waitable_event->Wait(); + auto transceiver_states = surfacer_->ObtainStates(); + EXPECT_EQ(1u, transceiver_states.size()); + auto& transceiver_state = transceiver_states[0]; + EXPECT_TRUE(transceiver_state.sender_state()); + EXPECT_TRUE(transceiver_state.sender_state()->is_initialized()); + EXPECT_FALSE(transceiver_state.receiver_state()); + // Expect transceiver members be be missing for optional members and have + // sensible values for non-optional members. + EXPECT_FALSE(transceiver_state.mid()); + EXPECT_FALSE(transceiver_state.stopped()); + EXPECT_EQ(transceiver_state.direction(), + webrtc::RtpTransceiverDirection::kSendOnly); + EXPECT_FALSE(transceiver_state.current_direction()); +} + +TEST_F(TransceiverStateSurfacerTest, SurfaceReceiverStateOnly) { + auto local_track_adapter = CreateLocalTrackAndAdapter("local_track"); + auto webrtc_receiver = CreateWebRtcReceiver("remote_track", "remote_stream"); + auto waitable_event = AsyncInitializeSurfacerWithWaitableEvent( + {new SurfaceReceiverStateOnly(webrtc_receiver)}); + waitable_event->Wait(); + auto transceiver_states = surfacer_->ObtainStates(); + EXPECT_EQ(1u, transceiver_states.size()); + auto& transceiver_state = transceiver_states[0]; + EXPECT_FALSE(transceiver_state.sender_state()); + EXPECT_TRUE(transceiver_state.receiver_state()); + EXPECT_TRUE(transceiver_state.receiver_state()->is_initialized()); + // Expect transceiver members be be missing for optional members and have + // sensible values for non-optional members. + EXPECT_FALSE(transceiver_state.mid()); + EXPECT_FALSE(transceiver_state.stopped()); + EXPECT_EQ(transceiver_state.direction(), + webrtc::RtpTransceiverDirection::kRecvOnly); + EXPECT_FALSE(transceiver_state.current_direction()); +} + +} // namespace content
diff --git a/content/renderer/media/webrtc/webrtc_set_remote_description_observer.cc b/content/renderer/media/webrtc/webrtc_set_remote_description_observer.cc index 0b936ee..a61c952 100644 --- a/content/renderer/media/webrtc/webrtc_set_remote_description_observer.cc +++ b/content/renderer/media/webrtc/webrtc_set_remote_description_observer.cc
@@ -8,22 +8,6 @@ namespace content { -WebRtcReceiverState::WebRtcReceiverState( - scoped_refptr<webrtc::RtpReceiverInterface> receiver, - std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref, - std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>> - stream_refs) - : receiver(std::move(receiver)), - track_ref(std::move(track_ref)), - stream_refs(std::move(stream_refs)) {} - -WebRtcReceiverState::WebRtcReceiverState(WebRtcReceiverState&& other) = default; - -WebRtcReceiverState& WebRtcReceiverState::operator=( - WebRtcReceiverState&& other) = default; - -WebRtcReceiverState::~WebRtcReceiverState() {} - WebRtcSetRemoteDescriptionObserver::States::States() : signaling_state( webrtc::PeerConnectionInterface::SignalingState::kClosed) {} @@ -41,42 +25,33 @@ return *this; } -void WebRtcSetRemoteDescriptionObserver::States::CheckInvariants() const { - // Invariants: - // - All receiver states have a stream ref - // - All receiver states refer to streams that are non-null. - for (auto& receiver_state : receiver_states) { - for (auto& stream_ref : receiver_state.stream_refs) { - CHECK(stream_ref); - CHECK(!stream_ref->adapter().web_stream().IsNull()); - } - } -} - WebRtcSetRemoteDescriptionObserver::WebRtcSetRemoteDescriptionObserver() {} WebRtcSetRemoteDescriptionObserver::~WebRtcSetRemoteDescriptionObserver() {} scoped_refptr<WebRtcSetRemoteDescriptionObserverHandler> WebRtcSetRemoteDescriptionObserverHandler::Create( - scoped_refptr<base::SingleThreadTaskRunner> main_thread, + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner, scoped_refptr<webrtc::PeerConnectionInterface> pc, - scoped_refptr<WebRtcMediaStreamAdapterMap> stream_adapter_map, + scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map, scoped_refptr<WebRtcSetRemoteDescriptionObserver> observer) { return new rtc::RefCountedObject<WebRtcSetRemoteDescriptionObserverHandler>( - std::move(main_thread), std::move(pc), std::move(stream_adapter_map), - std::move(observer)); + std::move(main_task_runner), std::move(signaling_task_runner), + std::move(pc), std::move(track_adapter_map), std::move(observer)); } WebRtcSetRemoteDescriptionObserverHandler:: WebRtcSetRemoteDescriptionObserverHandler( - scoped_refptr<base::SingleThreadTaskRunner> main_thread, + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner, scoped_refptr<webrtc::PeerConnectionInterface> pc, - scoped_refptr<WebRtcMediaStreamAdapterMap> stream_adapter_map, + scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map, scoped_refptr<WebRtcSetRemoteDescriptionObserver> observer) - : main_thread_(std::move(main_thread)), + : main_task_runner_(std::move(main_task_runner)), + signaling_task_runner_(std::move(signaling_task_runner)), pc_(std::move(pc)), - stream_adapter_map_(std::move(stream_adapter_map)), + track_adapter_map_(std::move(track_adapter_map)), observer_(std::move(observer)) {} WebRtcSetRemoteDescriptionObserverHandler:: @@ -84,7 +59,7 @@ void WebRtcSetRemoteDescriptionObserverHandler::OnSetRemoteDescriptionComplete( webrtc::RTCError error) { - CHECK(!main_thread_->BelongsToCurrentThread()); + CHECK(signaling_task_runner_->BelongsToCurrentThread()); webrtc::RTCErrorOr<WebRtcSetRemoteDescriptionObserver::States> states_or_error; @@ -93,22 +68,20 @@ states.signaling_state = pc_->signaling_state(); for (const auto& webrtc_receiver : pc_->GetReceivers()) { std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref = - track_adapter_map()->GetOrCreateRemoteTrackAdapter( + track_adapter_map_->GetOrCreateRemoteTrackAdapter( webrtc_receiver->track().get()); - std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>> - stream_refs; - for (const auto& stream : webrtc_receiver->streams()) { - stream_refs.push_back( - stream_adapter_map_->GetOrCreateRemoteStreamAdapter(stream.get())); - } - states.receiver_states.push_back(WebRtcReceiverState( - webrtc_receiver.get(), std::move(track_ref), std::move(stream_refs))); + std::vector<std::string> stream_ids; + for (const auto& stream : webrtc_receiver->streams()) + stream_ids.push_back(stream->id()); + states.receiver_states.push_back(RtpReceiverState( + main_task_runner_, signaling_task_runner_, webrtc_receiver.get(), + std::move(track_ref), std::move(stream_ids))); } states_or_error = std::move(states); } else { states_or_error = std::move(error); } - main_thread_->PostTask( + main_task_runner_->PostTask( FROM_HERE, base::BindOnce(&WebRtcSetRemoteDescriptionObserverHandler:: OnSetRemoteDescriptionCompleteOnMainThread, this, std::move(states_or_error))); @@ -118,7 +91,11 @@ OnSetRemoteDescriptionCompleteOnMainThread( webrtc::RTCErrorOr<WebRtcSetRemoteDescriptionObserver::States> states_or_error) { - CHECK(main_thread_->BelongsToCurrentThread()); + CHECK(main_task_runner_->BelongsToCurrentThread()); + if (states_or_error.ok()) { + for (auto& receiver_state : states_or_error.value().receiver_states) + receiver_state.Initialize(); + } observer_->OnSetRemoteDescriptionComplete(std::move(states_or_error)); }
diff --git a/content/renderer/media/webrtc/webrtc_set_remote_description_observer.h b/content/renderer/media/webrtc/webrtc_set_remote_description_observer.h index 999e5c7..3b531c0 100644 --- a/content/renderer/media/webrtc/webrtc_set_remote_description_observer.h +++ b/content/renderer/media/webrtc/webrtc_set_remote_description_observer.h
@@ -14,8 +14,8 @@ #include "base/threading/thread_task_runner_handle.h" #include "content/common/content_export.h" #include "content/renderer/media/webrtc/rtc_peer_connection_handler.h" -#include "content/renderer/media/webrtc/webrtc_media_stream_adapter_map.h" -#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter.h" +#include "content/renderer/media/webrtc/rtc_rtp_receiver.h" +#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h" #include "third_party/webrtc/api/peerconnectioninterface.h" #include "third_party/webrtc/api/rtcerror.h" #include "third_party/webrtc/api/rtpreceiverinterface.h" @@ -26,32 +26,6 @@ namespace content { -// Describes an instance of a receiver at the time the SRD call was completed. -// Because webrtc and content operate on different threads, webrtc objects may -// have been modified by the time we synchronize the receivers on the main -// thread, and members of this class should be inspected rather than members of -// |receiver|. -struct CONTENT_EXPORT WebRtcReceiverState { - WebRtcReceiverState( - scoped_refptr<webrtc::RtpReceiverInterface> receiver, - std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref, - std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>> - stream_refs); - WebRtcReceiverState(WebRtcReceiverState&& other); - ~WebRtcReceiverState(); - - WebRtcReceiverState& operator=(WebRtcReceiverState&& other); - - scoped_refptr<webrtc::RtpReceiverInterface> receiver; - // The receiver's track when the SRD occurred. - std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref; - // The receiver's associated set of streams when the SRD occurred. - std::vector<std::unique_ptr<WebRtcMediaStreamAdapterMap::AdapterRef>> - stream_refs; - - DISALLOW_COPY_AND_ASSIGN(WebRtcReceiverState); -}; - // The content layer correspondent of // webrtc::SetRemoteDescriptionObserverInterface. It's an interface with // callbacks for handling the result of SetRemoteDescription on the main thread. @@ -73,9 +47,7 @@ webrtc::PeerConnectionInterface::SignalingState signaling_state; // The receivers at the time of the event. - std::vector<WebRtcReceiverState> receiver_states; - // Check that the invariants for this structure hold. - void CheckInvariants() const; + std::vector<RtpReceiverState> receiver_states; DISALLOW_COPY_AND_ASSIGN(States); }; @@ -104,9 +76,10 @@ : public webrtc::SetRemoteDescriptionObserverInterface { public: static scoped_refptr<WebRtcSetRemoteDescriptionObserverHandler> Create( - scoped_refptr<base::SingleThreadTaskRunner> main_thread, + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner, scoped_refptr<webrtc::PeerConnectionInterface> pc, - scoped_refptr<WebRtcMediaStreamAdapterMap> stream_adapter_map, + scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map, scoped_refptr<WebRtcSetRemoteDescriptionObserver> observer); // webrtc::SetRemoteDescriptionObserverInterface implementation. @@ -114,9 +87,10 @@ protected: WebRtcSetRemoteDescriptionObserverHandler( - scoped_refptr<base::SingleThreadTaskRunner> main_thread, + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner, scoped_refptr<webrtc::PeerConnectionInterface> pc, - scoped_refptr<WebRtcMediaStreamAdapterMap> stream_adapter_map, + scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map, scoped_refptr<WebRtcSetRemoteDescriptionObserver> observer); ~WebRtcSetRemoteDescriptionObserverHandler() override; @@ -125,13 +99,10 @@ webrtc::RTCErrorOr<WebRtcSetRemoteDescriptionObserver::States> states_or_error); - scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map() const { - return stream_adapter_map_->track_adapter_map(); - } - - scoped_refptr<base::SingleThreadTaskRunner> main_thread_; + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; + scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner_; scoped_refptr<webrtc::PeerConnectionInterface> pc_; - scoped_refptr<WebRtcMediaStreamAdapterMap> stream_adapter_map_; + scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map_; scoped_refptr<WebRtcSetRemoteDescriptionObserver> observer_; DISALLOW_COPY_AND_ASSIGN(WebRtcSetRemoteDescriptionObserverHandler);
diff --git a/content/renderer/media/webrtc/webrtc_set_remote_description_observer_unittest.cc b/content/renderer/media/webrtc/webrtc_set_remote_description_observer_unittest.cc index 5b86145..0814612 100644 --- a/content/renderer/media/webrtc/webrtc_set_remote_description_observer_unittest.cc +++ b/content/renderer/media/webrtc/webrtc_set_remote_description_observer_unittest.cc
@@ -73,7 +73,8 @@ main_thread_)); observer_ = new WebRtcSetRemoteDescriptionObserverForTest(); observer_handler_ = WebRtcSetRemoteDescriptionObserverHandler::Create( - main_thread_, pc_, map, observer_); + main_thread_, dependency_factory_->GetWebRtcSignalingThread(), pc_, + map->track_adapter_map(), observer_); } void TearDown() override { blink::WebHeap::CollectAllGarbageForTesting(); } @@ -131,13 +132,12 @@ EXPECT_TRUE(observer_->result()); EXPECT_EQ(1u, observer_->states().receiver_states.size()); - const WebRtcReceiverState& receiver_state = + const RtpReceiverState& receiver_state = observer_->states().receiver_states[0]; - EXPECT_EQ(added_receiver, receiver_state.receiver); - EXPECT_EQ(added_track, receiver_state.track_ref->webrtc_track()); - EXPECT_EQ(1u, receiver_state.stream_refs.size()); - EXPECT_EQ(added_stream, - receiver_state.stream_refs[0]->adapter().webrtc_stream()); + EXPECT_EQ(added_receiver, receiver_state.webrtc_receiver()); + EXPECT_EQ(added_track, receiver_state.track_ref()->webrtc_track()); + EXPECT_EQ(1u, receiver_state.stream_ids().size()); + EXPECT_EQ(added_stream->id(), receiver_state.stream_ids()[0]); } TEST_F(WebRtcSetRemoteDescriptionObserverHandlerTest, OnFailure) {
diff --git a/content/renderer/media/webrtc/webrtc_util.h b/content/renderer/media/webrtc/webrtc_util.h new file mode 100644 index 0000000..e88a3d1f --- /dev/null +++ b/content/renderer/media/webrtc/webrtc_util.h
@@ -0,0 +1,36 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_UTIL_H_ +#define CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_UTIL_H_ + +#include "base/optional.h" +#include "third_party/webrtc/api/optional.h" + +namespace content { + +template <typename T> +base::Optional<T> ToBaseOptional(const absl::optional<T>& optional) { + return optional ? base::Optional<T>(*optional) : base::nullopt; +} + +template <typename T> +bool operator==(const base::Optional<T>& base_optional, + const absl::optional<T>& absl_optional) { + if (!base_optional) + return !absl_optional; + if (!absl_optional) + return false; + return *base_optional == *absl_optional; +} + +template <typename T> +bool operator==(const absl::optional<T>& absl_optional, + const base::Optional<T>& base_optional) { + return base_optional == absl_optional; +} + +} // namespace content + +#endif // CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_UTIL_H_
diff --git a/content/renderer/mus/BUILD.gn b/content/renderer/mus/BUILD.gn index 3fbd631..297195a 100644 --- a/content/renderer/mus/BUILD.gn +++ b/content/renderer/mus/BUILD.gn
@@ -18,10 +18,6 @@ configs += [ "//content:content_implementation" ] - public_deps = [ - "//content/public/common:common_sources", - ] - deps = [ "//base", "//cc", @@ -29,6 +25,7 @@ "//components/viz/client", "//content/common", "//content/public/child:child_sources", + "//content/public/common:common_sources", "//media/mojo/interfaces:remoting", "//services/service_manager/public/cpp", "//services/ui/public/cpp",
diff --git a/content/renderer/navigation_state_impl.h b/content/renderer/navigation_state_impl.h index 8ea0ec0..9b3628b9 100644 --- a/content/renderer/navigation_state_impl.h +++ b/content/renderer/navigation_state_impl.h
@@ -57,6 +57,10 @@ navigation_client_ = std::move(navigation_client_impl); } + void set_navigation_start(const base::TimeTicks& navigation_start) { + common_params_.navigation_start = navigation_start; + } + void RunCommitNavigationCallback(blink::mojom::CommitResult result); private:
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 101c5ff..2deec13 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -909,6 +909,18 @@ request->SetURL(blink::WebURL(GURL(path))); } +// Sets the |navigation_start| time into the |document_state|'s NavigationState. +void SetNavigationStartTimeInPendingParams( + const base::TimeTicks& navigation_start, + PendingNavigationParams* pending_navigation_params) { + // Lower bound for browser initiated navigation start time. + base::TimeTicks renderer_navigation_start = base::TimeTicks::Now(); + + // Sanitize navigation start and store it in |document_state|. + pending_navigation_params->common_params.navigation_start = + SanitizeNavigationTiming(navigation_start, renderer_navigation_start); +} + } // namespace class RenderFrameImpl::FrameURLLoaderFactory @@ -3076,7 +3088,9 @@ pending_navigation_params_.reset( new PendingNavigationParams(common_params, request_params, base::TimeTicks::Now(), std::move(callback))); - PrepareFrameForCommit(); + PrepareFrameForCommit(common_params.url, request_params); + SetNavigationStartTimeInPendingParams(common_params.navigation_start, + pending_navigation_params_.get()); std::unique_ptr<DocumentState> document_state( BuildDocumentStateFromPending(pending_navigation_params_.get())); @@ -3309,16 +3323,14 @@ common_params.has_user_gesture ? new blink::WebScopedUserGesture(frame_) : nullptr); - // Note: The CommitNavigationCallback below is not used: the commit of - // same-document navigation is synchronous so there is enough information at - // the end of this function to run |callback| directly. - // TODO(clamy): See if PendingNavigationParams should not be set at all for - // same-document navigations. + // TODO(ahemery): |pending_navigation_params_| below is solely used by + // IsBrowserInitiated() in DecidePolicyForNavigation. Try and find a a way to + // avoid having to create the entire structure just for this. pending_navigation_params_.reset(new PendingNavigationParams( common_params, request_params, base::TimeTicks(), // Not used for same-document navigation. CommitNavigationCallback())); - PrepareFrameForCommit(); + PrepareFrameForCommit(common_params.url, request_params); blink::WebFrameLoadType load_type = NavigationTypeToLoadType( common_params.navigation_type, common_params.should_replace_current_entry, @@ -5728,27 +5740,16 @@ } } -void RenderFrameImpl::PrepareFrameForCommit() { +void RenderFrameImpl::PrepareFrameForCommit( + const GURL& url, + const RequestNavigationParams& request_params) { browser_side_navigation_pending_ = false; browser_side_navigation_pending_url_ = GURL(); GetContentClient()->SetActiveURL( - pending_navigation_params_->common_params.url, - frame_->Top()->GetSecurityOrigin().ToString().Utf8()); + url, frame_->Top()->GetSecurityOrigin().ToString().Utf8()); - RenderFrameImpl::PrepareRenderViewForNavigation( - pending_navigation_params_->common_params.url, - pending_navigation_params_->request_params); - - // Lower bound for browser initiated navigation start time. - base::TimeTicks renderer_navigation_start = base::TimeTicks::Now(); - - // Sanitize navigation start and store in |pending_navigation_params_|. - // It will be picked up in UpdateNavigationState. - pending_navigation_params_->common_params.navigation_start = - SanitizeNavigationTiming( - pending_navigation_params_->common_params.navigation_start, - renderer_navigation_start); + RenderFrameImpl::PrepareRenderViewForNavigation(url, request_params); } blink::mojom::CommitResult RenderFrameImpl::PrepareForHistoryNavigationCommit(
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index 77e9f54..586376a 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -1288,7 +1288,8 @@ CreateWebSocketHandshakeThrottle() override; // Updates the state of this frame when asked to commit a navigation. - void PrepareFrameForCommit(); + void PrepareFrameForCommit(const GURL& url, + const RequestNavigationParams& request_params); // Updates the state when asked to commit a history navigation. Sets // |item_for_history_navigation| and |load_type| to the appropriate values for
diff --git a/content/renderer/render_thread_impl.h b/content/renderer/render_thread_impl.h index 958b8f6..8cfd19d9 100644 --- a/content/renderer/render_thread_impl.h +++ b/content/renderer/render_thread_impl.h
@@ -307,6 +307,14 @@ std::unique_ptr<LayoutTestDependencies> deps) { layout_test_deps_ = std::move(deps); } + // Returns whether we are running layout tests with display compositor for + // pixel dump enabled. It is meant to disable feature that require display + // compositor while it is not enabled by default. + // This should only be called if currently running in layout tests. + bool LayoutTestModeUsesDisplayCompositorPixelDump() const { + DCHECK(layout_test_deps_); + return layout_test_deps_->UseDisplayCompositorPixelDump(); + } discardable_memory::ClientDiscardableSharedMemoryManager* GetDiscardableSharedMemoryManagerForTest() {
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index 950a68c8..18b91502 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc
@@ -39,6 +39,7 @@ #include "build/build_config.h" #include "cc/base/switches.h" #include "cc/paint/skia_paint_canvas.h" +#include "cc/trees/layer_tree_host.h" #include "content/common/content_constants_internal.h" #include "content/common/dom_storage/dom_storage_namespace_ids.h" #include "content/common/dom_storage/dom_storage_types.h" @@ -937,7 +938,9 @@ static_cast<blink::WebEffectiveConnectionType>( prefs.low_priority_iframes_threshold)); - settings->SetPictureInPictureEnabled(prefs.picture_in_picture_enabled); + settings->SetPictureInPictureEnabled( + prefs.picture_in_picture_enabled && + MediaFactory::VideoSurfaceLayerEnabled()); settings->SetDataSaverHoldbackWebApi( prefs.data_saver_holdback_web_api_enabled);
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index 0a9c02c..152dccd 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc
@@ -31,6 +31,7 @@ #include "cc/input/touch_action.h" #include "cc/trees/layer_tree_frame_sink.h" #include "cc/trees/layer_tree_host.h" +#include "cc/trees/ukm_manager.h" #include "components/viz/common/features.h" #include "components/viz/common/frame_sinks/begin_frame_source.h" #include "components/viz/common/frame_sinks/copy_output_request.h" @@ -1370,11 +1371,16 @@ blink::WebLayerTreeView* RenderWidget::InitializeLayerTreeView() { DCHECK(!host_closing_); - compositor_ = - std::make_unique<RenderWidgetCompositor>(this, compositor_deps_); - compositor_->Initialize(GenerateLayerTreeSettings( - compositor_deps_, for_oopif_, screen_info_.rect.size(), - screen_info_.device_scale_factor)); + compositor_ = std::make_unique<RenderWidgetCompositor>( + this, compositor_deps_->GetCompositorMainThreadTaskRunner(), + compositor_deps_->GetCompositorImplThreadTaskRunner(), + compositor_deps_->GetTaskGraphRunner(), + compositor_deps_->GetWebMainThreadScheduler()); + compositor_->Initialize( + GenerateLayerTreeSettings(compositor_deps_, for_oopif_, + screen_info_.rect.size(), + screen_info_.device_scale_factor), + compositor_deps_->CreateUkmRecorderFactory()); UpdateSurfaceAndScreenInfo(local_surface_id_from_parent_, compositor_viewport_pixel_size_, screen_info_);
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc index 64a2754f..f06027e 100644 --- a/content/renderer/renderer_blink_platform_impl.cc +++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -205,17 +205,13 @@ class RendererBlinkPlatformImpl::SandboxSupport : public blink::WebSandboxSupport { public: -#if defined(OS_LINUX) - explicit SandboxSupport(sk_sp<font_service::FontLoader> font_loader) - : font_loader_(std::move(font_loader)) {} -#endif ~SandboxSupport() override {} #if defined(OS_MACOSX) bool LoadFont(CTFontRef src_font, CGFontRef* container, uint32_t* font_id) override; -#elif defined(OS_LINUX) +#elif defined(OS_POSIX) void GetFallbackFontForCharacter( blink::WebUChar32 character, const char* preferred_locale, @@ -233,7 +229,6 @@ // here. base::Lock unicode_font_families_mutex_; std::map<int32_t, blink::WebFallbackFont> unicode_font_families_; - sk_sp<font_service::FontLoader> font_loader_; #endif }; #endif // !defined(OS_ANDROID) && !defined(OS_WIN) @@ -252,6 +247,13 @@ is_locked_to_site_(false), default_task_runner_(main_thread_scheduler->DefaultTaskRunner()), main_thread_scheduler_(main_thread_scheduler) { +#if !defined(OS_ANDROID) && !defined(OS_WIN) && !defined(OS_FUCHSIA) + if (g_sandbox_enabled && sandboxEnabled()) { + sandbox_support_.reset(new RendererBlinkPlatformImpl::SandboxSupport); + } else { + DVLOG(1) << "Disabling sandbox support for testing."; + } +#endif // RenderThread may not exist in some tests. if (RenderThreadImpl::current()) { @@ -265,28 +267,11 @@ web_idb_factory_.reset(new WebIDBFactoryImpl( sync_message_filter_, RenderThreadImpl::current()->GetIOTaskRunner().get())); -#if defined(OS_LINUX) - font_loader_ = sk_make_sp<font_service::FontLoader>(connector_.get()); - SkFontConfigInterface::SetGlobal(font_loader_); -#endif } else { service_manager::mojom::ConnectorRequest request; connector_ = service_manager::Connector::Create(&request); } -#if !defined(OS_ANDROID) && !defined(OS_WIN) && !defined(OS_FUCHSIA) - if (g_sandbox_enabled && sandboxEnabled()) { -#if defined(OS_MACOSX) - sandbox_support_.reset(new RendererBlinkPlatformImpl::SandboxSupport()); -#else - sandbox_support_.reset( - new RendererBlinkPlatformImpl::SandboxSupport(font_loader_)); -#endif - } else { - DVLOG(1) << "Disabling sandbox support for testing."; - } -#endif - blink_interface_provider_.reset( new BlinkInterfaceProviderImpl(connector_.get())); top_level_blame_context_.Initialize(); @@ -607,8 +592,8 @@ return; } - content::GetFallbackFontForCharacter(font_loader_, character, - preferred_locale, fallbackFont); + content::GetFallbackFontForCharacter(character, preferred_locale, + fallbackFont); unicode_font_families_.insert(std::make_pair(character, *fallbackFont)); } @@ -619,8 +604,8 @@ bool is_italic, float device_scale_factor, blink::WebFontRenderStyle* out) { - GetRenderStyleForStrike(font_loader_, family, size, is_bold, is_italic, - device_scale_factor, out); + GetRenderStyleForStrike(family, size, is_bold, is_italic, device_scale_factor, + out); } #endif
diff --git a/content/renderer/renderer_blink_platform_impl.h b/content/renderer/renderer_blink_platform_impl.h index 11a3acd6..464f3bb 100644 --- a/content/renderer/renderer_blink_platform_impl.h +++ b/content/renderer/renderer_blink_platform_impl.h
@@ -29,11 +29,6 @@ #include "third_party/blink/public/platform/modules/indexeddb/web_idb_factory.h" #include "third_party/blink/public/platform/modules/webdatabase/web_database.mojom.h" -#if defined(OS_LINUX) -#include "components/services/font/public/cpp/font_loader.h" // nogncheck -#include "third_party/skia/include/core/SkRefCnt.h" // nogncheck -#endif - namespace IPC { class SyncMessageFilter; } @@ -323,10 +318,6 @@ blink::mojom::WebDatabaseHostPtrInfo web_database_host_info_; scoped_refptr<blink::mojom::ThreadSafeWebDatabaseHostPtr> web_database_host_; -#if defined(OS_LINUX) - sk_sp<font_service::FontLoader> font_loader_; -#endif - THREAD_CHECKER(main_thread_checker_); DISALLOW_COPY_AND_ASSIGN(RendererBlinkPlatformImpl);
diff --git a/content/renderer/renderer_main.cc b/content/renderer/renderer_main.cc index 0b722923..30e9f57 100644 --- a/content/renderer/renderer_main.cc +++ b/content/renderer/renderer_main.cc
@@ -43,6 +43,14 @@ #include "base/android/library_loader/library_loader_hooks.h" #endif // OS_ANDROID +#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) && \ + !defined(OS_FUCHSIA) +#include "content/common/font_config_ipc_linux.h" +#include "services/service_manager/sandbox/linux/sandbox_linux.h" +#include "services/service_manager/zygote/common/common_sandbox_support_linux.h" +#include "third_party/skia/include/ports/SkFontConfigInterface.h" +#endif + #if defined(OS_MACOSX) #include <Carbon/Carbon.h> #include <signal.h> @@ -113,6 +121,16 @@ } #endif +#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) && \ + !defined(OS_FUCHSIA) + // This call could already have been made from zygote_main_linux.cc. However + // we need to do it here if Zygote is disabled. + if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kNoZygote)) { + SkFontConfigInterface::SetGlobal( + sk_make_sp<FontConfigIPC>(service_manager::GetSandboxFD())); + } +#endif + InitializeSkia(); // This function allows pausing execution using the --renderer-startup-dialog
diff --git a/content/renderer/service_worker/controller_service_worker_connector.cc b/content/renderer/service_worker/controller_service_worker_connector.cc index b9900a2e..9bfb0ad 100644 --- a/content/renderer/service_worker/controller_service_worker_connector.cc +++ b/content/renderer/service_worker/controller_service_worker_connector.cc
@@ -6,22 +6,25 @@ #include "base/bind.h" #include "base/bind_helpers.h" -#include "mojo/public/cpp/bindings/interface_request.h" namespace content { ControllerServiceWorkerConnector::ControllerServiceWorkerConnector( mojom::ServiceWorkerContainerHostPtrInfo container_host_info, - mojom::ControllerServiceWorkerPtr controller_ptr, - const std::string& client_id) - : client_id_(client_id) { - container_host_ptr_.Bind(std::move(container_host_info)); - container_host_ptr_.set_connection_error_handler(base::BindOnce( - &ControllerServiceWorkerConnector::OnContainerHostConnectionClosed, - base::Unretained(this))); - SetControllerServiceWorkerPtr(std::move(controller_ptr)); + mojom::ControllerServiceWorkerPtrInfo controller_info, + const std::string& client_id, + scoped_refptr<base::SequencedTaskRunner> task_runner) + : client_id_(client_id), weak_factory_(this) { + DCHECK(task_runner); + task_runner->PostTask( + FROM_HERE, + base::BindOnce(&ControllerServiceWorkerConnector::InitializeOnTaskRunner, + base::Unretained(this), std::move(container_host_info), + std::move(controller_info))); } +ControllerServiceWorkerConnector::~ControllerServiceWorkerConnector() = default; + mojom::ControllerServiceWorker* ControllerServiceWorkerConnector::GetControllerServiceWorker( mojom::ControllerServiceWorkerPurpose purpose) { @@ -72,20 +75,28 @@ observer.OnConnectionClosed(); } -void ControllerServiceWorkerConnector::AddBinding( - mojom::ControllerServiceWorkerConnectorRequest request) { - bindings_.AddBinding(this, std::move(request)); -} - void ControllerServiceWorkerConnector::UpdateController( - mojom::ControllerServiceWorkerPtr controller_ptr) { + mojom::ControllerServiceWorkerPtrInfo controller_info) { if (state_ == State::kNoContainerHost) return; - SetControllerServiceWorkerPtr(std::move(controller_ptr)); + SetControllerServiceWorkerPtr( + mojom::ControllerServiceWorkerPtr(std::move(controller_info))); if (!controller_service_worker_) state_ = State::kNoController; } +void ControllerServiceWorkerConnector::InitializeOnTaskRunner( + mojom::ServiceWorkerContainerHostPtrInfo container_host_info, + mojom::ControllerServiceWorkerPtrInfo controller_info) { + DCHECK(!container_host_ptr_); + container_host_ptr_.Bind(std::move(container_host_info)); + container_host_ptr_.set_connection_error_handler(base::BindOnce( + &ControllerServiceWorkerConnector::OnContainerHostConnectionClosed, + base::Unretained(this))); + SetControllerServiceWorkerPtr( + mojom::ControllerServiceWorkerPtr(std::move(controller_info))); +} + void ControllerServiceWorkerConnector::SetControllerServiceWorkerPtr( mojom::ControllerServiceWorkerPtr controller_ptr) { controller_service_worker_ = std::move(controller_ptr); @@ -97,6 +108,4 @@ } } -ControllerServiceWorkerConnector::~ControllerServiceWorkerConnector() = default; - } // namespace content
diff --git a/content/renderer/service_worker/controller_service_worker_connector.h b/content/renderer/service_worker/controller_service_worker_connector.h index e24bbda..5d861a2 100644 --- a/content/renderer/service_worker/controller_service_worker_connector.h +++ b/content/renderer/service_worker/controller_service_worker_connector.h
@@ -6,12 +6,11 @@ #define CONTENT_RENDERER_SERVICE_WORKER_CONTROLLER_SERVICE_WORKER_CONNECTOR_H_ #include "base/macros.h" -#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "content/common/content_export.h" #include "content/common/service_worker/controller_service_worker.mojom.h" #include "content/common/service_worker/service_worker_container.mojom.h" -#include "mojo/public/cpp/bindings/binding_set.h" namespace content { @@ -20,12 +19,9 @@ } // namespace mojom // Vends a connection to the controller service worker for a given -// ServiceWorkerContainerHost. This is co-owned by -// ServiceWorkerProviderContext::ControlleeState and -// ServiceWorkerSubresourceLoader{,Factory}. -class CONTENT_EXPORT ControllerServiceWorkerConnector - : public mojom::ControllerServiceWorkerConnector, - public base::RefCounted<ControllerServiceWorkerConnector> { +// ServiceWorkerContainerHost. This is owned by +// ServiceWorkerSubresourceLoaderFactory. +class CONTENT_EXPORT ControllerServiceWorkerConnector { public: // Observes the connection to the controller. class Observer { @@ -53,17 +49,18 @@ kNoContainerHost, }; - // This class should only be created if a controller exists for the client. - // |controller_ptr| may be nullptr if the caller does not yet have a Mojo - // connection to the controller. |state_| is set to kDisconnected in that - // case. - // Creates and holds the ownership of |container_host_ptr_| (as |this| - // will be created on a different thread from the thread that has the - // original |container_host|). + // This should only be called if a controller exists for the client. + // |this| is initialized on |task_runner|, and therefore must be + // used only on |task_runner|. + // |controller_info| can be null if the caller does not have the Mojo ptr + // to the controller. In that case |controller_service_worker_| is populated + // by talking to |controller_host_ptr_|. ControllerServiceWorkerConnector( mojom::ServiceWorkerContainerHostPtrInfo container_host_info, - mojom::ControllerServiceWorkerPtr controller_ptr, - const std::string& client_id); + mojom::ControllerServiceWorkerPtrInfo controller_info, + const std::string& client_id, + scoped_refptr<base::SequencedTaskRunner> task_runner); + ~ControllerServiceWorkerConnector(); // This may return nullptr if the connection to the ContainerHost (in the // browser process) is already terminated. @@ -76,27 +73,25 @@ void OnContainerHostConnectionClosed(); void OnControllerConnectionClosed(); - void AddBinding(mojom::ControllerServiceWorkerConnectorRequest request); - - // mojom::ControllerServiceWorkerConnector: - void UpdateController( - mojom::ControllerServiceWorkerPtr controller_ptr) override; + void UpdateController(mojom::ControllerServiceWorkerPtrInfo controller_info); State state() const { return state_; } const std::string& client_id() const { return client_id_; } + base::WeakPtr<ControllerServiceWorkerConnector> GetWeakPtr() { + return weak_factory_.GetWeakPtr(); + } + private: + void InitializeOnTaskRunner( + mojom::ServiceWorkerContainerHostPtrInfo container_host_info, + mojom::ControllerServiceWorkerPtrInfo controller_info); void SetControllerServiceWorkerPtr( mojom::ControllerServiceWorkerPtr controller_ptr); State state_ = State::kDisconnected; - friend class base::RefCounted<ControllerServiceWorkerConnector>; - ~ControllerServiceWorkerConnector() override; - - mojo::BindingSet<mojom::ControllerServiceWorkerConnector> bindings_; - // Keeps the mojo end to the browser process on its own. // Non-null only for the service worker clients that are workers (i.e., only // when created for dedicated workers or shared workers). @@ -116,6 +111,8 @@ // ServiceWorkerProviderHost::provider_id). std::string client_id_; + base::WeakPtrFactory<ControllerServiceWorkerConnector> weak_factory_; + DISALLOW_COPY_AND_ASSIGN(ControllerServiceWorkerConnector); };
diff --git a/content/renderer/service_worker/service_worker_provider_context.cc b/content/renderer/service_worker/service_worker_provider_context.cc index 07dcd1a..e69a936 100644 --- a/content/renderer/service_worker/service_worker_provider_context.cc +++ b/content/renderer/service_worker/service_worker_provider_context.cc
@@ -36,20 +36,12 @@ namespace { void CreateSubresourceLoaderFactoryForProviderContext( - mojom::ServiceWorkerContainerHostPtrInfo container_host_info, - mojom::ControllerServiceWorkerPtrInfo controller_ptr_info, - const std::string& client_id, + std::unique_ptr<ControllerServiceWorkerConnector> controller_connector, std::unique_ptr<network::SharedURLLoaderFactoryInfo> fallback_factory_info, - mojom::ControllerServiceWorkerConnectorRequest connector_request, network::mojom::URLLoaderFactoryRequest request, scoped_refptr<base::SequencedTaskRunner> task_runner) { - mojom::ControllerServiceWorkerPtr controller_ptr; - controller_ptr.Bind(std::move(controller_ptr_info)); - auto connector = base::MakeRefCounted<ControllerServiceWorkerConnector>( - std::move(container_host_info), std::move(controller_ptr), client_id); - connector->AddBinding(std::move(connector_request)); ServiceWorkerSubresourceLoaderFactory::Create( - std::move(connector), + std::move(controller_connector), network::SharedURLLoaderFactory::Create(std::move(fallback_factory_info)), std::move(request), std::move(task_runner)); } @@ -112,14 +104,18 @@ // and is to be passed to (i.e. taken by) a subresource loader factory when // GetSubresourceLoaderFactory() is called for the first time when a valid // controller exists. - // - // |controller_connector| is a Mojo pipe to the - // ControllerServiceWorkerConnector that is attached to the newly created - // subresource loader factory and lives on a background thread. This is - // populated when GetSubresourceLoader() creates the subresource loader - // factory and takes |controller_endpoint|. mojom::ControllerServiceWorkerPtrInfo controller_endpoint; - mojom::ControllerServiceWorkerConnectorPtr controller_connector; + + // S13nServiceWorker + // |controller_connector| is a weak pointer to + // ControllerServiceWorkerConnector that is attached to the newly created + // |subresource_loader_factory| and lives on a background + // |subresource_loader_task_runner|. They are populated when + // GetSubresourceLoader() creates the subresource loader factory and takes + // |controller_endpoint|. Note that |controller_connector| must be accessed + // only on |subresource_loader_task_runner|. + base::WeakPtr<ControllerServiceWorkerConnector> controller_connector; + scoped_refptr<base::SequencedTaskRunner> subresource_loader_task_runner; // For service worker clients. Map from registration id to JavaScript // ServiceWorkerRegistration object. @@ -199,7 +195,7 @@ DCHECK(state_for_client_); auto* state = state_for_client_.get(); - if (!state->controller_endpoint && !state->controller_connector) { + if (!state->controller_endpoint && !state->subresource_loader_task_runner) { // No controller is attached. return nullptr; } @@ -211,21 +207,23 @@ } if (!state->subresource_loader_factory) { - DCHECK(!state->controller_connector); DCHECK(state->controller_endpoint); // Create a SubresourceLoaderFactory on a background thread to avoid // extra contention on the main thread. auto task_runner = base::CreateSequencedTaskRunnerWithTraits( {base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}); - task_runner->PostTask( + auto connector = std::make_unique<ControllerServiceWorkerConnector>( + CloneContainerHostPtrInfo(), std::move(state->controller_endpoint), + state->client_id, task_runner); + state->controller_connector = connector->GetWeakPtr(); + state->subresource_loader_task_runner = task_runner; + state->subresource_loader_task_runner->PostTask( FROM_HERE, base::BindOnce(&CreateSubresourceLoaderFactoryForProviderContext, - CloneContainerHostPtrInfo(), - std::move(state->controller_endpoint), state->client_id, + std::move(connector), state->fallback_loader_factory->Clone(), - mojo::MakeRequest(&state->controller_connector), mojo::MakeRequest(&state->subresource_loader_factory), - task_runner)); + std::move(task_runner))); } return state->subresource_loader_factory.get(); } @@ -388,7 +386,7 @@ // (B) Had a controller, and lost the controller. // (C) Didn't have a controller, and got a new controller. // (D) Didn't have a controller, and lost the controller (nothing to do). - if (state->controller_connector) { + if (state->subresource_loader_task_runner) { // Used to have a controller at least once and have created a // subresource loader factory before (if no subresource factory was // created before, then the right controller, if any, will be used when @@ -400,9 +398,11 @@ // the existing controller or may use the new controller settings // depending on when the request is actually passed to the factory (this // part is inherently racy). - state->controller_connector->UpdateController( - mojom::ControllerServiceWorkerPtr( - std::move(state->controller_endpoint))); + state->subresource_loader_task_runner->PostTask( + FROM_HERE, + base::BindOnce(&ControllerServiceWorkerConnector::UpdateController, + state->controller_connector, + std::move(state->controller_endpoint))); } }
diff --git a/content/renderer/service_worker/service_worker_subresource_loader.cc b/content/renderer/service_worker/service_worker_subresource_loader.cc index 547e62a..1a0e3fe 100644 --- a/content/renderer/service_worker/service_worker_subresource_loader.cc +++ b/content/renderer/service_worker/service_worker_subresource_loader.cc
@@ -149,7 +149,7 @@ const network::ResourceRequest& resource_request, network::mojom::URLLoaderClientPtr client, const net::MutableNetworkTrafficAnnotationTag& traffic_annotation, - scoped_refptr<ControllerServiceWorkerConnector> controller_connector, + base::WeakPtr<ControllerServiceWorkerConnector> controller_connector, scoped_refptr<network::SharedURLLoaderFactory> fallback_factory, scoped_refptr<base::SequencedTaskRunner> task_runner) : redirect_limit_(net::URLRequest::kMaxRedirects), @@ -195,6 +195,13 @@ DCHECK(!ServiceWorkerUtils::IsMainResourceType( static_cast<ResourceType>(resource_request.resource_type))); + if (!controller_connector_) { + // The factory (that owns the connector) is dead; which means the frame + // must be getting dropped now. + SettleFetchEventDispatch(base::nullopt); + return; + } + DCHECK(!controller_connector_observer_.IsObservingSources()); controller_connector_observer_.Add(controller_connector_.get()); fetch_request_restarted_ = false; @@ -209,6 +216,13 @@ } void ServiceWorkerSubresourceLoader::DispatchFetchEvent() { + if (!controller_connector_) { + // The factory (that owns the connector) is dead; which means the frame + // must be getting dropped now. + SettleFetchEventDispatch(base::nullopt); + return; + } + mojom::ServiceWorkerFetchResponseCallbackPtr response_callback_ptr; response_callback_binding_.Bind(mojo::MakeRequest(&response_callback_ptr)); mojom::ControllerServiceWorker* controller = @@ -594,7 +608,7 @@ // static void ServiceWorkerSubresourceLoaderFactory::Create( - scoped_refptr<ControllerServiceWorkerConnector> controller_connector, + std::unique_ptr<ControllerServiceWorkerConnector> controller_connector, scoped_refptr<network::SharedURLLoaderFactory> fallback_factory, network::mojom::URLLoaderFactoryRequest request, scoped_refptr<base::SequencedTaskRunner> task_runner) { @@ -604,7 +618,7 @@ } ServiceWorkerSubresourceLoaderFactory::ServiceWorkerSubresourceLoaderFactory( - scoped_refptr<ControllerServiceWorkerConnector> controller_connector, + std::unique_ptr<ControllerServiceWorkerConnector> controller_connector, scoped_refptr<network::SharedURLLoaderFactory> fallback_factory, network::mojom::URLLoaderFactoryRequest request, scoped_refptr<base::SequencedTaskRunner> task_runner) @@ -635,8 +649,8 @@ // destructs itself (while the loader client continues to work). new ServiceWorkerSubresourceLoader( std::move(request), routing_id, request_id, options, resource_request, - std::move(client), traffic_annotation, controller_connector_, - fallback_factory_, task_runner_); + std::move(client), traffic_annotation, + controller_connector_->GetWeakPtr(), fallback_factory_, task_runner_); } void ServiceWorkerSubresourceLoaderFactory::Clone(
diff --git a/content/renderer/service_worker/service_worker_subresource_loader.h b/content/renderer/service_worker/service_worker_subresource_loader.h index 91b180b2..6bd4b3bc 100644 --- a/content/renderer/service_worker/service_worker_subresource_loader.h +++ b/content/renderer/service_worker/service_worker_subresource_loader.h
@@ -14,6 +14,7 @@ #include "content/renderer/service_worker/controller_service_worker_connector.h" #include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/binding_set.h" +#include "mojo/public/cpp/bindings/strong_binding_set.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "net/url_request/redirect_info.h" #include "services/network/public/mojom/url_loader_factory.mojom.h" @@ -33,8 +34,7 @@ // S13nServiceWorker: // A custom URLLoader implementation used by Service Worker controllees // for loading subresources via the controller Service Worker. -// Currently an instance of this class is created and used only on -// the main thread (while the implementation itself is thread agnostic). +// An instance of this class is created and run on a background thread. class CONTENT_EXPORT ServiceWorkerSubresourceLoader : public network::mojom::URLLoader, public mojom::ServiceWorkerFetchResponseCallback, @@ -50,7 +50,7 @@ const network::ResourceRequest& resource_request, network::mojom::URLLoaderClientPtr client, const net::MutableNetworkTrafficAnnotationTag& traffic_annotation, - scoped_refptr<ControllerServiceWorkerConnector> controller_connector, + base::WeakPtr<ControllerServiceWorkerConnector> controller_connector, scoped_refptr<network::SharedURLLoaderFactory> fallback_factory, scoped_refptr<base::SequencedTaskRunner> task_runner); @@ -123,7 +123,7 @@ // The blob needs to be held while it's read to keep it alive. blink::mojom::BlobPtr body_as_blob_; - scoped_refptr<ControllerServiceWorkerConnector> controller_connector_; + base::WeakPtr<ControllerServiceWorkerConnector> controller_connector_; // Observes |controller_connector_| while this loader dispatches a fetch event // to the controller. If a broken connection is observed, this loader attempts @@ -169,6 +169,7 @@ // A custom URLLoaderFactory implementation used by Service Worker controllees // for loading subresources via the controller Service Worker. // Self destroys when no more bindings exist. +// An instance of this class is created and run on a background thread. class CONTENT_EXPORT ServiceWorkerSubresourceLoaderFactory : public network::mojom::URLLoaderFactory { public: @@ -182,7 +183,7 @@ // this around because calling base::SequencedTaskRunnerHandle is // prohibited in the renderer :() static void Create( - scoped_refptr<ControllerServiceWorkerConnector> controller_connector, + std::unique_ptr<ControllerServiceWorkerConnector> controller_connector, scoped_refptr<network::SharedURLLoaderFactory> fallback_factory, network::mojom::URLLoaderFactoryRequest request, scoped_refptr<base::SequencedTaskRunner> task_runner); @@ -202,14 +203,14 @@ private: ServiceWorkerSubresourceLoaderFactory( - scoped_refptr<ControllerServiceWorkerConnector> controller_connector, + std::unique_ptr<ControllerServiceWorkerConnector> controller_connector, scoped_refptr<network::SharedURLLoaderFactory> fallback_factory, network::mojom::URLLoaderFactoryRequest request, scoped_refptr<base::SequencedTaskRunner> task_runner); void OnConnectionError(); - scoped_refptr<ControllerServiceWorkerConnector> controller_connector_; + std::unique_ptr<ControllerServiceWorkerConnector> controller_connector_; // Used when a request falls back to network. scoped_refptr<network::SharedURLLoaderFactory> fallback_factory_;
diff --git a/content/renderer/service_worker/service_worker_subresource_loader_unittest.cc b/content/renderer/service_worker/service_worker_subresource_loader_unittest.cc index addc8d9..ed76026c 100644 --- a/content/renderer/service_worker/service_worker_subresource_loader_unittest.cc +++ b/content/renderer/service_worker/service_worker_subresource_loader_unittest.cc
@@ -429,21 +429,34 @@ } network::mojom::URLLoaderFactoryPtr CreateSubresourceLoaderFactory() { - if (!connector_) { - mojom::ServiceWorkerContainerHostPtrInfo host_ptr_info; - fake_container_host_.CloneForWorker(mojo::MakeRequest(&host_ptr_info)); - connector_ = base::MakeRefCounted<ControllerServiceWorkerConnector>( - std::move(host_ptr_info), nullptr /*controller_ptr*/, - "" /*client_id*/); - } + DCHECK(!connector_); + mojom::ServiceWorkerContainerHostPtrInfo host_ptr_info; + fake_container_host_.CloneForWorker(mojo::MakeRequest(&host_ptr_info)); + task_runner_ = blink::scheduler::GetSequencedTaskRunnerForTesting(); + + auto connector = std::make_unique<ControllerServiceWorkerConnector>( + std::move(host_ptr_info), nullptr /*controller_ptr*/, "" /*client_id*/, + task_runner_); + connector_ = connector->GetWeakPtr(); + network::mojom::URLLoaderFactoryPtr service_worker_url_loader_factory; ServiceWorkerSubresourceLoaderFactory::Create( - connector_, loader_factory_, - mojo::MakeRequest(&service_worker_url_loader_factory), - blink::scheduler::GetSequencedTaskRunnerForTesting()); + std::move(connector), loader_factory_, + mojo::MakeRequest(&service_worker_url_loader_factory), task_runner_); + return service_worker_url_loader_factory; } + void UpdateController(mojom::ControllerServiceWorkerPtrInfo controller) { + base::RunLoop run_loop; + task_runner_->PostTaskAndReply( + FROM_HERE, + base::BindOnce(&ControllerServiceWorkerConnector::UpdateController, + connector_, std::move(controller)), + run_loop.QuitClosure()); + run_loop.Run(); + } + // Starts |request| using |loader_factory| and sets |out_loader| and // |out_loader_client| to the resulting URLLoader and its URLLoaderClient. The // caller can then use functions like client.RunUntilComplete() to wait for @@ -530,7 +543,8 @@ TestBrowserThreadBundle thread_bundle_; scoped_refptr<network::SharedURLLoaderFactory> loader_factory_; - scoped_refptr<ControllerServiceWorkerConnector> connector_; + base::WeakPtr<ControllerServiceWorkerConnector> connector_; + scoped_refptr<base::SequencedTaskRunner> task_runner_; FakeServiceWorkerContainerHost fake_container_host_; FakeControllerServiceWorker fake_controller_; base::test::ScopedFeatureList feature_list_; @@ -653,8 +667,7 @@ } // Make the connector have no controller. - connector_->UpdateController(nullptr); - base::RunLoop().RunUntilIdle(); + UpdateController({}); base::HistogramTester histogram_tester; {
diff --git a/content/renderer/service_worker/worker_fetch_context_impl.cc b/content/renderer/service_worker/worker_fetch_context_impl.cc index 2e3524a..c6f4f1b 100644 --- a/content/renderer/service_worker/worker_fetch_context_impl.cc +++ b/content/renderer/service_worker/worker_fetch_context_impl.cc
@@ -38,15 +38,12 @@ // Runs on IO thread. void CreateSubresourceLoaderFactoryForWorker( - mojom::ServiceWorkerContainerHostPtrInfo container_host_info, - const std::string& client_id, + std::unique_ptr<ControllerServiceWorkerConnector> controller_connector, std::unique_ptr<network::SharedURLLoaderFactoryInfo> fallback_factory, network::mojom::URLLoaderFactoryRequest request, scoped_refptr<base::SequencedTaskRunner> task_runner) { ServiceWorkerSubresourceLoaderFactory::Create( - base::MakeRefCounted<ControllerServiceWorkerConnector>( - std::move(container_host_info), nullptr /* controller_ptr */, - client_id), + std::move(controller_connector), network::SharedURLLoaderFactory::Create(std::move(fallback_factory)), std::move(request), std::move(task_runner)); } @@ -398,8 +395,11 @@ task_runner->PostTask( FROM_HERE, base::BindOnce( - &CreateSubresourceLoaderFactoryForWorker, std::move(host_ptr_info), - client_id_, fallback_factory_->Clone(), + &CreateSubresourceLoaderFactoryForWorker, + std::make_unique<ControllerServiceWorkerConnector>( + std::move(host_ptr_info), mojom::ControllerServiceWorkerPtrInfo(), + client_id_, task_runner), + fallback_factory_->Clone(), mojo::MakeRequest(&service_worker_url_loader_factory), task_runner)); web_loader_factory_->SetServiceWorkerURLLoaderFactory( std::move(service_worker_url_loader_factory));
diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn index ab42e81..4ca446be 100644 --- a/content/shell/BUILD.gn +++ b/content/shell/BUILD.gn
@@ -352,10 +352,6 @@ ] } - if (is_linux && !is_android) { - deps += [ "//components/services/font:lib" ] - } - if (use_x11) { # Some tests rely on this tool at runtime. Note: it might be better if # the tests that needed it had this as a dep instead of adding it here. @@ -896,10 +892,6 @@ service_manifest("content_shell_packaged_services_manifest_overlay") { source = "//content/shell/browser/content_shell_packaged_services_manifest_overlay.json" packaged_services = [ "//services/test/echo:manifest" ] - - if (is_linux && !is_android) { - packaged_services += [ "//components/services/font:manifest" ] - } } group("content_shell_crash_test") {
diff --git a/content/shell/DEPS b/content/shell/DEPS index bb03394e1..d9f371c 100644 --- a/content/shell/DEPS +++ b/content/shell/DEPS
@@ -33,7 +33,6 @@ # 1) it's an example browser # 2) it's not linked into the content library "+components/embedder_support", - "+components/content_view", "+components/crash", "+components/download/public/common", "+components/url_formatter",
diff --git a/content/shell/android/BUILD.gn b/content/shell/android/BUILD.gn index a7bb1092..b073a67 100644 --- a/content/shell/android/BUILD.gn +++ b/content/shell/android/BUILD.gn
@@ -77,7 +77,7 @@ ":content_shell_java_resources", ":content_shell_manifest", "//base:base_java", - "//components/content_view:content_view_java", + "//components/embedder_support/android:content_view_java", "//components/embedder_support/android:media_java", "//components/embedder_support/android:view_java", "//content/public/android:content_java",
diff --git a/content/shell/android/java/src/org/chromium/content_shell/Shell.java b/content/shell/android/java/src/org/chromium/content_shell/Shell.java index e579df1..0833260 100644 --- a/content/shell/android/java/src/org/chromium/content_shell/Shell.java +++ b/content/shell/android/java/src/org/chromium/content_shell/Shell.java
@@ -27,8 +27,8 @@ import org.chromium.base.Callback; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; -import org.chromium.components.content_view.ContentView; import org.chromium.components.embedder_support.media.ActivityContentVideoViewEmbedder; +import org.chromium.components.embedder_support.view.ContentView; import org.chromium.components.embedder_support.view.ContentViewRenderView; import org.chromium.content.browser.ContentViewCoreImpl; import org.chromium.content_public.browser.ActionModeCallbackHelper;
diff --git a/content/shell/browser/shell_content_browser_client.cc b/content/shell/browser/shell_content_browser_client.cc index 904da49b..2a7e3b5 100644 --- a/content/shell/browser/shell_content_browser_client.cc +++ b/content/shell/browser/shell_content_browser_client.cc
@@ -65,11 +65,6 @@ #include "content/public/common/content_descriptors.h" #endif -#if defined(OS_LINUX) -#include "components/services/font/font_service_app.h" // nogncheck -#include "components/services/font/public/interfaces/constants.mojom.h" // nogncheck -#endif - #if defined(OS_WIN) #include "sandbox/win/src/sandbox.h" #include "services/service_manager/sandbox/win/sandbox_win.h" @@ -232,10 +227,6 @@ base::BindRepeating(&base::ASCIIToUTF16, "Test Service"); (*services)[echo::mojom::kServiceName] = base::BindRepeating(&base::ASCIIToUTF16, "Echo Service"); -#if defined(OS_LINUX) - (*services)[font_service::mojom::kServiceName] = - base::BindRepeating(&base::ASCIIToUTF16, "Font Service"); -#endif } bool ShellContentBrowserClient::ShouldTerminateOnServiceQuit(
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index df8913e..1280db73 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -1058,7 +1058,10 @@ } if (is_linux) { - sources += [ "../zygote/zygote_browsertest.cc" ] + sources += [ + "../browser/linux_ipc_browsertest.cc", + "../zygote/zygote_browsertest.cc", + ] deps += [ "//ui/gfx:test_support" ] } @@ -1687,10 +1690,12 @@ "../renderer/media/webrtc/rtc_peer_connection_handler_unittest.cc", "../renderer/media/webrtc/rtc_rtp_receiver_unittest.cc", "../renderer/media/webrtc/rtc_rtp_sender_unittest.cc", + "../renderer/media/webrtc/rtc_rtp_transceiver_unittest.cc", "../renderer/media/webrtc/rtc_stats_unittest.cc", "../renderer/media/webrtc/rtc_video_decoder_unittest.cc", "../renderer/media/webrtc/rtc_video_encoder_unittest.cc", "../renderer/media/webrtc/stun_field_trial_unittest.cc", + "../renderer/media/webrtc/transceiver_state_surfacer_unittest.cc", "../renderer/media/webrtc/two_keys_adapter_map_unittest.cc", "../renderer/media/webrtc/webrtc_audio_renderer_unittest.cc", "../renderer/media/webrtc/webrtc_media_stream_adapter_map_unittest.cc",
diff --git a/content/utility/BUILD.gn b/content/utility/BUILD.gn index 117ae90..610106e 100644 --- a/content/utility/BUILD.gn +++ b/content/utility/BUILD.gn
@@ -68,10 +68,6 @@ "//media/mojo/services", ] } - - if (is_linux && !is_android) { - deps += [ "//components/services/font:lib" ] - } } # See comment at the top of //content/BUILD.gn for how this works.
diff --git a/content/utility/utility_blink_platform_with_sandbox_support_impl.cc b/content/utility/utility_blink_platform_with_sandbox_support_impl.cc index 13ab692..a3987953 100644 --- a/content/utility/utility_blink_platform_with_sandbox_support_impl.cc +++ b/content/utility/utility_blink_platform_with_sandbox_support_impl.cc
@@ -13,8 +13,6 @@ #elif defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_FUCHSIA) #include "base/synchronization/lock.h" #include "content/child/child_process_sandbox_support_impl_linux.h" -#include "content/child/child_thread_impl.h" -#include "services/service_manager/public/cpp/connector.h" #include "third_party/blink/public/platform/linux/web_fallback_font.h" #include "third_party/blink/public/platform/linux/web_sandbox_support.h" #endif @@ -32,10 +30,6 @@ class UtilityBlinkPlatformWithSandboxSupportImpl::SandboxSupport : public blink::WebSandboxSupport { public: -#if defined(OS_LINUX) - explicit SandboxSupport(sk_sp<font_service::FontLoader> font_loader) - : font_loader_(std::move(font_loader)) {} -#endif ~SandboxSupport() override {} #if defined(OS_MACOSX) @@ -59,20 +53,14 @@ base::Lock unicode_font_families_mutex_; // Maps unicode chars to their fallback fonts. std::map<int32_t, blink::WebFallbackFont> unicode_font_families_; - sk_sp<font_service::FontLoader> font_loader_; #endif // defined(OS_MACOSX) }; #endif // defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_FUCHSIA) UtilityBlinkPlatformWithSandboxSupportImpl:: - UtilityBlinkPlatformWithSandboxSupportImpl( - service_manager::Connector* connector) { -#if defined(OS_LINUX) - font_loader_ = sk_make_sp<font_service::FontLoader>(connector); - SkFontConfigInterface::SetGlobal(font_loader_); - sandbox_support_ = std::make_unique<SandboxSupport>(font_loader_); -#elif defined(OS_MACOSX) + UtilityBlinkPlatformWithSandboxSupportImpl() { +#if defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_FUCHSIA) sandbox_support_ = std::make_unique<SandboxSupport>(); #endif } @@ -117,8 +105,9 @@ fallback_font->is_italic = iter->second.is_italic; return; } - content::GetFallbackFontForCharacter(font_loader_, character, - preferred_locale, fallback_font); + + content::GetFallbackFontForCharacter(character, preferred_locale, + fallback_font); unicode_font_families_.emplace(character, *fallback_font); } @@ -129,8 +118,8 @@ bool is_italic, float device_scale_factor, blink::WebFontRenderStyle* out) { - GetRenderStyleForStrike(font_loader_, family, size, is_bold, is_italic, - device_scale_factor, out); + GetRenderStyleForStrike(family, size, is_bold, is_italic, device_scale_factor, + out); } #endif
diff --git a/content/utility/utility_blink_platform_with_sandbox_support_impl.h b/content/utility/utility_blink_platform_with_sandbox_support_impl.h index bdb6e9e..db4236a 100644 --- a/content/utility/utility_blink_platform_with_sandbox_support_impl.h +++ b/content/utility/utility_blink_platform_with_sandbox_support_impl.h
@@ -11,19 +11,10 @@ #include "build/build_config.h" #include "content/utility/utility_blink_platform_impl.h" -#if defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_FUCHSIA) -#include "components/services/font/public/cpp/font_loader.h" // nogncheck -#include "third_party/skia/include/core/SkRefCnt.h" // nogncheck -#endif - namespace blink { class WebSandboxSupport; } -namespace service_manager { -class Connector; -} - namespace content { // This class extends from UtilityBlinkPlatformImpl with added blink web @@ -31,9 +22,7 @@ class UtilityBlinkPlatformWithSandboxSupportImpl : public UtilityBlinkPlatformImpl { public: - UtilityBlinkPlatformWithSandboxSupportImpl() = delete; - explicit UtilityBlinkPlatformWithSandboxSupportImpl( - service_manager::Connector*); + UtilityBlinkPlatformWithSandboxSupportImpl(); ~UtilityBlinkPlatformWithSandboxSupportImpl() override; // BlinkPlatformImpl @@ -44,9 +33,6 @@ class SandboxSupport; std::unique_ptr<SandboxSupport> sandbox_support_; #endif -#if defined(OS_LINUX) - sk_sp<font_service::FontLoader> font_loader_; -#endif DISALLOW_COPY_AND_ASSIGN(UtilityBlinkPlatformWithSandboxSupportImpl); };
diff --git a/content/utility/utility_service_factory.cc b/content/utility/utility_service_factory.cc index 2d0a82de..4d2eb95 100644 --- a/content/utility/utility_service_factory.cc +++ b/content/utility/utility_service_factory.cc
@@ -45,11 +45,6 @@ #endif // BUILDFLAG(ENABLE_CDM_HOST_VERIFICATION) #endif -#if defined(OS_LINUX) -#include "components/services/font/font_service_app.h" // nogncheck -#include "components/services/font/public/interfaces/constants.mojom.h" // nogncheck -#endif - #if defined(OS_WIN) #include "sandbox/win/src/sandbox.h" @@ -175,14 +170,6 @@ services->insert( std::make_pair(content::mojom::kNetworkServiceName, network_info)); } - -#if defined(OS_LINUX) - service_manager::EmbeddedServiceInfo font_service_info; - font_service_info.factory = - base::BindRepeating(&font_service::FontServiceApp::CreateService); - services->insert( - std::make_pair(font_service::mojom::kServiceName, font_service_info)); -#endif } void UtilityServiceFactory::OnServiceQuit() {
diff --git a/content/utility/utility_thread_impl.cc b/content/utility/utility_thread_impl.cc index 65b164f..767ee872 100644 --- a/content/utility/utility_thread_impl.cc +++ b/content/utility/utility_thread_impl.cc
@@ -118,8 +118,7 @@ blink_platform_impl_ = sandbox_support - ? std::make_unique<UtilityBlinkPlatformWithSandboxSupportImpl>( - GetConnector()) + ? std::make_unique<UtilityBlinkPlatformWithSandboxSupportImpl>() : std::make_unique<UtilityBlinkPlatformImpl>(); blink::Platform::Initialize(blink_platform_impl_.get()); }
diff --git a/device/vr/oculus/oculus_render_loop.cc b/device/vr/oculus/oculus_render_loop.cc index edfd54b..f7ee4af5 100644 --- a/device/vr/oculus/oculus_render_loop.cc +++ b/device/vr/oculus/oculus_render_loop.cc
@@ -362,7 +362,7 @@ device::mojom::XRInputSourceDescription::New(); // It's a handheld pointing device. - desc->pointer_origin = device::mojom::XRPointerOrigin::HAND; + desc->target_ray_mode = device::mojom::XRTargetRayMode::POINTING; // Set handedness. switch (hand) {
diff --git a/device/vr/openvr/openvr_render_loop.cc b/device/vr/openvr/openvr_render_loop.cc index b4a86e8..02d687e 100644 --- a/device/vr/openvr/openvr_render_loop.cc +++ b/device/vr/openvr/openvr_render_loop.cc
@@ -349,7 +349,7 @@ device::mojom::XRInputSourceDescription::New(); // It's a handheld pointing device. - desc->pointer_origin = device::mojom::XRPointerOrigin::HAND; + desc->target_ray_mode = device::mojom::XRTargetRayMode::POINTING; // Set handedness. switch (controller_role) {
diff --git a/device/vr/public/mojom/vr_service.mojom b/device/vr/public/mojom/vr_service.mojom index 885c648b..663276c3 100644 --- a/device/vr/public/mojom/vr_service.mojom +++ b/device/vr/public/mojom/vr_service.mojom
@@ -22,10 +22,10 @@ RIGHT = 2 }; -enum XRPointerOrigin { - HEAD = 1, - HAND = 2, - SCREEN = 3 +enum XRTargetRayMode { + GAZING = 1, + POINTING = 2, + TAPPING = 3 }; struct XRSessionOptions { @@ -47,7 +47,7 @@ }; struct XRInputSourceDescription { - XRPointerOrigin pointer_origin; + XRTargetRayMode target_ray_mode; XRHandedness handedness; bool emulated_position;
diff --git a/docs/linux_sandbox_ipc.md b/docs/linux_sandbox_ipc.md index f0555b8..5ff70906 100644 --- a/docs/linux_sandbox_ipc.md +++ b/docs/linux_sandbox_ipc.md
@@ -4,13 +4,11 @@ is a lower level system which deals with cases where we need to route requests from the bottom of the call stack up into the browser. -The motivating example used to be Skia, which uses fontconfig to load -fonts. Howvever, the OOP IPC for FontConfig was moved to using Font Service and -the `components/services/font/public/cpp/font_loader.h` interface. - -These days, only the out-of-process localtime implementation as well as -an OOP call for making a shared memory segment are using the Sandbox IPC -file-descriptor based system. See `sandbox/linux/services/libc_interceptor.cc`. +The motivating example is Skia, which uses fontconfig to load fonts. In a +chrooted renderer we cannot access the user's fontcache, nor the font files +themselves. However, font loading happens when we have called through WebKit, +through Skia and into the SkFontHost. At this point, we cannot loop back around +to use the main IPC system. Thus we define a small IPC system which doesn't depend on anything but `base` and which can make synchronous requests to the browser process. @@ -38,12 +36,22 @@ Here is a (possibly incomplete) list of endpoints in the renderer: -### localtime +### fontconfig -`content/browser/sandbox_ipc_linux.h` defines HandleLocalTime which is -implemented in `sandbox/linux/services/libc_interceptor.cc`. +As mentioned above, the motivating example of this is dealing with fontconfig +from a chrooted renderer. We implement our own Skia FontHost, outside of the +Skia tree, in `skia/ext/SkFontHost_fontconfig**`. -### Creating a shared memory segment +There are two methods used. One for performing a match against the fontconfig +data and one to return a file descriptor to a font file resulting from one of +those matches. The only wrinkle is that fontconfig is a single-threaded library +and it's already used in the browser by GTK itself. -`content/browser/sandbox_ipc_linux.h` defines HandleMakeSharedMemorySegment -which is implemented in `content/browser/sandbox_ipc_linux.cc`. +Thus, we have a couple of options: + +1. Handle the requests on the UI thread in the browser. +1. Handle the requests in a separate address space. + +The original implementation did the former (handle on UI thread). This turned +out to be a terrible idea, performance wise, so we now handle the requests on a +dedicated process.
diff --git a/docs/speed/apk_size_regressions.md b/docs/speed/apk_size_regressions.md index 4354530..af1f8c3 100644 --- a/docs/speed/apk_size_regressions.md +++ b/docs/speed/apk_size_regressions.md
@@ -158,6 +158,11 @@ * Use [//tools/binary_size/diagnose_bloat.py](https://chromium.googlesource.com/chromium/src/+/master/tools/binary_size/README.md) to show a diff of Java symbols. * Ensure any new Java deps are as specific as possible. + * If the change doesn't look suspect, check to see if the regression still + exists when internal proguard is used (see + [downstream graphs](https://chromeperf.appspot.com/report?sid=83bf643964a326648325f7eb6767d8adb85d67db8306dd94aa7476ed70d7dace) + or use `diagnose_bloat.py -v --enable-chrome-android-internal REV` + to build locally) ### Growth is from "other lib size" or "Unknown files size"
diff --git a/extensions/shell/BUILD.gn b/extensions/shell/BUILD.gn index 8debf0c..b46aaa83 100644 --- a/extensions/shell/BUILD.gn +++ b/extensions/shell/BUILD.gn
@@ -222,10 +222,6 @@ ] } - if (is_linux) { - deps += [ "//components/services/font/public/cpp" ] - } - if (is_chromeos) { sources += [ "browser/api/vpn_provider/vpn_service_factory.cc",
diff --git a/extensions/shell/browser/DEPS b/extensions/shell/browser/DEPS index 2f55513..ac34117 100644 --- a/extensions/shell/browser/DEPS +++ b/extensions/shell/browser/DEPS
@@ -8,7 +8,6 @@ "+components/network_session_configurator/common", "+components/pref_registry", "+components/sessions", - "+components/services/font", "+components/update_client", "+components/user_prefs", "+components/web_modal",
diff --git a/extensions/shell/browser/shell_content_browser_client.cc b/extensions/shell/browser/shell_content_browser_client.cc index fd77420..c018d0c 100644 --- a/extensions/shell/browser/shell_content_browser_client.cc +++ b/extensions/shell/browser/shell_content_browser_client.cc
@@ -8,10 +8,8 @@ #include <utility> -#include "base/bind.h" #include "base/command_line.h" #include "base/macros.h" -#include "build/build_config.h" #include "components/guest_view/browser/guest_view_message_filter.h" #include "components/nacl/common/buildflags.h" #include "content/public/browser/browser_main_runner.h" @@ -58,12 +56,6 @@ #include "content/public/browser/child_process_data.h" #endif -#if defined(OS_LINUX) -#include "base/strings/utf_string_conversions.h" -#include "components/services/font/font_service_app.h" // nogncheck -#include "components/services/font/public/interfaces/constants.mojom.h" // nogncheck -#endif - using base::CommandLine; using content::BrowserContext; using content::BrowserThread; @@ -265,14 +257,6 @@ return throttles; } -void ShellContentBrowserClient::RegisterOutOfProcessServices( - OutOfProcessServiceMap* services) { -#if defined(OS_LINUX) - (*services)[font_service::mojom::kServiceName] = - base::BindRepeating(&base::ASCIIToUTF16, "Font Service"); -#endif -} - std::unique_ptr<content::NavigationUIData> ShellContentBrowserClient::GetNavigationUIData( content::NavigationHandle* navigation_handle) {
diff --git a/extensions/shell/browser/shell_content_browser_client.h b/extensions/shell/browser/shell_content_browser_client.h index 3bb45208..3be19c9 100644 --- a/extensions/shell/browser/shell_content_browser_client.h +++ b/extensions/shell/browser/shell_content_browser_client.h
@@ -64,7 +64,6 @@ std::vector<std::unique_ptr<content::NavigationThrottle>> CreateThrottlesForNavigation( content::NavigationHandle* navigation_handle) override; - void RegisterOutOfProcessServices(OutOfProcessServiceMap* services) override; std::unique_ptr<content::NavigationUIData> GetNavigationUIData( content::NavigationHandle* navigation_handle) override; void RegisterNonNetworkNavigationURLLoaderFactories(
diff --git a/headless/BUILD.gn b/headless/BUILD.gn index 7e22f62..de14e675 100644 --- a/headless/BUILD.gn +++ b/headless/BUILD.gn
@@ -449,10 +449,6 @@ deps += [ "//components/os_crypt" ] } - if (is_linux) { - deps += [ "//components/services/font/public/cpp" ] - } - if (is_component_build) { sources += [ "lib/browser/headless_content_browser_client.cc",
diff --git a/headless/lib/browser/DEPS b/headless/lib/browser/DEPS index 6552fb8..f20dffe 100644 --- a/headless/lib/browser/DEPS +++ b/headless/lib/browser/DEPS
@@ -3,7 +3,6 @@ "+components/printing/browser", "+components/printing/common", "+components/security_state", - "+components/services/font", "+components/viz", "+printing", "+storage/browser/quota",
diff --git a/headless/lib/browser/headless_content_browser_client.cc b/headless/lib/browser/headless_content_browser_client.cc index 715270a..b764fc0 100644 --- a/headless/lib/browser/headless_content_browser_client.cc +++ b/headless/lib/browser/headless_content_browser_client.cc
@@ -13,7 +13,6 @@ #include "base/json/json_reader.h" #include "base/path_service.h" #include "base/strings/string_number_conversions.h" -#include "build/build_config.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/client_certificate_delegate.h" @@ -51,11 +50,6 @@ #include "components/services/pdf_compositor/public/interfaces/pdf_compositor.mojom.h" #endif -#if defined(OS_LINUX) -#include "components/services/font/font_service_app.h" // nogncheck -#include "components/services/font/public/interfaces/constants.mojom.h" // nogncheck -#endif - namespace headless { namespace { @@ -171,10 +165,6 @@ (*services)[printing::mojom::kServiceName] = base::BindRepeating(&base::ASCIIToUTF16, "PDF Compositor Service"); #endif -#if defined(OS_LINUX) - (*services)[font_service::mojom::kServiceName] = - base::BindRepeating(&base::ASCIIToUTF16, "Font Service"); -#endif } std::unique_ptr<base::Value>
diff --git a/ios/build/bots/scripts/test_runner.py b/ios/build/bots/scripts/test_runner.py index 58648b0..578801cc 100644 --- a/ios/build/bots/scripts/test_runner.py +++ b/ios/build/bots/scripts/test_runner.py
@@ -551,6 +551,7 @@ raise # Retry failed test cases. + retry_results = {} if self.retries and failed: print '%s tests failed and will be retried.' % len(failed) print @@ -558,13 +559,20 @@ for test in failed.keys(): print 'Retry #%s for %s.' % (i + 1, test) print - result = self._run(self.get_launch_command(test_filter=[test])) + retry_result = self._run(self.get_launch_command( + test_filter=[test] + )) # If the test passed on retry, consider it flake instead of failure. - if test in result.passed_tests: + if test in retry_result.passed_tests: flaked[test] = failed.pop(test) + # Save the result of the latest run for each test. + retry_results[test] = retry_result # Build test_results.json. - self.test_results['interrupted'] = result.crashed + # Check if if any of the retries crashed in addition to the original run. + interrupted = (result.crashed or + any([r.crashed for r in retry_results.values()])) + self.test_results['interrupted'] = interrupted self.test_results['num_failures_by_type'] = { 'FAIL': len(failed) + len(flaked), 'PASS': len(passed), @@ -584,7 +592,7 @@ for test, log_lines in flaked.iteritems(): self.logs[test] = log_lines - return not failed + return not failed and not interrupted finally: self.tear_down()
diff --git a/ios/chrome/browser/autofill/form_input_egtest.mm b/ios/chrome/browser/autofill/form_input_egtest.mm index 14fad89..1bfdfab7 100644 --- a/ios/chrome/browser/autofill/form_input_egtest.mm +++ b/ios/chrome/browser/autofill/form_input_egtest.mm
@@ -17,6 +17,7 @@ #import "ios/testing/wait_util.h" #import "ios/web/public/test/earl_grey/web_view_actions.h" #import "ios/web/public/test/earl_grey/web_view_matchers.h" +#include "ios/web/public/test/element_selector.h" #import "ios/web/public/test/http_server/http_server.h" #include "ios/web/public/test/http_server/http_server_util.h" @@ -24,6 +25,8 @@ #error "This file requires ARC support." #endif +using web::test::ElementSelector; + namespace { const char kFormElementId1[] = "username"; @@ -100,7 +103,7 @@ chrome_test_util::GetCurrentWebState())] performAction:web::WebViewTapElement( chrome_test_util::GetCurrentWebState(), - kFormElementId1)]; + ElementSelector::ElementSelectorId(kFormElementId1))]; id<GREYMatcher> nextButtonMatcher = chrome_test_util::ButtonWithAccessibilityLabelId(
diff --git a/ios/chrome/browser/context_menu/context_menu_egtest.mm b/ios/chrome/browser/context_menu/context_menu_egtest.mm index 6cbbb83..6b263ae 100644 --- a/ios/chrome/browser/context_menu/context_menu_egtest.mm +++ b/ios/chrome/browser/context_menu/context_menu_egtest.mm
@@ -23,6 +23,7 @@ #import "ios/testing/wait_util.h" #import "ios/web/public/features.h" #import "ios/web/public/test/earl_grey/web_view_matchers.h" +#include "ios/web/public/test/element_selector.h" #include "net/test/embedded_test_server/http_request.h" #include "net/test/embedded_test_server/http_response.h" #include "url/gurl.h" @@ -37,6 +38,7 @@ using chrome_test_util::OpenLinkInNewTabButton; using chrome_test_util::SystemSelectionCallout; using chrome_test_util::SystemSelectionCalloutCopyButton; +using web::test::ElementSelector; namespace { // Directory containing the |kLogoPagePath| and |kLogoPageImageSourcePath| @@ -126,7 +128,8 @@ web::WebViewInWebState(chrome_test_util::GetCurrentWebState()); [[EarlGrey selectElementWithMatcher:web_view_matcher] performAction:chrome_test_util::LongPressElementForContextMenu( - element_id, true /* menu should appear */)]; + ElementSelector::ElementSelectorId(element_id), + true /* menu should appear */)]; } // Tap on |context_menu_item_button| context menu item.
diff --git a/ios/chrome/browser/metrics/tab_usage_recorder_egtest.mm b/ios/chrome/browser/metrics/tab_usage_recorder_egtest.mm index 91c6b11b..e342847 100644 --- a/ios/chrome/browser/metrics/tab_usage_recorder_egtest.mm +++ b/ios/chrome/browser/metrics/tab_usage_recorder_egtest.mm
@@ -31,6 +31,7 @@ #import "ios/chrome/test/earl_grey/chrome_test_case.h" #import "ios/testing/wait_util.h" #import "ios/web/public/test/earl_grey/web_view_matchers.h" +#include "ios/web/public/test/element_selector.h" #include "ios/web/public/test/http_server/delayed_response_provider.h" #include "ios/web/public/test/http_server/html_response_provider.h" #import "ios/web/public/test/http_server/http_server.h" @@ -48,6 +49,7 @@ using chrome_test_util::SettingsMenuPrivacyButton; using tab_usage_recorder_test_util::OpenNewIncognitoTabUsingUIAndEvictMainTabs; using tab_usage_recorder_test_util::SwitchToNormalMode; +using web::test::ElementSelector; namespace { @@ -691,7 +693,8 @@ web::WebViewInWebState(chrome_test_util::GetCurrentWebState()); [[EarlGrey selectElementWithMatcher:webViewMatcher] performAction:chrome_test_util::LongPressElementForContextMenu( - "link", true /* menu should appear */)]; + ElementSelector::ElementSelectorId("link"), + true /* menu should appear */)]; [[EarlGrey selectElementWithMatcher:OpenLinkInNewTabButton()] performAction:grey_tap()];
diff --git a/ios/chrome/browser/ui/authentication/BUILD.gn b/ios/chrome/browser/ui/authentication/BUILD.gn index f908a6c..4c41fac 100644 --- a/ios/chrome/browser/ui/authentication/BUILD.gn +++ b/ios/chrome/browser/ui/authentication/BUILD.gn
@@ -131,6 +131,7 @@ "//base", "//base/test:test_support", "//components/consent_auditor", + "//components/consent_auditor:test_support", "//components/pref_registry", "//components/signin/core/browser:browser", "//components/sync_preferences",
diff --git a/ios/chrome/browser/ui/authentication/chrome_signin_view_controller_unittest.mm b/ios/chrome/browser/ui/authentication/chrome_signin_view_controller_unittest.mm index a9a0149..ab220e9f 100644 --- a/ios/chrome/browser/ui/authentication/chrome_signin_view_controller_unittest.mm +++ b/ios/chrome/browser/ui/authentication/chrome_signin_view_controller_unittest.mm
@@ -11,6 +11,7 @@ #include "base/test/scoped_feature_list.h" #include "base/timer/mock_timer.h" #include "components/consent_auditor/consent_auditor.h" +#include "components/consent_auditor/fake_consent_auditor.h" #include "components/signin/core/browser/account_tracker_service.h" #include "components/signin/core/browser/profile_management_switches.h" #include "components/version_info/version_info.h" @@ -80,59 +81,15 @@ false, true, }; -// Fake consent auditor used for the tests. -class FakeConsentAuditor : public consent_auditor::ConsentAuditor { - public: - static std::unique_ptr<KeyedService> CreateInstance( - web::BrowserState* context) { - ios::ChromeBrowserState* ios_context = - ios::ChromeBrowserState::FromBrowserState(context); - syncer::UserEventService* const user_event_service = - IOSUserEventServiceFactory::GetForBrowserState(ios_context); - return std::make_unique<FakeConsentAuditor>( - ios_context->GetPrefs(), user_event_service, - version_info::GetVersionNumber(), - GetApplicationContext()->GetApplicationLocale()); - } - - FakeConsentAuditor(PrefService* pref_service, - syncer::UserEventService* user_event_service, - const std::string& app_version, - const std::string& app_locale) - : ConsentAuditor(pref_service, - /*consent_sync_bridge=*/nullptr, - user_event_service, - app_version, - app_locale) {} - ~FakeConsentAuditor() override {} - - void RecordGaiaConsent(const std::string& account_id, - consent_auditor::Feature feature, - const std::vector<int>& description_grd_ids, - int confirmation_string_id, - consent_auditor::ConsentStatus status) override { - account_id_ = account_id; - feature_ = feature; - recorded_ids_ = description_grd_ids; - confirmation_string_id_ = confirmation_string_id; - status_ = status; - } - - const std::string& account_id() const { return account_id_; } - consent_auditor::Feature feature() const { return feature_; } - const std::vector<int>& recorded_ids() const { return recorded_ids_; } - int confirmation_string_id() const { return confirmation_string_id_; } - consent_auditor::ConsentStatus status() const { return status_; } - - private: - std::string account_id_; - consent_auditor::Feature feature_; - std::vector<int> recorded_ids_; - int confirmation_string_id_ = -1; - consent_auditor::ConsentStatus status_; - - DISALLOW_COPY_AND_ASSIGN(FakeConsentAuditor); -}; +static std::unique_ptr<KeyedService> CreateFakeConsentAuditor( + web::BrowserState* context) { + ios::ChromeBrowserState* ios_context = + ios::ChromeBrowserState::FromBrowserState(context); + syncer::UserEventService* const user_event_service = + IOSUserEventServiceFactory::GetForBrowserState(ios_context); + return std::make_unique<consent_auditor::FakeConsentAuditor>( + ios_context->GetPrefs(), user_event_service); +} // These tests verify that Chrome correctly records user's consent to Chrome // Sync, which is a GDPR requirement. None of those tests should be turned off. @@ -160,16 +117,19 @@ builder.AddTestingFactory( AuthenticationServiceFactory::GetInstance(), AuthenticationServiceFake::CreateAuthenticationService); + builder.AddTestingFactory(ConsentAuditorFactory::GetInstance(), - FakeConsentAuditor::CreateInstance); + &CreateFakeConsentAuditor); context_ = builder.Build(); ios::FakeChromeIdentityService* identity_service = ios::FakeChromeIdentityService::GetInstanceFromChromeProvider(); identity_service->AddIdentity(identity_); account_tracker_service_ = ios::AccountTrackerServiceFactory::GetForBrowserState(context_.get()); - fake_consent_auditor_ = static_cast<FakeConsentAuditor*>( + + fake_consent_auditor_ = static_cast<consent_auditor::FakeConsentAuditor*>( ConsentAuditorFactory::GetForBrowserState(context_.get())); + // Setup view controller. vc_ = [[ChromeSigninViewController alloc] initWithBrowserState:context_.get() @@ -401,7 +361,7 @@ FakeChromeIdentity* identity_; UIWindow* window_; ChromeSigninViewController* vc_; - FakeConsentAuditor* fake_consent_auditor_; + consent_auditor::FakeConsentAuditor* fake_consent_auditor_; AccountTrackerService* account_tracker_service_; base::test::ScopedFeatureList scoped_feature_list_; base::MockOneShotTimer* mock_timer_ptr_ = nullptr; @@ -429,14 +389,15 @@ return this->vc_delegate_.didSigninCalled; }; EXPECT_TRUE(testing::WaitUntilConditionOrTimeout(10, condition)); - const std::vector<int>& recorded_ids = fake_consent_auditor_->recorded_ids(); + const std::vector<int>& recorded_ids = + fake_consent_auditor_->recorded_id_vectors().at(0); EXPECT_EQ(ExpectedConsentStringIds(), recorded_ids); EXPECT_EQ(ConfirmationStringId(), - fake_consent_auditor_->confirmation_string_id()); + fake_consent_auditor_->recorded_confirmation_ids().at(0)); EXPECT_EQ(consent_auditor::ConsentStatus::GIVEN, - fake_consent_auditor_->status()); + fake_consent_auditor_->recorded_statuses().at(0)); EXPECT_EQ(consent_auditor::Feature::CHROME_SYNC, - fake_consent_auditor_->feature()); + fake_consent_auditor_->recorded_features().at(0)); EXPECT_EQ(account_tracker_service_->PickAccountIdForAccount( base::SysNSStringToUTF8([identity_ gaiaID]), base::SysNSStringToUTF8([identity_ userEmail])), @@ -447,9 +408,8 @@ TEST_P(ChromeSigninViewControllerTest, TestRefusingConsent) { WaitAndExpectAllStringsOnScreen(); [vc_.secondaryButton sendActionsForControlEvents:UIControlEventTouchUpInside]; - const std::vector<int>& recorded_ids = fake_consent_auditor_->recorded_ids(); - EXPECT_EQ(0ul, recorded_ids.size()); - EXPECT_EQ(-1, fake_consent_auditor_->confirmation_string_id()); + EXPECT_EQ(0ul, fake_consent_auditor_->recorded_id_vectors().size()); + EXPECT_EQ(0ul, fake_consent_auditor_->recorded_confirmation_ids().size()); } // Tests that RecordGaiaConsent() is called with the expected list of string @@ -457,14 +417,15 @@ TEST_P(ChromeSigninViewControllerTest, TestConsentWithSettings) { WaitAndExpectAllStringsOnScreen(); [vc_ signinConfirmationControllerDidTapSettingsLink:vc_.confirmationVC]; - const std::vector<int>& recorded_ids = fake_consent_auditor_->recorded_ids(); + const std::vector<int>& recorded_ids = + fake_consent_auditor_->recorded_id_vectors().at(0); EXPECT_EQ(ExpectedConsentStringIds(), recorded_ids); EXPECT_EQ(SettingsConfirmationStringId(), - fake_consent_auditor_->confirmation_string_id()); + fake_consent_auditor_->recorded_confirmation_ids().at(0)); EXPECT_EQ(consent_auditor::ConsentStatus::GIVEN, - fake_consent_auditor_->status()); + fake_consent_auditor_->recorded_statuses().at(0)); EXPECT_EQ(consent_auditor::Feature::CHROME_SYNC, - fake_consent_auditor_->feature()); + fake_consent_auditor_->recorded_features().at(0)); EXPECT_EQ(account_tracker_service_->PickAccountIdForAccount( base::SysNSStringToUTF8([identity_ gaiaID]), base::SysNSStringToUTF8([identity_ userEmail])),
diff --git a/ios/chrome/browser/ui/dialogs/javascript_dialog_egtest.mm b/ios/chrome/browser/ui/dialogs/javascript_dialog_egtest.mm index 68bbbde..dd8decf8 100644 --- a/ios/chrome/browser/ui/dialogs/javascript_dialog_egtest.mm +++ b/ios/chrome/browser/ui/dialogs/javascript_dialog_egtest.mm
@@ -23,6 +23,7 @@ #import "ios/testing/earl_grey/matchers.h" #import "ios/testing/wait_util.h" #import "ios/web/public/test/earl_grey/web_view_matchers.h" +#include "ios/web/public/test/element_selector.h" #import "ios/web/public/test/http_server/http_server.h" #include "ios/web/public/test/http_server/http_server_util.h" #include "ios/web/public/test/url_test_util.h" @@ -38,6 +39,7 @@ using chrome_test_util::ButtonWithAccessibilityLabel; using chrome_test_util::OKButton; using chrome_test_util::SettingsDoneButton; +using web::test::ElementSelector; using web::test::HttpServer; namespace { @@ -523,7 +525,8 @@ [[EarlGrey selectElementWithMatcher:webViewMatcher] performAction:chrome_test_util::LongPressElementForContextMenu( - kLinkID, true /* menu should appear */)]; + ElementSelector::ElementSelectorId(kLinkID), + true /* menu should appear */)]; // Tap on the "Open In New Tab" button. id<GREYMatcher> newTabMatcher = ButtonWithAccessibilityLabel(
diff --git a/ios/chrome/browser/ui/fullscreen/fullscreen_web_state_observer.mm b/ios/chrome/browser/ui/fullscreen/fullscreen_web_state_observer.mm index bf3b716..1ce7a5d 100644 --- a/ios/chrome/browser/ui/fullscreen/fullscreen_web_state_observer.mm +++ b/ios/chrome/browser/ui/fullscreen/fullscreen_web_state_observer.mm
@@ -104,6 +104,13 @@ void FullscreenWebStateObserver::DidStartLoading(web::WebState* web_state) { SetIsLoading(true); + if (IsUIRefreshPhase1Enabled()) { + // This is done to show the toolbar when navigating to a page that is + // considered as being in the SameDocument by the NavigationContext, so the + // toolbar isn't shown in the DidFinishNavigation. For example this is + // needed to load AMP pages from Google Search Result Page. + controller_->ResetModel(); + } } void FullscreenWebStateObserver::DidStopLoading(web::WebState* web_state) {
diff --git a/ios/chrome/browser/ui/settings/passwords_settings_egtest.mm b/ios/chrome/browser/ui/settings/passwords_settings_egtest.mm index 7a051e4b..9da223e 100644 --- a/ios/chrome/browser/ui/settings/passwords_settings_egtest.mm +++ b/ios/chrome/browser/ui/settings/passwords_settings_egtest.mm
@@ -38,6 +38,7 @@ #import "ios/third_party/material_components_ios/src/components/Snackbar/src/MaterialSnackbar.h" #include "ios/web/public/test/earl_grey/web_view_actions.h" #include "ios/web/public/test/earl_grey/web_view_matchers.h" +#include "ios/web/public/test/element_selector.h" #include "ios/web/public/test/http_server/http_server.h" #include "ios/web/public/test/http_server/http_server_util.h" #include "ui/base/l10n/l10n_util.h" @@ -60,6 +61,7 @@ using chrome_test_util::SettingsMenuBackButton; using chrome_test_util::SetUpAndReturnMockReauthenticationModule; using chrome_test_util::SetUpAndReturnMockReauthenticationModuleForExport; +using web::test::ElementSelector; namespace { @@ -1558,7 +1560,8 @@ selectElementWithMatcher:web::WebViewInWebState( chrome_test_util::GetCurrentWebState())] performAction:web::WebViewTapElement( - chrome_test_util::GetCurrentWebState(), "password")]; + chrome_test_util::GetCurrentWebState(), + ElementSelector::ElementSelectorId("password"))]; // Wait until the keyboard shows up before tapping. id<GREYMatcher> showAll = grey_allOf(
diff --git a/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_egtest.mm b/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_egtest.mm index 8afcfa97f..c75700c 100644 --- a/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_egtest.mm +++ b/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_egtest.mm
@@ -28,6 +28,7 @@ #include "ios/testing/earl_grey/disabled_test_macros.h" #import "ios/testing/earl_grey/disabled_test_macros.h" #import "ios/web/public/test/earl_grey/web_view_matchers.h" +#include "ios/web/public/test/element_selector.h" #include "net/test/embedded_test_server/http_request.h" #include "net/test/embedded_test_server/http_response.h" #include "ui/base/l10n/l10n_util_mac.h" @@ -36,6 +37,8 @@ #error "This file requires ARC support." #endif +using web::test::ElementSelector; + namespace { using chrome_test_util::BackButton; @@ -690,7 +693,8 @@ selectElementWithMatcher:web::WebViewInWebState( chrome_test_util::GetCurrentWebState())] performAction:chrome_test_util::LongPressElementForContextMenu( - kLinkID, true /* menu should appear */)]; + ElementSelector::ElementSelectorId(kLinkID), + true /* menu should appear */)]; [[EarlGrey selectElementWithMatcher: chrome_test_util::StaticTextWithAccessibilityLabelId( IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWINCOGNITOTAB)]
diff --git a/ios/chrome/browser/web/forms_egtest.mm b/ios/chrome/browser/web/forms_egtest.mm index 625fbba..b0ea927d 100644 --- a/ios/chrome/browser/web/forms_egtest.mm +++ b/ios/chrome/browser/web/forms_egtest.mm
@@ -22,6 +22,7 @@ #import "ios/testing/wait_util.h" #import "ios/web/public/test/earl_grey/web_view_actions.h" #import "ios/web/public/test/earl_grey/web_view_matchers.h" +#include "ios/web/public/test/element_selector.h" #include "ios/web/public/test/http_server/data_response_provider.h" #import "ios/web/public/test/http_server/http_server.h" #include "ios/web/public/test/http_server/http_server_util.h" @@ -35,6 +36,7 @@ using chrome_test_util::OmniboxText; using chrome_test_util::TapWebViewElementWithId; using testing::ElementToDismissAlert; +using web::test::ElementSelector; namespace { @@ -445,7 +447,9 @@ web::WebState* currentWebState = chrome_test_util::GetCurrentWebState(); [[EarlGrey selectElementWithMatcher:web::WebViewInWebState(currentWebState)] - performAction:web::WebViewTapElement(currentWebState, ID)]; + performAction:web::WebViewTapElement( + currentWebState, + ElementSelector::ElementSelectorId(ID))]; // Wait until the keyboard shows up before tapping. GREYCondition* condition = [GREYCondition
diff --git a/ios/chrome/browser/web/window_open_by_dom_egtest.mm b/ios/chrome/browser/web/window_open_by_dom_egtest.mm index 4d1b893e..05c4102 100644 --- a/ios/chrome/browser/web/window_open_by_dom_egtest.mm +++ b/ios/chrome/browser/web/window_open_by_dom_egtest.mm
@@ -20,6 +20,7 @@ #import "ios/chrome/test/earl_grey/chrome_test_case.h" #import "ios/web/public/test/earl_grey/web_view_actions.h" #import "ios/web/public/test/earl_grey/web_view_matchers.h" +#include "ios/web/public/test/element_selector.h" #import "ios/web/public/test/http_server/http_server.h" #include "ios/web/public/test/http_server/http_server_util.h" #include "ui/base/l10n/l10n_util.h" @@ -32,6 +33,7 @@ using chrome_test_util::GetCurrentWebState; using chrome_test_util::OmniboxText; using chrome_test_util::TapWebViewElementWithId; +using web::test::ElementSelector; using web::test::HttpServer; using web::WebViewInWebState; @@ -92,7 +94,9 @@ GREYAssert(!error, @"Error during script execution: %@", error); const char ID[] = "webScenarioWindowOpenSameURLWithBlankTarget"; [[EarlGrey selectElementWithMatcher:WebViewInWebState(GetCurrentWebState())] - performAction:web::WebViewTapElement(GetCurrentWebState(), ID)]; + performAction:web::WebViewTapElement( + GetCurrentWebState(), + ElementSelector::ElementSelectorId(ID))]; [ChromeEarlGrey waitForMainTabCount:2]; [ChromeEarlGrey waitForWebViewContainingText:"Expected result"]; @@ -106,7 +110,9 @@ - (void)testLinkWithBlankTarget { const char ID[] = "webScenarioWindowOpenRegularLink"; [[EarlGrey selectElementWithMatcher:WebViewInWebState(GetCurrentWebState())] - performAction:web::WebViewTapElement(GetCurrentWebState(), ID)]; + performAction:web::WebViewTapElement( + GetCurrentWebState(), + ElementSelector::ElementSelectorId(ID))]; [ChromeEarlGrey waitForMainTabCount:2]; } @@ -126,13 +132,17 @@ - (void)testLinkWithBlankTargetMultipleTimes { const char ID[] = "webScenarioWindowOpenRegularLinkMultipleTimes"; [[EarlGrey selectElementWithMatcher:WebViewInWebState(GetCurrentWebState())] - performAction:web::WebViewTapElement(GetCurrentWebState(), ID)]; + performAction:web::WebViewTapElement( + GetCurrentWebState(), + ElementSelector::ElementSelectorId(ID))]; [ChromeEarlGrey waitForMainTabCount:2]; chrome_test_util::OpenNewTab(); [ChromeEarlGrey waitForMainTabCount:3]; chrome_test_util::SelectTabAtIndexInCurrentMode(0); [[EarlGrey selectElementWithMatcher:WebViewInWebState(GetCurrentWebState())] - performAction:web::WebViewTapElement(GetCurrentWebState(), ID)]; + performAction:web::WebViewTapElement( + GetCurrentWebState(), + ElementSelector::ElementSelectorId(ID))]; [ChromeEarlGrey waitForMainTabCount:4]; } @@ -186,7 +196,9 @@ - (void)testLinkWithBlankTargetWithDelayedClose { const char ID[] = "webScenarioWindowOpenWithDelayedClose"; [[EarlGrey selectElementWithMatcher:WebViewInWebState(GetCurrentWebState())] - performAction:web::WebViewTapElement(GetCurrentWebState(), ID)]; + performAction:web::WebViewTapElement( + GetCurrentWebState(), + ElementSelector::ElementSelectorId(ID))]; [ChromeEarlGrey waitForMainTabCount:2]; base::test::ios::SpinRunLoopWithMinDelay(base::TimeDelta::FromSecondsD(1)); [ChromeEarlGrey waitForMainTabCount:1]; @@ -243,7 +255,9 @@ - (void)testWindowOpenWithAboutNewTabScript { const char ID[] = "webScenarioWindowOpenWithAboutNewTabScript"; [[EarlGrey selectElementWithMatcher:WebViewInWebState(GetCurrentWebState())] - performAction:web::WebViewTapElement(GetCurrentWebState(), ID)]; + performAction:web::WebViewTapElement( + GetCurrentWebState(), + ElementSelector::ElementSelectorId(ID))]; [ChromeEarlGrey waitForMainTabCount:2]; [[EarlGrey selectElementWithMatcher:OmniboxText("about:newtab")] assertWithMatcher:grey_notNil()];
diff --git a/ios/chrome/test/earl_grey/BUILD.gn b/ios/chrome/test/earl_grey/BUILD.gn index 9f5188077..7cb946e 100644 --- a/ios/chrome/test/earl_grey/BUILD.gn +++ b/ios/chrome/test/earl_grey/BUILD.gn
@@ -261,7 +261,6 @@ "//ios/third_party/material_components_ios", "//ios/web", "//ios/web:earl_grey_test_support", - "//ios/web/public/test", "//ios/web/public/test/http_server", "//ui/base", "//ui/base:test_support", @@ -271,6 +270,7 @@ public_deps = [ "//build/config/ios:xctest", "//ios/third_party/earl_grey:earl_grey+link", + "//ios/web/public/test", "//ios/web/public/test/fakes", "//net:test_support", ]
diff --git a/ios/chrome/test/earl_grey/chrome_actions.h b/ios/chrome/test/earl_grey/chrome_actions.h index 1edc9c2..861f3ae 100644 --- a/ios/chrome/test/earl_grey/chrome_actions.h +++ b/ios/chrome/test/earl_grey/chrome_actions.h
@@ -9,16 +9,22 @@ #import <EarlGrey/EarlGrey.h> +#include "ios/web/public/test/element_selector.h" + namespace chrome_test_util { -// Action to longpress on element |element_id| in the Chrome's webview. -// If |triggers_context_menu| is true, this gesture is expected to +// Action to longpress on the element selected by |selector| in the Chrome's +// webview. If |triggers_context_menu| is true, this gesture is expected to // cause the context menu to appear, and is not expected to trigger events // in the webview. If |triggers_context_menu| is false, the converse is true. // This action doesn't fail if the context menu isn't displayed; calling code // should check for that separately with a matcher. -id<GREYAction> LongPressElementForContextMenu(const std::string& element_id, +// The version taking an |elementId| is deprecated and will be removed. +id<GREYAction> LongPressElementForContextMenu(const std::string& elementId, bool triggers_context_menu); +id<GREYAction> LongPressElementForContextMenu( + web::test::ElementSelector selector, + bool triggers_context_menu); // Action to turn the switch of a SettingsSwitchCell to the given |on| // state.
diff --git a/ios/chrome/test/earl_grey/chrome_actions.mm b/ios/chrome/test/earl_grey/chrome_actions.mm index d3a1817..d3c1c31 100644 --- a/ios/chrome/test/earl_grey/chrome_actions.mm +++ b/ios/chrome/test/earl_grey/chrome_actions.mm
@@ -17,10 +17,18 @@ namespace chrome_test_util { -id<GREYAction> LongPressElementForContextMenu(const std::string& element_id, +id<GREYAction> LongPressElementForContextMenu(const std::string& elementId, bool triggers_context_menu) { + return LongPressElementForContextMenu( + web::test::ElementSelector::ElementSelectorId(elementId), + triggers_context_menu); +} + +id<GREYAction> LongPressElementForContextMenu( + web::test::ElementSelector selector, + bool triggers_context_menu) { return WebViewLongPressElementForContextMenu( - chrome_test_util::GetCurrentWebState(), element_id, + chrome_test_util::GetCurrentWebState(), std::move(selector), triggers_context_menu); }
diff --git a/ios/web/public/test/earl_grey/web_view_actions.h b/ios/web/public/test/earl_grey/web_view_actions.h index 1e6631c8..fbc2668 100644 --- a/ios/web/public/test/earl_grey/web_view_actions.h +++ b/ios/web/public/test/earl_grey/web_view_actions.h
@@ -9,19 +9,21 @@ #import <EarlGrey/EarlGrey.h> +#include "ios/web/public/test/element_selector.h" #import "ios/web/public/web_state/web_state.h" namespace web { // Action wrapper that performs |action| on the webview of |state|. -// The action will fail (in addition to its own failure modes) if |element_id| -// can't be located, or if it doesn't trigger a mousedown event on |element_id| -// inside the webview. -id<GREYAction> WebViewVerifiedActionOnElement(WebState* state, - id<GREYAction> action, - const std::string& element_id); +// The action will fail (in addition to its own failure modes) if the element +// retrieved by |selector| can't be located, or if it doesn't trigger a +// mousedown event on it inside the webview. +id<GREYAction> WebViewVerifiedActionOnElement( + WebState* state, + id<GREYAction> action, + web::test::ElementSelector selector); -// Executes a longpress on element |element_id| in the webview of +// Executes a longpress on the element selected by |selector| in the webview of // |state|. If |triggers_context_menu| is true, this gesture is expected to // cause the context menu to appear, and is not expected to trigger events // in the webview. If |triggers_context_menu| is false, the converse is true. @@ -29,12 +31,12 @@ // should check for that separately with a matcher. id<GREYAction> WebViewLongPressElementForContextMenu( WebState* state, - const std::string& element_id, + web::test::ElementSelector selector, bool triggers_context_menu); -// Taps on element |element_id| in the webview of |state|. +// Taps on element selected by |selector| in the webview of |state|. id<GREYAction> WebViewTapElement(WebState* state, - const std::string& element_id); + web::test::ElementSelector selector); } // namespace web
diff --git a/ios/web/public/test/earl_grey/web_view_actions.mm b/ios/web/public/test/earl_grey/web_view_actions.mm index 76c6df8..50b31a3 100644 --- a/ios/web/public/test/earl_grey/web_view_actions.mm +++ b/ios/web/public/test/earl_grey/web_view_actions.mm
@@ -32,31 +32,24 @@ // is reduced on devices. const NSTimeInterval kWaitForVerificationTimeout = 8.0; -// Callback prefix for injected verifiers. -const std::string CallbackPrefixForElementId(const std::string& element_id) { - return "__web_test_" + element_id + "_interaction"; -} - // Generic verification injector. Injects one-time mousedown verification into // |web_state| that will set the boolean pointed to by |verified| to true when // |web_state|'s webview registers the mousedown event. -// RemoveVerifierForElementWithId() should be called after this to ensure +// RemoveVerifierWithPrefix should be called after this to ensure // future tests can add verifiers with the same prefix. -bool AddVerifierToElementWithId(web::WebState* web_state, - const std::string& element_id, - bool* verified) { - const std::string kCallbackPrefix = CallbackPrefixForElementId(element_id); +bool AddVerifierToElementWithPrefix(web::WebState* web_state, + const web::test::ElementSelector& selector, + const std::string& prefix, + bool* verified) { const char kCallbackCommand[] = "verified"; - const std::string kCallbackInvocation = - kCallbackPrefix + '.' + kCallbackCommand; + const std::string kCallbackInvocation = prefix + '.' + kCallbackCommand; const char kAddInteractionVerifierScriptTemplate[] = "(function() {" - // First template param: element ID. - " var elementId = '%1$s';" - " var element = document.getElementById(elementId);" + // First template param: element. + " var element = %1$s;" " if (!element)" - " return 'Element ' + elementId + ' not found';" + " return 'Element not found';" " var invokeType = typeof __gCrWeb.message;" " if (invokeType != 'object')" " return 'Host invocation not installed (' + invokeType + ')';" @@ -69,9 +62,9 @@ " return true;" "})();"; - const std::string kAddVerifierScript = - base::StringPrintf(kAddInteractionVerifierScriptTemplate, - element_id.c_str(), kCallbackInvocation.c_str()); + const std::string kAddVerifierScript = base::StringPrintf( + kAddInteractionVerifierScriptTemplate, + selector.GetSelectorScript().c_str(), kCallbackInvocation.c_str()); bool success = testing::WaitUntilConditionOrTimeout(testing::kWaitForUIElementTimeout, ^{ @@ -102,24 +95,25 @@ return true; }); - static_cast<web::WebStateImpl*>(web_state)->AddScriptCommandCallback( - callback, kCallbackPrefix); + static_cast<web::WebStateImpl*>(web_state)->AddScriptCommandCallback(callback, + prefix); return true; } // Removes the injected callback. -void RemoveVerifierForElementWithId(web::WebState* web_state, - const std::string& element_id) { +void RemoveVerifierWithPrefix(web::WebState* web_state, + const std::string& prefix) { static_cast<web::WebStateImpl*>(web_state)->RemoveScriptCommandCallback( - CallbackPrefixForElementId(element_id)); + prefix); } // Returns a no element found error. -id<GREYAction> WebViewElementNotFound(const std::string& element_id) { - NSString* description = [NSString - stringWithFormat:@"Couldn't locate a bounding rect for element_id %s; " - @"either it isn't there or it has no area.", - element_id.c_str()]; +id<GREYAction> WebViewElementNotFound(web::test::ElementSelector selector) { + NSString* description = + [NSString stringWithFormat: + @"Couldn't locate a bounding rect for element %s; " + @"either it isn't there or it has no area.", + selector.GetSelectorDescription().c_str()]; GREYPerformBlock throw_error = ^BOOL(id /* element */, __strong NSError** error) { NSDictionary* user_info = @{NSLocalizedDescriptionKey : description}; @@ -136,33 +130,37 @@ namespace web { -id<GREYAction> WebViewVerifiedActionOnElement(WebState* state, - id<GREYAction> action, - const std::string& element_id) { - NSString* action_name = - [NSString stringWithFormat:@"Verified action (%@) on webview element %s.", - action.name, element_id.c_str()]; +id<GREYAction> WebViewVerifiedActionOnElement( + WebState* state, + id<GREYAction> action, + web::test::ElementSelector selector) { + NSString* action_name = [NSString + stringWithFormat:@"Verified action (%@) on webview element %s.", + action.name, selector.GetSelectorDescription().c_str()]; + const std::string prefix = + base::StringPrintf("__web_test_%p_interaction", &selector); GREYPerformBlock verified_tap = ^BOOL(id element, __strong NSError** error) { - // A pointer to |verified| is passed into AddVerifierToElementWithId() so - // the verifier can update its value, but |verified| also needs to be marked - // as __block so that waitUntilCondition(), below, can access it by + // A pointer to |verified| is passed into AddVerifierToElementWithPrefix() + // so the verifier can update its value, but |verified| also needs to be + // marked as __block so that waitUntilCondition(), below, can access it by // reference. __block bool verified = false; - // Ensure that RemoveVerifierForElementWithId() is run regardless of how + // Ensure that RemoveVerifierWithPrefix() is run regardless of how // the block exits. base::ScopedClosureRunner cleanup( - base::Bind(&RemoveVerifierForElementWithId, state, element_id)); + base::BindOnce(&RemoveVerifierWithPrefix, state, prefix)); // Inject the verifier. bool verifier_added = - AddVerifierToElementWithId(state, element_id, &verified); + AddVerifierToElementWithPrefix(state, selector, prefix, &verified); if (!verifier_added) { - NSString* description = [NSString - stringWithFormat:@"It wasn't possible to add the verification " - @"javascript for element_id %s", - element_id.c_str()]; + NSString* description = + [NSString stringWithFormat: + @"It wasn't possible to add the verification " + @"javascript for element %s", + selector.GetSelectorDescription().c_str()]; NSDictionary* user_info = @{NSLocalizedDescriptionKey : description}; *error = [NSError errorWithDomain:kGREYInteractionErrorDomain code:kGREYInteractionActionFailedErrorCode @@ -181,9 +179,10 @@ // Wait for the verified to trigger and set |verified|. NSString* verification_timeout_message = - [NSString stringWithFormat:@"The action (%@) on element_id %s wasn't " - @"verified before timing out.", - action.name, element_id.c_str()]; + [NSString stringWithFormat: + @"The action (%@) on element %s wasn't " + @"verified before timing out.", + action.name, selector.GetSelectorDescription().c_str()]; GREYAssert(testing::WaitUntilConditionOrTimeout( kWaitForVerificationTimeout, ^{ @@ -205,11 +204,11 @@ id<GREYAction> WebViewLongPressElementForContextMenu( WebState* state, - const std::string& element_id, + web::test::ElementSelector selector, bool triggers_context_menu) { - CGRect rect = web::test::GetBoundingRectOfElementWithId(state, element_id); + CGRect rect = web::test::GetBoundingRectOfElement(state, selector); if (CGRectIsEmpty(rect)) { - return WebViewElementNotFound(element_id); + return WebViewElementNotFound(std::move(selector)); } CGPoint point = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect)); id<GREYAction> longpress = @@ -217,16 +216,17 @@ if (triggers_context_menu) { return longpress; } - return WebViewVerifiedActionOnElement(state, longpress, element_id); + return WebViewVerifiedActionOnElement(state, longpress, std::move(selector)); } id<GREYAction> WebViewTapElement(WebState* state, - const std::string& element_id) { - CGRect rect = web::test::GetBoundingRectOfElementWithId(state, element_id); + web::test::ElementSelector selector) { + CGRect rect = web::test::GetBoundingRectOfElement(state, selector); CGPoint point = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect)); - return CGRectIsEmpty(rect) ? WebViewElementNotFound(element_id) - : WebViewVerifiedActionOnElement( - state, grey_tapAtPoint(point), element_id); + return CGRectIsEmpty(rect) + ? WebViewElementNotFound(std::move(selector)) + : WebViewVerifiedActionOnElement(state, grey_tapAtPoint(point), + std::move(selector)); } } // namespace web
diff --git a/ios/web/public/test/element_selector.h b/ios/web/public/test/element_selector.h index 43504fc5..4ebc477 100644 --- a/ios/web/public/test/element_selector.h +++ b/ios/web/public/test/element_selector.h
@@ -33,7 +33,7 @@ // Returns the javascript to invoke on a page to retrieve the element. const std::string GetSelectorScript() const; - // Return a human readable description of the query. + // Returns a human readable description of the query. const std::string GetSelectorDescription() const; private:
diff --git a/ios/web/public/test/element_selector.mm b/ios/web/public/test/element_selector.mm index 7967cc5..bb301ab0 100644 --- a/ios/web/public/test/element_selector.mm +++ b/ios/web/public/test/element_selector.mm
@@ -18,7 +18,7 @@ const std::string element_id) { return ElementSelector( base::StringPrintf("document.getElementById('%s')", element_id.c_str()), - base::StringPrintf("with ID '%s')", element_id.c_str())); + base::StringPrintf("with ID %s", element_id.c_str())); } // Static. @@ -27,7 +27,7 @@ const std::string script(base::StringPrintf("document.querySelector(\"%s\")", css_selector.c_str())); const std::string description( - base::StringPrintf("with CSS selector '%s')", css_selector.c_str())); + base::StringPrintf("with CSS selector '%s'", css_selector.c_str())); return ElementSelector(std::move(script), std::move(description)); } @@ -39,7 +39,7 @@ "null,XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue", xpath_selector.c_str())); const std::string description( - base::StringPrintf("with xpath '%s')", xpath_selector.c_str())); + base::StringPrintf("with xpath '%s'", xpath_selector.c_str())); return ElementSelector(std::move(script), std::move(description)); } @@ -50,6 +50,7 @@ const std::string ElementSelector::GetSelectorScript() const { return script_; } + const std::string ElementSelector::GetSelectorDescription() const { return description_; }
diff --git a/ios/web/public/test/web_view_interaction_test_util.h b/ios/web/public/test/web_view_interaction_test_util.h index 652afd4..899d0c1 100644 --- a/ios/web/public/test/web_view_interaction_test_util.h +++ b/ios/web/public/test/web_view_interaction_test_util.h
@@ -12,6 +12,7 @@ #import "base/ios/block_types.h" #include "base/values.h" +#include "ios/web/public/test/element_selector.h" #import "ios/web/public/web_state/web_state.h" namespace web { @@ -23,12 +24,12 @@ const std::string& script); // Returns the CGRect, in the coordinate system of web_state's view, that -// encloses the element with |element_id| in |web_state|'s webview. +// encloses the element returned by |selector| in |web_state|'s webview. // There is no guarantee that the CGRect returned is inside the current window; // callers should check and act accordingly (scrolling the webview, perhaps). // Returns CGRectNull if no element could be found. -CGRect GetBoundingRectOfElementWithId(web::WebState* web_state, - const std::string& element_id); +CGRect GetBoundingRectOfElement(web::WebState* web_state, + const web::test::ElementSelector& selector); // Returns whether the element with |element_id| in the passed |web_state| has // been tapped using a JavaScript click() event.
diff --git a/ios/web/public/test/web_view_interaction_test_util.mm b/ios/web/public/test/web_view_interaction_test_util.mm index dcb5673..6666b4f 100644 --- a/ios/web/public/test/web_view_interaction_test_util.mm +++ b/ios/web/public/test/web_view_interaction_test_util.mm
@@ -5,6 +5,7 @@ #import "ios/web/public/test/web_view_interaction_test_util.h" #include "base/bind.h" +#include "base/json/string_escape.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #import "base/test/ios/wait_util.h" @@ -66,17 +67,28 @@ return stack_result; } -CGRect GetBoundingRectOfElementWithId(web::WebState* web_state, - const std::string& element_id) { +CGRect GetBoundingRectOfElement(web::WebState* web_state, + const web::test::ElementSelector& selector) { + std::string quoted_description; + bool success = + base::EscapeJSONString(selector.GetSelectorDescription(), + true /* put_in_quotes */, "ed_description); + if (!success) { + DLOG(ERROR) << "Error quoting description: " + << selector.GetSelectorDescription(); + } + std::string kGetBoundsScript = "(function() {" - " var element = document.getElementById('" + - element_id + - "');" - " if (!element)" - " return {'error': 'Element " + - element_id + - " not found'};" + " var element = " + + selector.GetSelectorScript() + + ";" + " if (!element) {" + " var description = " + + quoted_description + + ";" + " return {'error': 'Element ' + description + ' not found'};" + " }" " var rect = element.getBoundingClientRect();" " return {" " 'left': rect.left,"
diff --git a/ios/web/shell/test/context_menu_egtest.mm b/ios/web/shell/test/context_menu_egtest.mm index 925912f..96d1c43 100644 --- a/ios/web/shell/test/context_menu_egtest.mm +++ b/ios/web/shell/test/context_menu_egtest.mm
@@ -9,6 +9,7 @@ #import "base/ios/block_types.h" #import "ios/testing/earl_grey/matchers.h" +#include "ios/web/public/test/element_selector.h" #import "ios/web/public/test/http_server/http_server.h" #include "ios/web/public/test/http_server/http_server_util.h" #import "ios/web/public/test/web_view_interaction_test_util.h" @@ -25,6 +26,7 @@ using testing::ButtonWithAccessibilityLabel; using testing::ElementToDismissAlert; +using web::test::ElementSelector; // Context menu test cases for the web shell. @interface ContextMenuTestCase : WebShellTestCase @@ -53,7 +55,8 @@ [ShellEarlGrey waitForWebViewContainingText:linkText]; [[EarlGrey selectElementWithMatcher:web::WebView()] - performAction:web::LongPressElementForContextMenu(linkID)]; + performAction:web::LongPressElementForContextMenu( + ElementSelector::ElementSelectorId(linkID))]; id<GREYMatcher> copyItem = ButtonWithAccessibilityLabel(@"Copy Link"); @@ -94,7 +97,8 @@ [ShellEarlGrey waitForWebViewContainingText:linkText]; [[EarlGrey selectElementWithMatcher:web::WebView()] - performAction:web::LongPressElementForContextMenu(linkID)]; + performAction:web::LongPressElementForContextMenu( + ElementSelector::ElementSelectorId(linkID))]; id<GREYMatcher> copyItem = ButtonWithAccessibilityLabel(@"Copy Link");
diff --git a/ios/web/shell/test/earl_grey/shell_actions.h b/ios/web/shell/test/earl_grey/shell_actions.h index 779c44e5..6cb6fd398 100644 --- a/ios/web/shell/test/earl_grey/shell_actions.h +++ b/ios/web/shell/test/earl_grey/shell_actions.h
@@ -9,14 +9,17 @@ #import <EarlGrey/EarlGrey.h> +#include "ios/web/public/test/element_selector.h" + namespace web { -// Action to longpress on element |element_id| in the shell's webview. This -// gesture is expected to cause the context menu to appear, and is not expected -// to trigger events in the webview. This action doesn't fail if the context -// menu isn't displayed; calling code should check for that separately with a -// matcher. -id<GREYAction> LongPressElementForContextMenu(const std::string& element_id); +// Action to longpress on the element found by |selector| in the shell's +// webview. This gesture is expected to cause the context menu to appear, and +// is not expected to trigger events in the webview. This action doesn't fail if +// the context menu isn't displayed; calling code should check for that +// separately with a matcher. +id<GREYAction> LongPressElementForContextMenu( + web::test::ElementSelector selector); } // namespace web
diff --git a/ios/web/shell/test/earl_grey/shell_actions.mm b/ios/web/shell/test/earl_grey/shell_actions.mm index 692da0b9..15fa770 100644 --- a/ios/web/shell/test/earl_grey/shell_actions.mm +++ b/ios/web/shell/test/earl_grey/shell_actions.mm
@@ -5,6 +5,7 @@ #import "ios/web/shell/test/earl_grey/shell_actions.h" #import "ios/web/public/test/earl_grey/web_view_actions.h" +#include "ios/web/public/test/element_selector.h" #import "ios/web/shell/test/app/web_shell_test_util.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -13,9 +14,10 @@ namespace web { -id<GREYAction> LongPressElementForContextMenu(const std::string& element_id) { +id<GREYAction> LongPressElementForContextMenu( + web::test::ElementSelector selector) { return WebViewLongPressElementForContextMenu( - shell_test_util::GetCurrentWebState(), element_id, true); + shell_test_util::GetCurrentWebState(), std::move(selector), true); } } // namespace web
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc index 11736c8..f3fbc82a 100644 --- a/media/base/media_switches.cc +++ b/media/base/media_switches.cc
@@ -219,8 +219,14 @@ base::FEATURE_ENABLED_BY_DEFAULT}; // Enable Picture-in-Picture. -const base::Feature kPictureInPicture{"PictureInPicture", - base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kPictureInPicture { + "PictureInPicture", +#if defined(OS_ANDROID) + base::FEATURE_DISABLED_BY_DEFAULT +#else + base::FEATURE_ENABLED_BY_DEFAULT +#endif +}; const base::Feature kPreloadMetadataSuspend{"PreloadMetadataSuspend", base::FEATURE_ENABLED_BY_DEFAULT}; @@ -317,7 +323,7 @@ // Use SurfaceLayer instead of VideoLayer. const base::Feature kUseSurfaceLayerForVideo{"UseSurfaceLayerForVideo", - base::FEATURE_DISABLED_BY_DEFAULT}; + base::FEATURE_ENABLED_BY_DEFAULT}; // Enable VA-API hardware encode acceleration for VP8. const base::Feature kVaapiVP8Encoder{"VaapiVP8Encoder",
diff --git a/media/blink/webmediaplayer_impl_unittest.cc b/media/blink/webmediaplayer_impl_unittest.cc index e3e9856..97cc6d07 100644 --- a/media/blink/webmediaplayer_impl_unittest.cc +++ b/media/blink/webmediaplayer_impl_unittest.cc
@@ -762,6 +762,16 @@ EXPECT_CALL(client_, CouldPlayIfEnoughData()).WillRepeatedly(Return(false)); wmpi_->SetPreload(blink::WebMediaPlayer::kPreloadMetaData); wmpi_->SetPoster(blink::WebURL(GURL("file://example.com/sample.jpg"))); + + if (base::FeatureList::IsEnabled(kUseSurfaceLayerForVideo)) { + EXPECT_CALL(*surface_layer_bridge_ptr_, CreateSurfaceLayer()); + EXPECT_CALL(client_, SetCcLayer(_)).Times(0); + EXPECT_CALL(*surface_layer_bridge_ptr_, GetFrameSinkId()) + .WillOnce(ReturnRef(frame_sink_id_)); + EXPECT_CALL(*compositor_, EnableSubmission(_, _, _)); + EXPECT_CALL(*surface_layer_bridge_ptr_, SetContentsOpaque(false)); + } + LoadAndWaitForMetadata("bear-320x240-video-only.webm"); testing::Mock::VerifyAndClearExpectations(&client_); EXPECT_CALL(client_, ReadyStateChanged()).Times(AnyNumber()); @@ -1175,6 +1185,7 @@ EXPECT_CALL(*surface_layer_bridge_ptr_, GetFrameSinkId()) .WillOnce(ReturnRef(frame_sink_id_)); EXPECT_CALL(*compositor_, EnableSubmission(_, _, _)); + EXPECT_CALL(*surface_layer_bridge_ptr_, SetContentsOpaque(false)); } else { EXPECT_CALL(client_, SetCcLayer(NotNull())); } @@ -1201,6 +1212,7 @@ EXPECT_CALL(*surface_layer_bridge_ptr_, GetFrameSinkId()) .WillOnce(ReturnRef(frame_sink_id_)); EXPECT_CALL(*compositor_, EnableSubmission(_, _, _)); + EXPECT_CALL(*surface_layer_bridge_ptr_, SetContentsOpaque(false)); } else { EXPECT_CALL(client_, SetCcLayer(NotNull())); } @@ -1228,6 +1240,7 @@ EXPECT_CALL(*surface_layer_bridge_ptr_, GetFrameSinkId()) .WillOnce(ReturnRef(frame_sink_id_)); EXPECT_CALL(*compositor_, EnableSubmission(_, _, _)); + EXPECT_CALL(*surface_layer_bridge_ptr_, SetContentsOpaque(false)); } else { EXPECT_CALL(client_, SetCcLayer(NotNull())); } @@ -1303,6 +1316,7 @@ EXPECT_CALL(*surface_layer_bridge_ptr_, GetFrameSinkId()) .WillOnce(ReturnRef(frame_sink_id_)); EXPECT_CALL(*compositor_, EnableSubmission(_, _, _)); + EXPECT_CALL(*surface_layer_bridge_ptr_, SetContentsOpaque(false)); } else { EXPECT_CALL(client_, SetCcLayer(NotNull())); }
diff --git a/net/cert/cert_verify_proc_unittest.cc b/net/cert/cert_verify_proc_unittest.cc index 2a3a435d..982aead 100644 --- a/net/cert/cert_verify_proc_unittest.cc +++ b/net/cert/cert_verify_proc_unittest.cc
@@ -2760,8 +2760,8 @@ // NOTE: This test is separate from IntermediateFromAia200 as a different URL // needs to be used to avoid having the result depend on globally cached success // or failure of the fetch. -// Test flaky on Win crbug.com/859387 -#if defined(OS_WIN) +// Test flaky on Win and iOS crbug.com/859387 +#if defined(OS_WIN) || defined(OS_IOS) #define MAYBE_IntermediateFromAia404 DISABLED_IntermediateFromAia404 #else #define MAYBE_IntermediateFromAia404 IntermediateFromAia404
diff --git a/services/service_manager/sandbox/linux/sandbox_linux.h b/services/service_manager/sandbox/linux/sandbox_linux.h index dcf4eeee..e4d7a7a 100644 --- a/services/service_manager/sandbox/linux/sandbox_linux.h +++ b/services/service_manager/sandbox/linux/sandbox_linux.h
@@ -56,11 +56,11 @@ // This isn't the full list, values < 32 are reserved for methods called from // Skia, and values < 64 are reserved for libc_interceptor.cc. enum LinuxSandboxIPCMethods { - DEPRECATED_METHOD_GET_FALLBACK_FONT_FOR_CHAR = 64, + METHOD_GET_FALLBACK_FONT_FOR_CHAR = 64, DEPRECATED_METHOD_GET_CHILD_WITH_INODE, - DEPRECATED_METHOD_GET_STYLE_FOR_STRIKE, + METHOD_GET_STYLE_FOR_STRIKE, METHOD_MAKE_SHARED_MEMORY_SEGMENT, - DEPRECATED_METHOD_MATCH_WITH_FALLBACK, + METHOD_MATCH_WITH_FALLBACK, }; // These form a bitmask which describes the conditions of the Linux sandbox.
diff --git a/testing/buildbot/chromium.perf.json b/testing/buildbot/chromium.perf.json index 1fe1d79..51fee68a6 100644 --- a/testing/buildbot/chromium.perf.json +++ b/testing/buildbot/chromium.perf.json
@@ -719,7 +719,7 @@ "merge": { "args": [ "--service-account-file", - "/creds/service_accounts/service-account-chromium-perf-histograms.json" + "C:\\creds\\service_accounts\\service-account-chromium-perf-histograms.json" ], "script": "//tools/perf/process_perf_results.py" }, @@ -764,7 +764,7 @@ "merge": { "args": [ "--service-account-file", - "/creds/service_accounts/service-account-chromium-perf-histograms.json" + "C:\\creds\\service_accounts\\service-account-chromium-perf-histograms.json" ], "script": "//tools/perf/process_perf_results.py" }, @@ -805,7 +805,7 @@ "merge": { "args": [ "--service-account-file", - "/creds/service_accounts/service-account-chromium-perf-histograms.json" + "C:\\creds\\service_accounts\\service-account-chromium-perf-histograms.json" ], "script": "//tools/perf/process_perf_results.py" }, @@ -849,7 +849,7 @@ "merge": { "args": [ "--service-account-file", - "/creds/service_accounts/service-account-chromium-perf-histograms.json" + "C:\\creds\\service_accounts\\service-account-chromium-perf-histograms.json" ], "script": "//tools/perf/process_perf_results.py" }, @@ -890,7 +890,7 @@ "merge": { "args": [ "--service-account-file", - "/creds/service_accounts/service-account-chromium-perf-histograms.json" + "C:\\creds\\service_accounts\\service-account-chromium-perf-histograms.json" ], "script": "//tools/perf/process_perf_results.py" }, @@ -935,7 +935,7 @@ "merge": { "args": [ "--service-account-file", - "/creds/service_accounts/service-account-chromium-perf-histograms.json" + "C:\\creds\\service_accounts\\service-account-chromium-perf-histograms.json" ], "script": "//tools/perf/process_perf_results.py" }, @@ -976,7 +976,7 @@ "merge": { "args": [ "--service-account-file", - "/creds/service_accounts/service-account-chromium-perf-histograms.json" + "C:\\creds\\service_accounts\\service-account-chromium-perf-histograms.json" ], "script": "//tools/perf/process_perf_results.py" }, @@ -1017,7 +1017,7 @@ "merge": { "args": [ "--service-account-file", - "/creds/service_accounts/service-account-chromium-perf-histograms.json" + "C:\\creds\\service_accounts\\service-account-chromium-perf-histograms.json" ], "script": "//tools/perf/process_perf_results.py" }, @@ -1060,7 +1060,7 @@ "merge": { "args": [ "--service-account-file", - "/creds/service_accounts/service-account-chromium-perf-histograms.json" + "C:\\creds\\service_accounts\\service-account-chromium-perf-histograms.json" ], "script": "//tools/perf/process_perf_results.py" }, @@ -1094,6 +1094,50 @@ }, { "args": [ + "-v", + "--browser=release_x64", + "--upload-results", + "--run-ref-build", + "--test-shard-map-filename=win7_nvidia_shard_map.json" + ], + "isolate_name": "performance_test_suite", + "merge": { + "args": [ + "--service-account-file", + "C:\\creds\\service_accounts\\service-account-chromium-perf-histograms.json" + ], + "script": "//tools/perf/process_perf_results.py" + }, + "name": "performance_test_suite", + "override_compile_targets": [ + "performance_test_suite" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "gpu": "10de:1cb3", + "os": "Windows-2008ServerR2-SP1", + "pool": "chrome.tests.perf" + } + ], + "expiration": 36000, + "hard_timeout": 36000, + "ignore_task_failure": false, + "io_timeout": 1800, + "shards": 5, + "upload_test_results": true + }, + "trigger_script": { + "args": [ + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/perf_device_trigger.py" + } + }, + { + "args": [ "--non-telemetry=true", "--migrated-test=true", "--use-cmd-decoder=validating", @@ -1103,7 +1147,7 @@ "merge": { "args": [ "--service-account-file", - "/creds/service_accounts/service-account-chromium-perf-histograms.json" + "C:\\creds\\service_accounts\\service-account-chromium-perf-histograms.json" ], "script": "//tools/perf/process_perf_results.py" }, @@ -1148,7 +1192,7 @@ "merge": { "args": [ "--service-account-file", - "/creds/service_accounts/service-account-chromium-perf-histograms.json" + "C:\\creds\\service_accounts\\service-account-chromium-perf-histograms.json" ], "script": "//tools/perf/process_perf_results.py" }, @@ -1189,7 +1233,7 @@ "merge": { "args": [ "--service-account-file", - "/creds/service_accounts/service-account-chromium-perf-histograms.json" + "C:\\creds\\service_accounts\\service-account-chromium-perf-histograms.json" ], "script": "//tools/perf/process_perf_results.py" }, @@ -1230,7 +1274,7 @@ "merge": { "args": [ "--service-account-file", - "/creds/service_accounts/service-account-chromium-perf-histograms.json" + "C:\\creds\\service_accounts\\service-account-chromium-perf-histograms.json" ], "script": "//tools/perf/process_perf_results.py" }, @@ -1274,7 +1318,7 @@ "merge": { "args": [ "--service-account-file", - "/creds/service_accounts/service-account-chromium-perf-histograms.json" + "C:\\creds\\service_accounts\\service-account-chromium-perf-histograms.json" ], "script": "//tools/perf/process_perf_results.py" },
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG index 3f978fc..590f6571 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -65,7 +65,6 @@ crbug.com/591099 fast/dom/inner-text-first-letter.html [ Pass ] # New failures are appended below by the script. -crbug.com/591099 animations/cross-fade-list-style-image.html [ Failure ] crbug.com/591099 animations/rotate-transform-equivalent.html [ Failure ] crbug.com/728378 compositing/culling/tile-occlusion-boundaries.html [ Failure ] crbug.com/591099 compositing/geometry/bounds-ignores-hidden.html [ Failure ] @@ -345,6 +344,7 @@ crbug.com/591099 fast/block/positioning/rtl-static-positioning.html [ Failure ] crbug.com/591099 fast/block/positioning/table-cell-static-position.html [ Failure ] crbug.com/591099 fast/borders/bidi-002.html [ Failure ] +crbug.com/859497 fast/borders/bidi-009a.html [ Failure ] crbug.com/591099 fast/borders/bidi-012.html [ Failure ] crbug.com/591099 fast/borders/border-image-border-radius.html [ Failure ] crbug.com/714962 fast/borders/border-image-outset-split-inline.html [ Failure ] @@ -356,7 +356,6 @@ crbug.com/591099 fast/box-shadow/inset-subpixel.html [ Failure ] crbug.com/591099 fast/box-shadow/inset.html [ Failure ] crbug.com/591099 fast/box-sizing/replaced.html [ Failure ] -crbug.com/591099 fast/css-generated-content/015.html [ Failure ] crbug.com/591099 fast/css-generated-content/first-letter-next-sibling-crash.html [ Crash ] crbug.com/591099 fast/css-generated-content/float-first-letter-siblings-convert-to-inline.html [ Crash ] crbug.com/591099 fast/css-grid-layout/flex-and-minmax-content-resolution-columns.html [ Failure ] @@ -433,8 +432,6 @@ crbug.com/591099 fast/forms/select/select-style.html [ Failure ] crbug.com/591099 fast/forms/text-control-intrinsic-widths.html [ Timeout ] crbug.com/591099 fast/frames/iframe-with-frameborder.html [ Failure ] -crbug.com/591099 fast/gradients/list-item-gradient.html [ Failure ] -crbug.com/591099 fast/gradients/unprefixed-list-item-gradient.html [ Failure ] crbug.com/591099 fast/inline-block/baseline-vertical.html [ Failure ] crbug.com/591099 fast/inline-block/vertical-align-top-and-bottom-2.html [ Failure ] crbug.com/714962 fast/inline/continuation-outlines-with-layers-2.html [ Failure ] @@ -485,6 +482,7 @@ crbug.com/591099 fast/table/percent-height-overflow-auto-content-in-cell.html [ Failure Pass ] crbug.com/591099 fast/table/percent-height-overflow-scroll-content-in-cell.html [ Failure ] crbug.com/591099 fast/table/percent-height-replaced-content-in-cell.html [ Failure ] +crbug.com/858998 fast/table/table-continuation-outline-paint-crash.html [ Failure ] crbug.com/591099 fast/table/table-display-types-vertical.html [ Failure ] crbug.com/591099 fast/table/unbreakable-images-quirk.html [ Failure ] crbug.com/591099 fast/table/vertical-align-baseline-readjust.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-gen-property-trees b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-gen-property-trees index 214fa76..fe161b2f 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-gen-property-trees +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-gen-property-trees
@@ -103,7 +103,6 @@ Bug(none) virtual/origin-trials-runtimeflags-disabled/ [ Skip ] Bug(none) virtual/outofblink-cors/ [ Skip ] Bug(none) virtual/paint-timing/ [ Skip ] -Bug(none) virtual/picture-in-picture/ [ Skip ] Bug(none) virtual/prefer_compositing_to_lcd_text/ [ Skip ] Bug(none) virtual/presentation/ [ Skip ] Bug(none) virtual/print_browser/ [ Skip ]
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 index 24d62a0..4a7e7fb 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
@@ -82,7 +82,6 @@ Bug(none) virtual/mse-1mb-buffers/ [ Skip ] Bug(none) virtual/new-remote-playback-pipeline/ [ Skip ] Bug(none) virtual/outofblink-cors/ [ Skip ] -Bug(none) virtual/picture-in-picture/ [ Skip ] Bug(none) virtual/prefer_compositing_to_lcd_text/ [ Skip ] Bug(none) virtual/reporting-api/ [ Skip ] Bug(none) virtual/scalefactor150/ [ Skip ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 11aadf05..33a8d69 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -95,10 +95,6 @@ # seem to fix it. crbug.com/309675 compositing/gestures/gesture-tapHighlight-simple-longPress.html [ Failure ] -crbug.com/857501 [ Mac10.10 ] compositing/gestures/gesture-tapHighlight-pixel-rotated-div.html [ Failure Pass ] -crbug.com/857501 [ Mac10.10 ] compositing/gestures/gesture-tapHighlight-pixel-rotated-link.html [ Failure Pass ] -crbug.com/857501 [ Mac10.10 ] compositing/gestures/gesture-tapHighlight-pixel-transparent.html [ Failure Pass ] - crbug.com/845267 [ Mac ] http/tests/inspector-protocol/page/page-lifecycleEvents.js [ Failure Pass ] # SwiftShader Failures @@ -1711,16 +1707,11 @@ crbug.com/691944 virtual/outofblink-cors/external/wpt/service-workers/service-worker/update-after-oneday.https.html [ Skip ] # Crashing tests in dictionary order. -crbug.com/736308 virtual/outofblink-cors/external/wpt/service-workers/service-worker/fetch-cors-xhr.https.html [ Failure Crash ] -crbug.com/736308 virtual/outofblink-cors/external/wpt/service-workers/service-worker/fetch-event.https.html [ Failure Crash ] -crbug.com/736308 virtual/outofblink-cors/external/wpt/service-workers/service-worker/fetch-event-network-error.https.html [ Crash ] -crbug.com/736308 virtual/outofblink-cors/external/wpt/service-workers/service-worker/fetch-request-fallback.https.html [ Crash Failure ] -crbug.com/736308 virtual/outofblink-cors/external/wpt/service-workers/service-worker/performance-timeline.https.html [ Crash ] -crbug.com/736308 virtual/outofblink-cors/external/wpt/service-workers/service-worker/redirected-response.https.html [ Crash ] -crbug.com/736308 virtual/outofblink-cors/external/wpt/service-workers/service-worker/referer.https.html [ Crash ] -crbug.com/736308 virtual/outofblink-cors/external/wpt/service-workers/service-worker/referrer-policy-header.https.html [ Crash ] crbug.com/736308 virtual/outofblink-cors/http/tests/xmlhttprequest/redirect-cross-origin-post.html [ Timeout Crash ] +# This test crashes on some builders, passes on others, and fails on yet other builders. +crbug.com/736308 virtual/outofblink-cors/external/wpt/service-workers/service-worker/service-worker-csp-connect.https.html [ Crash Failure Pass ] + # Timeout tests in dictionary order. crbug.com/705490 virtual/outofblink-cors/external/wpt/fetch/api/basic/error-after-response.html [ Timeout Pass ] crbug.com/736308 virtual/outofblink-cors/external/wpt/fetch/api/cors/cors-preflight-status.any.html [ Pass Timeout ] @@ -1728,9 +1719,7 @@ crbug.com/813694 virtual/outofblink-cors/external/wpt/fetch/api/redirect/redirect-location-worker.html [ Pass Timeout ] crbug.com/736308 virtual/outofblink-cors/external/wpt/fetch/api/redirect/redirect-origin.html [ Pass Timeout ] crbug.com/736308 virtual/outofblink-cors/external/wpt/fetch/api/redirect/redirect-referrer.html [ Pass Timeout ] -crbug.com/626703 virtual/outofblink-cors/external/wpt/fetch/api/request/request-cache-default-conditional.html [ Pass Timeout ] crbug.com/626703 virtual/outofblink-cors/external/wpt/fetch/api/response/response-cancel-stream.html [ Pass Timeout ] -crbug.com/626703 virtual/outofblink-cors/external/wpt/fetch/http-cache/status.html [ Pass Timeout ] crbug.com/626703 virtual/outofblink-cors/external/wpt/http/basic-auth-cache-test.html [ Timeout ] crbug.com/688486 virtual/outofblink-cors/external/wpt/service-workers/service-worker/fetch-request-resources.https.html [ Timeout Failure Pass ] crbug.com/736308 virtual/outofblink-cors/external/wpt/service-workers/service-worker/foreign-fetch-basics.https.html [ Timeout ] @@ -1742,20 +1731,12 @@ crbug.com/736308 virtual/outofblink-cors/http/tests/xmlhttprequest/workers/cross-origin-unsupported-url.html [ Timeout ] # Failing tests in dictionary order. -crbug.com/802835 virtual/outofblink-cors/external/wpt/fetch/corb/img-mime-types-coverage.tentative.sub.html [ Failure ] -crbug.com/736308 virtual/outofblink-cors/external/wpt/service-workers/service-worker/controller-with-no-fetch-event-handler.https.html [ Failure ] -crbug.com/736308 virtual/outofblink-cors/external/wpt/service-workers/service-worker/fetch-canvas-tainting-image-cache.https.html [ Failure ] -crbug.com/736308 virtual/outofblink-cors/external/wpt/service-workers/service-worker/fetch-canvas-tainting-image.https.html [ Failure ] crbug.com/736308 virtual/outofblink-cors/external/wpt/service-workers/service-worker/fetch-canvas-tainting-video-cache.https.html [ Failure ] crbug.com/736308 virtual/outofblink-cors/external/wpt/service-workers/service-worker/fetch-canvas-tainting-video.https.html [ Failure ] -crbug.com/736308 virtual/outofblink-cors/external/wpt/service-workers/service-worker/fetch-event-referrer-policy.https.html [ Failure ] crbug.com/595993 virtual/outofblink-cors/external/wpt/service-workers/service-worker/fetch-header-visibility.https.html [ Failure ] -crbug.com/736308 virtual/outofblink-cors/external/wpt/service-workers/service-worker/fetch-request-html-imports.https.html [ Failure ] -crbug.com/736308 virtual/outofblink-cors/external/wpt/service-workers/service-worker/fetch-request-xhr.https.html [ Failure ] -crbug.com/736308 virtual/outofblink-cors/external/wpt/service-workers/service-worker/fetch-response-taint.https.html [ Failure ] crbug.com/736308 virtual/outofblink-cors/external/wpt/service-workers/service-worker/foreign-fetch-cors.https.html [ Failure ] crbug.com/736308 virtual/outofblink-cors/external/wpt/service-workers/service-worker/foreign-fetch-workers.https.html [ Failure ] -crbug.com/830472 virtual/outofblink-cors/external/wpt/service-workers/service-worker/navigation-preload/broken-chunked-encoding.https.html [ Failure ] +crbug.com/736308 virtual/outofblink-cors/external/wpt/service-workers/service-worker/navigation-timing.https.html [ Failure ] crbug.com/595993 virtual/outofblink-cors/external/wpt/service-workers/service-worker/request-end-to-end.https.html [ Failure ] crbug.com/831509 virtual/outofblink-cors/external/wpt/service-workers/service-worker/skip-waiting-installed.https.html [ Failure Pass ] crbug.com/832071 virtual/outofblink-cors/external/wpt/service-workers/service-worker/worker-client-id.https.html [ Failure ] @@ -1845,6 +1826,7 @@ # ====== Out of Blink CORS related tests END ====== crbug.com/771118 virtual/service-worker-servicification/external/wpt/service-workers/service-worker/mime-sniffing.https.html [ Failure ] +crbug.com/771118 virtual/outofblink-cors/external/wpt/service-workers/service-worker/mime-sniffing.https.html [ Failure ] crbug.com/492664 [ Linux ] external/wpt/css/css-writing-modes/box-offsets-rel-pos-vlr-005.xht [ Failure ] crbug.com/492664 [ Linux ] external/wpt/css/css-writing-modes/box-offsets-rel-pos-vrl-004.xht [ Failure ] @@ -2341,11 +2323,11 @@ # These tests are skipped as there is no touch support on Mac. crbug.com/613672 [ Mac ] external/wpt/feature-policy/experimental-features/vertical-scroll-touch-block-manual.tentative.html [ Skip ] -crbug.com/613672 [ Mac ] virtual/picture-in-picture/external/wpt/feature-policy/experimental-features/vertical-scroll-touch-block-manual.tentative.html [ Skip ] +crbug.com/613672 [ Mac ] virtual/video-surface-layer/external/wpt/feature-policy/experimental-features/vertical-scroll-touch-block-manual.tentative.html [ Skip ] crbug.com/613672 [ Mac ] virtual/unified-autoplay/external/wpt/feature-policy/experimental-features/vertical-scroll-touch-block-manual.tentative.html [ Skip ] crbug.com/613672 [ Mac ] external/wpt/feature-policy/experimental-features/vertical-scroll-touch-action-manual.tentative.html [ Skip ] crbug.com/613672 [ Mac ] virtual/threaded/external/wpt/feature-policy/experimental-features/vertical-scroll-touch-action-manual.tentative.html [ Skip ] -crbug.com/613672 [ Mac ] virtual/picture-in-picture/external/wpt/feature-policy/experimental-features/vertical-scroll-touch-action-manual.tentative.html [ Skip ] +crbug.com/613672 [ Mac ] virtual/video-surface-layer/external/wpt/feature-policy/experimental-features/vertical-scroll-touch-action-manual.tentative.html [ Skip ] crbug.com/613672 [ Mac ] virtual/unified-autoplay/external/wpt/feature-policy/experimental-features/vertical-scroll-touch-action-manual.tentative.html [ Skip ] crbug.com/613672 [ Mac ] fast/events/touch/multi-touch-user-gesture.html [ Skip ] crbug.com/613672 [ Mac ] virtual/mouseevent_fractional/fast/events/touch/multi-touch-user-gesture.html [ Skip ] @@ -2846,7 +2828,7 @@ crbug.com/626703 virtual/outofblink-cors/external/wpt/service-workers/service-worker/fetch-event-is-history-forward-navigation-manual.https.html [ Skip ] crbug.com/626703 external/wpt/service-workers/service-worker/fetch-event-is-history-forward-navigation-manual.https.html [ Skip ] crbug.com/626703 external/wpt/service-workers/service-worker/fetch-event-is-history-backward-navigation-manual.https.html [ Skip ] -crbug.com/626703 [ Mac10.12 ] virtual/picture-in-picture/external/wpt/feature-policy/feature-policy-frame-policy-allowed-for-all.https.sub.html [ Timeout ] +crbug.com/626703 [ Mac10.12 ] virtual/video-surface-layer/external/wpt/feature-policy/feature-policy-frame-policy-allowed-for-all.https.sub.html [ Timeout ] crbug.com/626703 external/wpt/fetch/security/redirect-to-url-with-credentials.https.html [ Timeout ] crbug.com/626703 virtual/outofblink-cors/external/wpt/fetch/security/redirect-to-url-with-credentials.https.html [ Timeout ] crbug.com/626703 [ Mac10.12 ] external/wpt/domxpath/xml_xpath_runner.html [ Timeout ] @@ -2968,8 +2950,8 @@ crbug.com/626703 virtual/unified-autoplay/external/wpt/feature-policy/feature-policy-frame-policy-disallowed-for-all.https.sub.html [ Pass Timeout ] crbug.com/626703 virtual/unified-autoplay/external/wpt/feature-policy/feature-policy-frame-policy-allowed-for-some.https.sub.html [ Pass Timeout ] crbug.com/626703 virtual/unified-autoplay/external/wpt/feature-policy/feature-policy-frame-policy-allowed-for-self.https.sub.html [ Pass Timeout ] -crbug.com/626703 virtual/picture-in-picture/external/wpt/feature-policy/feature-policy-frame-policy-allowed-for-some.https.sub.html [ Pass Timeout ] -crbug.com/846472 virtual/picture-in-picture/external/wpt/feature-policy/feature-policy-frame-policy-allowed-for-self.https.sub.html [ Pass Timeout ] +crbug.com/626703 virtual/video-surface-layer/external/wpt/feature-policy/feature-policy-frame-policy-allowed-for-some.https.sub.html [ Pass Timeout ] +crbug.com/846472 virtual/video-surface-layer/external/wpt/feature-policy/feature-policy-frame-policy-allowed-for-self.https.sub.html [ Pass Timeout ] crbug.com/829921 external/wpt/feature-policy/feature-policy-frame-policy-allowed-for-some.https.sub.html [ Pass Timeout ] crbug.com/626703 external/wpt/feature-policy/feature-policy-frame-policy-allowed-for-self.https.sub.html [ Pass Timeout ] @@ -3876,6 +3858,7 @@ # Importing 'fetch' tests from WPT. crbug.com/705490 external/wpt/fetch/api/basic/error-after-response.html [ Timeout Pass ] crbug.com/820334 external/wpt/fetch/api/request/request-cache-default-conditional.html [ Timeout Pass ] +crbug.com/820334 virtual/outofblink-cors/external/wpt/fetch/api/request/request-cache-default-conditional.html [ Timeout Pass ] crbug.com/765116 external/wpt/xhr/responsexml-document-properties.htm [ Failure ] @@ -4274,6 +4257,8 @@ # full browser. crbug.com/856700 external/wpt/client-hints/accept_ch_lifetime_same_origin_iframe.tentative.https.html [ Skip ] crbug.com/856700 external/wpt/client-hints/accept_ch_lifetime.tentative.https.html [ Skip ] +crbug.com/856700 external/wpt/client-hints/http_equiv_accept_ch_lifetime_same_origin_iframe.tentative.https.html [ Skip ] +crbug.com/856700 external/wpt/client-hints/http_equiv_accept_ch_lifetime.tentative.https.html [ Skip ] # Sheriff failures 2017-11-15 crbug.com/785179 [ Win7 Debug ] http/tests/devtools/console/console-viewport-stick-to-bottom.js [ Skip ] @@ -4471,9 +4456,6 @@ crbug.com/806249 media/picture-in-picture/controls/picture-in-picture-video-with-audio-only-button.html [ Failure ] crbug.com/806249 media/picture-in-picture/picture-in-picture-enabled.html [ Failure ] crbug.com/811977 media/picture-in-picture/picture-in-picture-interstitial.html [ Failure ] -crbug.com/806249 virtual/picture-in-picture/external/wpt/feature-policy/autoplay-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html [ Skip ] -crbug.com/806249 virtual/picture-in-picture/external/wpt/feature-policy/autoplay-default-feature-policy.https.sub.html [ Skip ] -crbug.com/806249 virtual/picture-in-picture/external/wpt/feature-policy/autoplay-disabled-by-feature-policy.https.sub.html [ Skip ] crbug.com/806249 virtual/unified-autoplay/external/wpt/feature-policy/picture-in-picture-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html [ Skip ] crbug.com/806249 virtual/unified-autoplay/external/wpt/feature-policy/picture-in-picture-allowed-by-feature-policy-attribute.https.sub.html [ Skip ] crbug.com/806249 virtual/unified-autoplay/external/wpt/feature-policy/picture-in-picture-allowed-by-feature-policy.https.sub.html [ Skip ] @@ -4482,6 +4464,9 @@ crbug.com/811977 virtual/video-surface-layer/media/picture-in-picture/picture-in-picture-interstitial.html [ Failure ] crbug.com/806249 virtual/video-surface-layer/media/picture-in-picture/controls/picture-in-picture-button.html [ Failure ] crbug.com/806249 virtual/video-surface-layer/media/picture-in-picture/controls/picture-in-picture-video-with-audio-only-button.html [ Failure ] +crbug.com/806249 virtual/video-surface-layer/external/wpt/feature-policy/autoplay-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html [ Skip ] +crbug.com/806249 virtual/video-surface-layer/external/wpt/feature-policy/autoplay-default-feature-policy.https.sub.html [ Skip ] +crbug.com/806249 virtual/video-surface-layer/external/wpt/feature-policy/autoplay-disabled-by-feature-policy.https.sub.html [ Skip ] # Sheriff 2018-02-26 crbug.com/816475 [ Win7 Linux ] external/wpt/webrtc/RTCDTMFSender-ontonechange.https.html [ Failure Pass ] @@ -4718,6 +4703,7 @@ # Sheriff 2018-06-18 crbug.com/853852 [ Win7 Linux ] virtual/threaded/external/wpt/feature-policy/experimental-features/vertical-scroll-wheel-block-manual.tentative.html [ Pass Timeout ] +crbug.com/853852 [ Linux ] virtual/video-surface-layer/external/wpt/feature-policy/experimental-features/vertical-scroll-touch-action-manual.tentative.html [ Skip ] crbug.com/854538 [ Win7 ] http/tests/security/contentSecurityPolicy/1.1/form-action-src-default-ignored-with-redirect.html [ Skip ] @@ -4761,4 +4747,7 @@ # Sheriff 2018-07-03 crbug.com/860031 [ Linux ] http/tests/object/remote-frame-crash.html [ Failure ] -crbug.com/859629 [ Mac10.13 ] http/tests/devtools/tracing/timeline-js/timeline-script-tag-1.js [ Failure ] \ No newline at end of file +crbug.com/859629 [ Mac10.13 ] http/tests/devtools/tracing/timeline-js/timeline-script-tag-1.js [ Failure ] + +# wpt/feature-policy/experimental-features/vertical-scroll-touch-block-manual.tentative.html is flaky in some virtual/ tests. +crbug.com/850964 [ Linux Win ] virtual/video-surface-layer/external/wpt/feature-policy/experimental-features/vertical-scroll-touch-block-manual.tentative.html [ Pass Failure ]
diff --git a/third_party/WebKit/LayoutTests/VirtualTestSuites b/third_party/WebKit/LayoutTests/VirtualTestSuites index 2ea030d..83a99a91 100644 --- a/third_party/WebKit/LayoutTests/VirtualTestSuites +++ b/third_party/WebKit/LayoutTests/VirtualTestSuites
@@ -492,32 +492,32 @@ { "prefix": "outofblink-cors", "base": "external/wpt/fetch", - "args": ["--enable-features=OutOfBlinkCORS"] + "args": ["--enable-features=OutOfBlinkCORS,ServiceWorkerServicification"] }, { "prefix": "outofblink-cors", "base": "external/wpt/http", - "args": ["--enable-features=OutOfBlinkCORS"] + "args": ["--enable-features=OutOfBlinkCORS,ServiceWorkerServicification"] }, { "prefix": "outofblink-cors", "base": "external/wpt/referrer-policy", - "args": ["--enable-features=OutOfBlinkCORS"] + "args": ["--enable-features=OutOfBlinkCORS,ServiceWorkerServicification"] }, { "prefix": "outofblink-cors", "base": "external/wpt/service-workers", - "args": ["--enable-features=OutOfBlinkCORS"] + "args": ["--enable-features=OutOfBlinkCORS,ServiceWorkerServicification"] }, { "prefix": "outofblink-cors", "base": "http/tests/fetch", - "args": ["--enable-features=OutOfBlinkCORS"] + "args": ["--enable-features=OutOfBlinkCORS,ServiceWorkerServicification"] }, { "prefix": "outofblink-cors", "base": "http/tests/xmlhttprequest", - "args": ["--enable-features=OutOfBlinkCORS"] + "args": ["--enable-features=OutOfBlinkCORS,ServiceWorkerServicification"] }, { "prefix": "presentation", @@ -611,21 +611,6 @@ "args": ["--enable-features=SignedHTTPExchangeOriginTrial,NetworkService"] }, { - "prefix": "picture-in-picture", - "base": "external/wpt/picture-in-picture", - "args": ["--enable-features=UseSurfaceLayerForVideo"] - }, - { - "prefix": "picture-in-picture", - "base": "external/wpt/feature-policy", - "args": ["--enable-features=UseSurfaceLayerForVideo"] - }, - { - "prefix": "picture-in-picture", - "base": "media/picture-in-picture", - "args": ["--enable-features=PictureInPicture,UseSurfaceLayerForVideo"] - }, - { "prefix": "service-worker-servicification", "base": "http/tests/serviceworker", "args": ["--enable-features=ServiceWorkerServicification", @@ -664,6 +649,18 @@ "--enable-display-compositor-pixel-dump"] }, { + "prefix": "video-surface-layer", + "base": "external/wpt/picture-in-picture", + "args": ["--enable-features=UseSurfaceLayerForVideo", + "--enable-display-compositor-pixel-dump"] + }, + { + "prefix": "video-surface-layer", + "base": "external/wpt/feature-policy", + "args": ["--enable-features=UseSurfaceLayerForVideo", + "--enable-display-compositor-pixel-dump"] + }, + { "prefix": "user-activation-v2", "base": "fast/dom/Window", "args": ["--enable-features=UserActivationV2"]
diff --git a/third_party/WebKit/LayoutTests/animations/custom-properties/angle-type-interpolation.html b/third_party/WebKit/LayoutTests/animations/custom-properties/angle-type-interpolation.html index 7085a599..1afe30a3 100644 --- a/third_party/WebKit/LayoutTests/animations/custom-properties/angle-type-interpolation.html +++ b/third_party/WebKit/LayoutTests/animations/custom-properties/angle-type-interpolation.html
@@ -15,6 +15,7 @@ name: '--angle', syntax: '<angle>', initialValue: '40deg', + inherits: false, }); assertInterpolation({
diff --git a/third_party/WebKit/LayoutTests/animations/custom-properties/color-type-interpolation.html b/third_party/WebKit/LayoutTests/animations/custom-properties/color-type-interpolation.html index 5d60922..4377bbe2 100644 --- a/third_party/WebKit/LayoutTests/animations/custom-properties/color-type-interpolation.html +++ b/third_party/WebKit/LayoutTests/animations/custom-properties/color-type-interpolation.html
@@ -16,6 +16,7 @@ name: '--color', syntax: '<color>', initialValue: 'black', + inherits: false, }); assertInterpolation({
diff --git a/third_party/WebKit/LayoutTests/animations/custom-properties/custom-ident-type-interpolation.html b/third_party/WebKit/LayoutTests/animations/custom-properties/custom-ident-type-interpolation.html index e496a9d..3249a44 100644 --- a/third_party/WebKit/LayoutTests/animations/custom-properties/custom-ident-type-interpolation.html +++ b/third_party/WebKit/LayoutTests/animations/custom-properties/custom-ident-type-interpolation.html
@@ -15,6 +15,7 @@ name: '--ident', syntax: '<custom-ident>', initialValue: 'initial-value', + inherits: false, }); assertNoInterpolation({
diff --git a/third_party/WebKit/LayoutTests/animations/custom-properties/empty-initial-value-crash.html b/third_party/WebKit/LayoutTests/animations/custom-properties/empty-initial-value-crash.html index efd5e5d..3db3cad 100644 --- a/third_party/WebKit/LayoutTests/animations/custom-properties/empty-initial-value-crash.html +++ b/third_party/WebKit/LayoutTests/animations/custom-properties/empty-initial-value-crash.html
@@ -8,7 +8,7 @@ <div id="target"></div> <script> setup(() => { - CSS.registerProperty({name: '--x'}); + CSS.registerProperty({name: '--x', inherits: false}); }); test(() => {
diff --git a/third_party/WebKit/LayoutTests/animations/custom-properties/ident-type-interpolation.html b/third_party/WebKit/LayoutTests/animations/custom-properties/ident-type-interpolation.html index a2301d53..9cfbc54e 100644 --- a/third_party/WebKit/LayoutTests/animations/custom-properties/ident-type-interpolation.html +++ b/third_party/WebKit/LayoutTests/animations/custom-properties/ident-type-interpolation.html
@@ -15,6 +15,7 @@ name: '--ident', syntax: 'parent | underlying | initial-value | hello | apple | banana', initialValue: 'initial-value', + inherits: false, }); assertNoInterpolation({
diff --git a/third_party/WebKit/LayoutTests/animations/custom-properties/image-type-interpolation.html b/third_party/WebKit/LayoutTests/animations/custom-properties/image-type-interpolation.html index 4853b18..595a332 100644 --- a/third_party/WebKit/LayoutTests/animations/custom-properties/image-type-interpolation.html +++ b/third_party/WebKit/LayoutTests/animations/custom-properties/image-type-interpolation.html
@@ -15,6 +15,7 @@ name: '--image', syntax: '<image>', initialValue: "url('http://initial.png')", + inherits: false, }); assertInterpolation({
diff --git a/third_party/WebKit/LayoutTests/animations/custom-properties/integer-type-interpolation.html b/third_party/WebKit/LayoutTests/animations/custom-properties/integer-type-interpolation.html index d8ea3101..5f3c8d4 100644 --- a/third_party/WebKit/LayoutTests/animations/custom-properties/integer-type-interpolation.html +++ b/third_party/WebKit/LayoutTests/animations/custom-properties/integer-type-interpolation.html
@@ -15,6 +15,7 @@ name: '--integer', syntax: '<integer>', initialValue: '40', + inherits: false, }); assertInterpolation({
diff --git a/third_party/WebKit/LayoutTests/animations/custom-properties/length-percentage-type-interpolation.html b/third_party/WebKit/LayoutTests/animations/custom-properties/length-percentage-type-interpolation.html index 1786d7b..cf30355 100644 --- a/third_party/WebKit/LayoutTests/animations/custom-properties/length-percentage-type-interpolation.html +++ b/third_party/WebKit/LayoutTests/animations/custom-properties/length-percentage-type-interpolation.html
@@ -18,6 +18,7 @@ name: '--length-percentage', syntax: '<length-percentage>', initialValue: 'calc(40px + 80%)', + inherits: false, }); assertInterpolation({
diff --git a/third_party/WebKit/LayoutTests/animations/custom-properties/length-percentage-type-mismatch-no-interpolation-expected.txt b/third_party/WebKit/LayoutTests/animations/custom-properties/length-percentage-type-mismatch-no-interpolation-expected.txt index ab22230f..e745b667 100644 --- a/third_party/WebKit/LayoutTests/animations/custom-properties/length-percentage-type-mismatch-no-interpolation-expected.txt +++ b/third_party/WebKit/LayoutTests/animations/custom-properties/length-percentage-type-mismatch-no-interpolation-expected.txt
@@ -1,5 +1,5 @@ -CONSOLE WARNING: line 24: Invalid keyframe value for property --length: 10% -CONSOLE WARNING: line 35: Invalid keyframe value for property --percentage: 10px +CONSOLE WARNING: line 26: Invalid keyframe value for property --length: 10% +CONSOLE WARNING: line 37: Invalid keyframe value for property --percentage: 10px This is a testharness.js-based test. PASS <length> properties don't accept percentages in animation keyframes PASS <percentage> properties don't accept lengths in animation keyframes
diff --git a/third_party/WebKit/LayoutTests/animations/custom-properties/length-percentage-type-mismatch-no-interpolation.html b/third_party/WebKit/LayoutTests/animations/custom-properties/length-percentage-type-mismatch-no-interpolation.html index 5bdf67d..5162ea2 100644 --- a/third_party/WebKit/LayoutTests/animations/custom-properties/length-percentage-type-mismatch-no-interpolation.html +++ b/third_party/WebKit/LayoutTests/animations/custom-properties/length-percentage-type-mismatch-no-interpolation.html
@@ -11,12 +11,14 @@ name: '--length', syntax: '<length>', initialValue: '40px', + inherits: false, }); CSS.registerProperty({ name: '--percentage', syntax: '<percentage>', initialValue: '40%', + inherits: false, }); });
diff --git a/third_party/WebKit/LayoutTests/animations/custom-properties/length-type-interpolation.html b/third_party/WebKit/LayoutTests/animations/custom-properties/length-type-interpolation.html index e6878e7..4fbd3cf 100644 --- a/third_party/WebKit/LayoutTests/animations/custom-properties/length-type-interpolation.html +++ b/third_party/WebKit/LayoutTests/animations/custom-properties/length-type-interpolation.html
@@ -16,6 +16,7 @@ name: '--length', syntax: '<length>', initialValue: '40px', + inherits: false, }); assertInterpolation({
diff --git a/third_party/WebKit/LayoutTests/animations/custom-properties/number-type-interpolation.html b/third_party/WebKit/LayoutTests/animations/custom-properties/number-type-interpolation.html index 82cb976e..ec30c921d 100644 --- a/third_party/WebKit/LayoutTests/animations/custom-properties/number-type-interpolation.html +++ b/third_party/WebKit/LayoutTests/animations/custom-properties/number-type-interpolation.html
@@ -15,6 +15,7 @@ name: '--number', syntax: '<number>', initialValue: '40', + inherits: false, }); assertInterpolation({
diff --git a/third_party/WebKit/LayoutTests/animations/custom-properties/percentage-type-interpolation.html b/third_party/WebKit/LayoutTests/animations/custom-properties/percentage-type-interpolation.html index 9addfd9..9c869f87 100644 --- a/third_party/WebKit/LayoutTests/animations/custom-properties/percentage-type-interpolation.html +++ b/third_party/WebKit/LayoutTests/animations/custom-properties/percentage-type-interpolation.html
@@ -15,6 +15,7 @@ name: '--percentage', syntax: '<percentage>', initialValue: '40%', + inherits: false, }); assertInterpolation({
diff --git a/third_party/WebKit/LayoutTests/animations/custom-properties/registered-neutral-keyframe.html b/third_party/WebKit/LayoutTests/animations/custom-properties/registered-neutral-keyframe.html index 37c12c5..bebfe1b 100644 --- a/third_party/WebKit/LayoutTests/animations/custom-properties/registered-neutral-keyframe.html +++ b/third_party/WebKit/LayoutTests/animations/custom-properties/registered-neutral-keyframe.html
@@ -15,6 +15,7 @@ CSS.registerProperty({ name: '--x', syntax: '*', + inherits: false, }); test(() => {
diff --git a/third_party/WebKit/LayoutTests/animations/custom-properties/registered-var-chain.html b/third_party/WebKit/LayoutTests/animations/custom-properties/registered-var-chain.html index da47db8..fcb3efcb 100644 --- a/third_party/WebKit/LayoutTests/animations/custom-properties/registered-var-chain.html +++ b/third_party/WebKit/LayoutTests/animations/custom-properties/registered-var-chain.html
@@ -9,6 +9,7 @@ name, syntax: '<number>', initialValue: '0', + inherits: false, }); } });
diff --git a/third_party/WebKit/LayoutTests/animations/custom-properties/registered-var-dynamic-dependency.html b/third_party/WebKit/LayoutTests/animations/custom-properties/registered-var-dynamic-dependency.html index 9d8d207..ee495566 100644 --- a/third_party/WebKit/LayoutTests/animations/custom-properties/registered-var-dynamic-dependency.html +++ b/third_party/WebKit/LayoutTests/animations/custom-properties/registered-var-dynamic-dependency.html
@@ -9,6 +9,7 @@ name, syntax: '<number> | initial-value', initialValue: 'initial-value', + inherits: false, }); } });
diff --git a/third_party/WebKit/LayoutTests/animations/custom-properties/registered-var-fallback.html b/third_party/WebKit/LayoutTests/animations/custom-properties/registered-var-fallback.html index 3276948..831f374 100644 --- a/third_party/WebKit/LayoutTests/animations/custom-properties/registered-var-fallback.html +++ b/third_party/WebKit/LayoutTests/animations/custom-properties/registered-var-fallback.html
@@ -15,6 +15,7 @@ name, syntax: '<number>', initialValue: '0', + inherits: false, }); } });
diff --git a/third_party/WebKit/LayoutTests/animations/custom-properties/registered-var-to-registered-animating.html b/third_party/WebKit/LayoutTests/animations/custom-properties/registered-var-to-registered-animating.html index b062b74..e16a36d3 100644 --- a/third_party/WebKit/LayoutTests/animations/custom-properties/registered-var-to-registered-animating.html +++ b/third_party/WebKit/LayoutTests/animations/custom-properties/registered-var-to-registered-animating.html
@@ -14,6 +14,7 @@ name, syntax: '<number>', initialValue: '0', + inherits: false, }); } });
diff --git a/third_party/WebKit/LayoutTests/animations/custom-properties/registered-var-to-registered-any-order.html b/third_party/WebKit/LayoutTests/animations/custom-properties/registered-var-to-registered-any-order.html index 281796a..d91549e 100644 --- a/third_party/WebKit/LayoutTests/animations/custom-properties/registered-var-to-registered-any-order.html +++ b/third_party/WebKit/LayoutTests/animations/custom-properties/registered-var-to-registered-any-order.html
@@ -9,6 +9,7 @@ name, syntax: '<number>', initialValue: '0', + inherits: false, }); } });
diff --git a/third_party/WebKit/LayoutTests/animations/custom-properties/registered-var-to-registered-transitioning.html b/third_party/WebKit/LayoutTests/animations/custom-properties/registered-var-to-registered-transitioning.html index 305e9445..9781bd1 100644 --- a/third_party/WebKit/LayoutTests/animations/custom-properties/registered-var-to-registered-transitioning.html +++ b/third_party/WebKit/LayoutTests/animations/custom-properties/registered-var-to-registered-transitioning.html
@@ -18,6 +18,7 @@ name, syntax: '<number>', initialValue: '0', + inherits: false, }); } });
diff --git a/third_party/WebKit/LayoutTests/animations/custom-properties/registered-var-to-registered.html b/third_party/WebKit/LayoutTests/animations/custom-properties/registered-var-to-registered.html index 6994eef..e5a9518 100644 --- a/third_party/WebKit/LayoutTests/animations/custom-properties/registered-var-to-registered.html +++ b/third_party/WebKit/LayoutTests/animations/custom-properties/registered-var-to-registered.html
@@ -15,6 +15,7 @@ name, syntax: '<number>', initialValue: '0', + inherits: false, }); } });
diff --git a/third_party/WebKit/LayoutTests/animations/custom-properties/registered-var-to-unregistered-animating.html b/third_party/WebKit/LayoutTests/animations/custom-properties/registered-var-to-unregistered-animating.html index 69185a8..6acf546 100644 --- a/third_party/WebKit/LayoutTests/animations/custom-properties/registered-var-to-unregistered-animating.html +++ b/third_party/WebKit/LayoutTests/animations/custom-properties/registered-var-to-unregistered-animating.html
@@ -13,6 +13,7 @@ name: '--test', syntax: '<number>', initialValue: '0', + inherits: false, }); });
diff --git a/third_party/WebKit/LayoutTests/animations/custom-properties/registered-var-to-unregistered.html b/third_party/WebKit/LayoutTests/animations/custom-properties/registered-var-to-unregistered.html index cd575dc..64ba2c1 100644 --- a/third_party/WebKit/LayoutTests/animations/custom-properties/registered-var-to-unregistered.html +++ b/third_party/WebKit/LayoutTests/animations/custom-properties/registered-var-to-unregistered.html
@@ -14,6 +14,7 @@ name: '--test', syntax: '<number>', initialValue: '0', + inherits: false, }); });
diff --git a/third_party/WebKit/LayoutTests/animations/custom-properties/resolution-interpolation.html b/third_party/WebKit/LayoutTests/animations/custom-properties/resolution-interpolation.html index 2b1d312f..2bfd1a34 100644 --- a/third_party/WebKit/LayoutTests/animations/custom-properties/resolution-interpolation.html +++ b/third_party/WebKit/LayoutTests/animations/custom-properties/resolution-interpolation.html
@@ -15,6 +15,7 @@ name: '--resolution', syntax: '<resolution>', initialValue: '40dppx', + inherits: false, }); assertInterpolation({
diff --git a/third_party/WebKit/LayoutTests/animations/custom-properties/time-type-interpolation.html b/third_party/WebKit/LayoutTests/animations/custom-properties/time-type-interpolation.html index 953848c..f1bf421a 100644 --- a/third_party/WebKit/LayoutTests/animations/custom-properties/time-type-interpolation.html +++ b/third_party/WebKit/LayoutTests/animations/custom-properties/time-type-interpolation.html
@@ -15,6 +15,7 @@ name: '--time', syntax: '<time>', initialValue: '40s', + inherits: false, }); assertInterpolation({
diff --git a/third_party/WebKit/LayoutTests/animations/custom-properties/token-stream-type-interpolation.html b/third_party/WebKit/LayoutTests/animations/custom-properties/token-stream-type-interpolation.html index b9f43a21..84d06bb 100644 --- a/third_party/WebKit/LayoutTests/animations/custom-properties/token-stream-type-interpolation.html +++ b/third_party/WebKit/LayoutTests/animations/custom-properties/token-stream-type-interpolation.html
@@ -15,6 +15,7 @@ name: '--token-stream', syntax: '*', initialValue: 'initial tokens', + inherits: false, }); assertNoInterpolation({
diff --git a/third_party/WebKit/LayoutTests/animations/custom-properties/url-type-interpolation.html b/third_party/WebKit/LayoutTests/animations/custom-properties/url-type-interpolation.html index 5650a0b..99f8d6c 100644 --- a/third_party/WebKit/LayoutTests/animations/custom-properties/url-type-interpolation.html +++ b/third_party/WebKit/LayoutTests/animations/custom-properties/url-type-interpolation.html
@@ -15,6 +15,7 @@ name: '--url', syntax: '<url>', initialValue: "url('http://initial.txt')", + inherits: false, }); assertNoInterpolation({
diff --git a/third_party/WebKit/LayoutTests/custom-properties/usecount-register-property.html b/third_party/WebKit/LayoutTests/custom-properties/usecount-register-property.html index 2f177269..5a75dcb 100644 --- a/third_party/WebKit/LayoutTests/custom-properties/usecount-register-property.html +++ b/third_party/WebKit/LayoutTests/custom-properties/usecount-register-property.html
@@ -12,7 +12,7 @@ assert_false(isCounted(), 'should not be counted before registerProperty call'); - CSS.registerProperty({name: '--name1'}); + CSS.registerProperty({name: '--name1', inherits: false}); assert_true(isCounted(), 'registerProperty call should be counted');
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json index b76cbb2..f0b7d82 100644 --- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json +++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -103350,6 +103350,11 @@ {} ] ], + "client-hints/resources/http_equiv_accept_ch_lifetime.html": [ + [ + {} + ] + ], "clipboard-apis/META.yml": [ [ {} @@ -168245,6 +168250,21 @@ {} ] ], + "svg/types/elements/SVGGeometryElement-rect-expected.txt": [ + [ + {} + ] + ], + "svg/types/scripted/SVGAnimatedRect-expected.txt": [ + [ + {} + ] + ], + "svg/types/scripted/SVGGraphicsElement-expected.txt": [ + [ + {} + ] + ], "svg/types/scripted/SVGLength-px-expected.txt": [ [ {} @@ -184509,6 +184529,30 @@ {} ] ], + "client-hints/http_equiv_accept_ch_lifetime.tentative.https.html": [ + [ + "/client-hints/http_equiv_accept_ch_lifetime.tentative.https.html", + {} + ] + ], + "client-hints/http_equiv_accept_ch_lifetime_cross_origin_iframe.tentative.sub.https.html": [ + [ + "/client-hints/http_equiv_accept_ch_lifetime_cross_origin_iframe.tentative.sub.https.html", + {} + ] + ], + "client-hints/http_equiv_accept_ch_lifetime_same_origin_iframe.tentative.https.html": [ + [ + "/client-hints/http_equiv_accept_ch_lifetime_same_origin_iframe.tentative.https.html", + {} + ] + ], + "client-hints/http_equiv_accept_ch_lifetime_subresource.tentative.https.html": [ + [ + "/client-hints/http_equiv_accept_ch_lifetime_subresource.tentative.https.html", + {} + ] + ], "client-hints/http_equiv_accept_ch_malformed_header.tentative.https.html": [ [ "/client-hints/http_equiv_accept_ch_malformed_header.tentative.https.html", @@ -198268,7 +198312,9 @@ "css/selectors/focus-visible-005.html": [ [ "/css/selectors/focus-visible-005.html", - {} + { + "testdriver": true + } ] ], "css/selectors/focus-visible-007.html": [ @@ -198279,6 +198325,24 @@ } ] ], + "css/selectors/focus-visible-008.html": [ + [ + "/css/selectors/focus-visible-008.html", + {} + ] + ], + "css/selectors/focus-visible-009.html": [ + [ + "/css/selectors/focus-visible-009.html", + {} + ] + ], + "css/selectors/focus-visible-010.html": [ + [ + "/css/selectors/focus-visible-010.html", + {} + ] + ], "css/selectors/focus-within-009.html": [ [ "/css/selectors/focus-within-009.html", @@ -250739,6 +250803,12 @@ {} ] ], + "svg/types/scripted/SVGGraphicsElement.svg": [ + [ + "/svg/types/scripted/SVGGraphicsElement.svg", + {} + ] + ], "svg/types/scripted/SVGLength-px-with-context.html": [ [ "/svg/types/scripted/SVGLength-px-with-context.html", @@ -274531,7 +274601,7 @@ "support" ], "client-hints/accept_ch.tentative.https.html": [ - "64f3e60bbc14c208a2fbe8193c694429fe394b31", + "812edca2d3fd438a13bcc05a6c7a722b467e000b", "testharness" ], "client-hints/accept_ch.tentative.sub.https.html": [ @@ -274543,19 +274613,19 @@ "support" ], "client-hints/accept_ch_lifetime.tentative.https.html": [ - "0e1756a8ea48e53011ada28ed0fa6070a0713691", + "4a0f40a61adfb2d4f5ab67244ebf98b4a66bf544", "testharness" ], "client-hints/accept_ch_lifetime_cross_origin_iframe.tentative.sub.https.html": [ - "0006c59d1d9c305e94dfe60511c00539fb1f0887", + "c1c96cf6eac7da1368fcb41590efe3d60456692c", "testharness" ], "client-hints/accept_ch_lifetime_same_origin_iframe.tentative.https.html": [ - "020fc61613776711177970917ddaacf3ed641a82", + "635b8d12d8d38f4f5be2b840e337a87cd63744ed", "testharness" ], "client-hints/accept_ch_lifetime_subresource.tentative.https.html": [ - "b6235b48fa3132c5f5e0cb6187f25134abdee57e", + "6aeb04a3ad14e9efb9765b37a46ca73ca45cdd26", "testharness" ], "client-hints/accept_ch_malformed_header.https.html": [ @@ -274582,6 +274652,22 @@ "f404276fd8263be9f4fc2ecfc4f1d28ce0f62f6d", "testharness" ], + "client-hints/http_equiv_accept_ch_lifetime.tentative.https.html": [ + "5881ee69c16a2990fd96bf201668900213f1c7d9", + "testharness" + ], + "client-hints/http_equiv_accept_ch_lifetime_cross_origin_iframe.tentative.sub.https.html": [ + "e505202f4f86587242bdd546eb2686d20ea70899", + "testharness" + ], + "client-hints/http_equiv_accept_ch_lifetime_same_origin_iframe.tentative.https.html": [ + "b1e602609e872b2e00f2086330450afae3764b17", + "testharness" + ], + "client-hints/http_equiv_accept_ch_lifetime_subresource.tentative.https.html": [ + "bcba9e32ad82008f3fa391559f9bc8fbca9805fb", + "testharness" + ], "client-hints/http_equiv_accept_ch_malformed_header.tentative.https.html": [ "17d80854b8a71289a1a1208984cca7021b51679a", "testharness" @@ -274603,11 +274689,15 @@ "support" ], "client-hints/resources/do_not_expect_client_hints_headers.html": [ - "0c036c2a388518922878380659da0f7e13d20543", + "3aa67914736b2aaf826a641ac3886bd1a07c37d5", "support" ], "client-hints/resources/expect_client_hints_headers.html": [ - "1fcc20d9ff0da7712aeeaa10db51fffb2fd97c50", + "f3dad5b94c675e20a768bd1408efeb160f7a9344", + "support" + ], + "client-hints/resources/http_equiv_accept_ch_lifetime.html": [ + "d892780f71f921b8fe8a068d417de63ee4a85600", "support" ], "clipboard-apis/META.yml": [ @@ -296139,7 +296229,7 @@ "testharness" ], "css/css-backgrounds/parsing/background-color-valid.html": [ - "cb9f0f31a7e4bc9f4b23c7e6240e377b05b14154", + "28b2f10b322194066a3eaa8029ea61d21ee00611", "testharness" ], "css/css-backgrounds/parsing/background-image-invalid.html": [ @@ -296195,7 +296285,7 @@ "testharness" ], "css/css-backgrounds/parsing/border-color-valid.html": [ - "a8df09796083692c802b5a48bd7761f474f14ef5", + "07c3c5a177b266026ed4de667ba7740d58f377e7", "testharness" ], "css/css-backgrounds/parsing/border-image-invalid.html": [ @@ -297331,7 +297421,7 @@ "testharness" ], "css/css-color/parsing/color-valid.html": [ - "462c103850d5880ccecdf4e7a79ac55d28380bf0", + "d13b776333ec9953ccfc403dfdc262ced259bd9a", "testharness" ], "css/css-color/parsing/opacity-invalid.html": [ @@ -342983,7 +343073,7 @@ "manual" ], "css/selectors/focus-visible-005.html": [ - "1c3cf3ee0ff36a3dfec3425416b97dcd1024e5d5", + "3c7dc48f1348531eb07dfd5ef556abdbe26c65a2", "testharness" ], "css/selectors/focus-visible-006-manual.html": [ @@ -342994,6 +343084,18 @@ "254e8c649b9b3801df191e6dc18bf01932a00191", "testharness" ], + "css/selectors/focus-visible-008.html": [ + "fb51f0ceeba6fb224ad5aa27cc59d3d02bb096f3", + "testharness" + ], + "css/selectors/focus-visible-009.html": [ + "20661274b554037c42ed30fd426d7a74c914c734", + "testharness" + ], + "css/selectors/focus-visible-010.html": [ + "bfe15a4423b1600e6cd97759f4aab20004a4c258", + "testharness" + ], "css/selectors/focus-within-001-ref.html": [ "cd36270f1a34ea74b10b761cb153a7eb85b221bc", "support" @@ -402371,7 +402473,7 @@ "testharness" ], "svg/historical.html": [ - "f18f89f68fdf1266768700235f08e7181ce0e0e1", + "18f7e83a130c87f91d6bb11c0e515c4e6302a106", "testharness" ], "svg/interfaces-expected.txt": [ @@ -402678,8 +402780,12 @@ "2976a4812636c4515cc5e2c633b17c47bee392ab", "testharness" ], + "svg/types/elements/SVGGeometryElement-rect-expected.txt": [ + "11b91f560c70bef8436895f6dbdba30de551863a", + "support" + ], "svg/types/elements/SVGGeometryElement-rect.svg": [ - "08237002915323f41dd5590ce4226f95ae79f285", + "118fd791a90c884cab72428d4167cebcacf91662", "testharness" ], "svg/types/scripted/SVGAnimatedAngle.html": [ @@ -402782,14 +402888,26 @@ "e2667461c918fceecc4aca58ff5713a98df347c0", "testharness" ], + "svg/types/scripted/SVGAnimatedRect-expected.txt": [ + "bed70856faa7aaa6649dcf49de62f0baface0840", + "support" + ], "svg/types/scripted/SVGAnimatedRect.html": [ - "dfc7ec677df247b015ef360793c7e5f0c926e45f", + "7ffbe6d2a29c0743b53c7d8cf5f1a280e1e7c857", "testharness" ], "svg/types/scripted/SVGGeometryElement.getPointAtLength-01.svg": [ "73c1c15179f02b637a68939ba08faa4f90af8e5b", "testharness" ], + "svg/types/scripted/SVGGraphicsElement-expected.txt": [ + "d002e0f7da6f282a3e94c294ce33d1eb2da71140", + "support" + ], + "svg/types/scripted/SVGGraphicsElement.svg": [ + "03bd83a59a23558f3d3a90e9e7742cc28af42f70", + "testharness" + ], "svg/types/scripted/SVGLength-px-expected.txt": [ "96ef321212d43fdc4808262e16e92392fd4d941c", "support" @@ -404123,7 +404241,7 @@ "testharness" ], "web-animations/META.yml": [ - "de7037ad7c7e358d95a3c579a5a347b149c69a0d", + "577cdcca4d53c33165793d69be5ce9722c07de91", "support" ], "web-animations/OWNERS": [
diff --git a/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch.tentative.https.html b/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch.tentative.https.html index 3f38574c..b8379de 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch.tentative.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch.tentative.https.html
@@ -37,15 +37,6 @@ }); }, "Precondition: Test that the browser does not have client hints preferences cached"); -// Fetching this webpage should NOT cause user-agent to persist client hint -// preferences for the origin. -var win = window.open("resources/accept_ch.html"); -assert_not_equals(win, null, "Popup windows not allowed?"); - -// Open a new window. Verify that the user agent does not attach the client -// hints. -var verify_win = window.open("resources/do_not_expect_client_hints_headers.html"); -assert_not_equals(verify_win, null, "Popup windows not allowed?"); async_test(t => { window.addEventListener('message', function(e) { if(!e.source.location.pathname.includes("do_not_expect_client_hints_headers.html")) { @@ -58,7 +49,19 @@ }) }, "Loading of resources/do_not_expect_client_hints_headers.html did not finish."); -</script> +function acceptChLoaded() { + // Open a new window. Verify that the user agent does not attach the client + // hints. + var verify_win = window.open("do_not_expect_client_hints_headers.html"); + assert_not_equals(verify_win, null, "Popup windows not allowed?"); +} +// Fetching this webpage should NOT cause user-agent to persist client hint +// preferences for the origin. +var win = window.open("resources/accept_ch.html"); +assert_not_equals(win, null, "Popup windows not allowed?"); +win.addEventListener('load', acceptChLoaded, false); + +</script> </body> </html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch_lifetime.tentative.https.html b/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch_lifetime.tentative.https.html index 8065cf1..0055b13 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch_lifetime.tentative.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch_lifetime.tentative.https.html
@@ -37,14 +37,6 @@ }); }, "Precondition: Test that the browser does not have client hints preferences cached"); -// Fetching this webpage should cause user-agent to persist client hint -// preferences for the origin. -var win = window.open("resources/accept_ch_lifetime.html"); -assert_not_equals(win, null, "Popup windows not allowed?"); - -// Open a new window. Verify that the user agent attaches the client hints. -var verify_win = window.open("resources/expect_client_hints_headers.html"); -assert_not_equals(verify_win, null, "Popup windows not allowed?"); async_test(t => { window.addEventListener('message', function(e) { if(!e.source.location.pathname.includes("expect_client_hints_headers.html")) { @@ -58,6 +50,18 @@ }, "Loading of resources/expect_client_hints_headers.html did not finish."); +function acceptChLifetimeLoaded() { + // Open a new window. Verify that the user agent attaches the client hints. + var verify_win = window.open("expect_client_hints_headers.html"); + assert_not_equals(verify_win, null, "Popup windows not allowed?"); +} + +// Fetching this webpage should cause user-agent to persist client hint +// preferences for the origin. +var win = window.open("resources/accept_ch_lifetime.html"); +assert_not_equals(win, null, "Popup windows not allowed?"); +win.addEventListener('load', acceptChLifetimeLoaded, false); + </script> </body> </html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch_lifetime_cross_origin_iframe.tentative.sub.https.html b/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch_lifetime_cross_origin_iframe.tentative.sub.https.html index 38e28e3..8273ac78 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch_lifetime_cross_origin_iframe.tentative.sub.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch_lifetime_cross_origin_iframe.tentative.sub.https.html
@@ -39,18 +39,6 @@ }); }, "Precondition: Test that the browser does not have client hints preferences cached"); -</script> - -<!-- Fetching this webpage should NOT cause user-agent to persist client hint - preferences for the origin.--> -<iframe src="https://{{hosts[][www]}}:{{ports[https][0]}}/client-hints/resources/accept_ch_lifetime.html"></iframe> - -<script> -// Open a new window. Verify that the user agent does not attach the client -// hints. -var win = window.open("resources/do_not_expect_client_hints_headers.html"); -assert_not_equals(win, null, "Popup windows not allowed?"); - async_test(t => { window.addEventListener('message', function(e) { if(!e.source.location.pathname.includes("do_not_expect_client_hints_headers.html")) { @@ -63,6 +51,18 @@ }) }, "Loading of resources/do_not_expect_client_hints_headers.html did not finish."); +function acceptChLifetimeLoaded() { + // Open a new window. Verify that the user agent does not attach the client + // hints. + var verify_win = window.open("resources/do_not_expect_client_hints_headers.html"); + assert_not_equals(verify_win, null, "Popup windows not allowed?"); +} + </script> + +<!-- Fetching this webpage should NOT cause user-agent to persist client hint + preferences for the origin.--> +<iframe onload="acceptChLifetimeLoaded()" src="https://{{hosts[][www]}}:{{ports[https][0]}}/client-hints/resources/accept_ch_lifetime.html"></iframe> + </body> </html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch_lifetime_same_origin_iframe.tentative.https.html b/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch_lifetime_same_origin_iframe.tentative.https.html index ca5a2b5..4d339b6d 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch_lifetime_same_origin_iframe.tentative.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch_lifetime_same_origin_iframe.tentative.https.html
@@ -39,16 +39,6 @@ }); }, "Precondition: Test that the browser does not have client hints preferences cached"); -</script> - -<!-- Fetching this webpage should cause user-agent to persist client hint - preferences for the origin.--> -<iframe src="resources/accept_ch_lifetime.html"></iframe> - -<script> -// Open a new window. Verify that the user agent attaches the client hints. -var win = window.open("resources/expect_client_hints_headers.html"); -assert_not_equals(win, null, "Popup windows not allowed?"); async_test(t => { window.addEventListener('message', function(e) { if(!e.source.location.pathname.includes("expect_client_hints_headers.html")) { @@ -61,7 +51,17 @@ }) }, "Loading of resources/expect_client_hints_headers.html did not finish."); +function acceptChLifetimeLoaded() { + // Open a new window. Verify that the user agent attaches the client hints. + var verify_win = window.open("resources/expect_client_hints_headers.html"); + assert_not_equals(verify_win, null, "Popup windows not allowed?"); +} </script> + +<!-- Fetching this webpage should cause user-agent to persist client hint + preferences for the origin.--> +<iframe onload="acceptChLifetimeLoaded()" src="resources/accept_ch_lifetime.html"></iframe> + </body> </html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch_lifetime_subresource.tentative.https.html b/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch_lifetime_subresource.tentative.https.html index c37dd94..e3864294 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch_lifetime_subresource.tentative.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/client-hints/accept_ch_lifetime_subresource.tentative.https.html
@@ -47,13 +47,13 @@ // Verify that the browser did not include client hints in the request // headers. assert_false(r.headers.has("device-memory-received"), "device-memory-received"); + // Open a new window. Verify that the user agent does not attach the client + // hints. + var win = window.open("resources/do_not_expect_client_hints_headers.html"); + assert_not_equals(win, null, "Popup windows not allowed?"); }); }, "Test receiving Accept-CH-Lifetime header"); -// Open a new window. Verify that the user agent does not attach the client -// hints. -var win = window.open("resources/do_not_expect_client_hints_headers.html"); -assert_not_equals(win, null, "Popup windows not allowed?"); async_test(t => { window.addEventListener('message', function(e) { if(!e.source.location.pathname.includes("do_not_expect_client_hints_headers.html")) { @@ -66,8 +66,6 @@ }) }, "Loading of resources/do_not_expect_client_hints_headers.html did not finish."); - </script> - </body> </html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/client-hints/http_equiv_accept_ch_lifetime.tentative.https.html b/third_party/WebKit/LayoutTests/external/wpt/client-hints/http_equiv_accept_ch_lifetime.tentative.https.html new file mode 100644 index 0000000..73ca1fc --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/client-hints/http_equiv_accept_ch_lifetime.tentative.https.html
@@ -0,0 +1,66 @@ +<html> +<title>Accept-CH-Lifetime test</title> +<body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<!-- +Apart from this webpage, the test opens two more html web page. One test is run +in this web page, and two in the other web pages. +--> + +<script> + +// This test fetches resources/http_equiv_accept_ch_lifetime.html. The response +// to that webpage contains Accept-CH and Accept-CH-Lifetime http-equiv headers. +// Fetching that webpage should cause the user-agent to persist origin +// preferences for the client hints specified in Accept-CH header for a +// duration specified in the Accept-CH-Lifetime header. + +// Next, to verify if the origin preferences were persisted by the user +// agent, this test fetches resources/expect_client_hints_headers.html +// in a new window. Fetching of resources/expect_client_hints_headers.html +// verifies that the user agent actually sends the client hints in the request +// headers. + +// Test is marked as tentative until https://github.com/whatwg/fetch/issues/726 +// is resolved. + +// First, verify the initial state to make sure that the browser does not have +// client hints preferences cached from a previous run of the test. +promise_test(t => { + return fetch("echo_client_hints_received.py").then(r => { + assert_equals(r.status, 200) + // Verify that the browser did not include client hints in the request + // headers when fetching echo_client_hints_received.py. + assert_false(r.headers.has("device-memory-received"), "device-memory-received"); + }); +}, "Precondition: Test that the browser does not have client hints preferences cached"); + +async_test(t => { + window.addEventListener('message', function(e) { + if(!e.source.location.pathname.includes("expect_client_hints_headers.html")) { + return; + } + if(typeof e.data != "string") + return; + assert_equals(e.data, "PASS"); + t.done(); +}) +}, "Loading of resources/expect_client_hints_headers.html did not finish."); + +function acceptChLifetimeLoaded() { + // Open a new window. Verify that the user agent attaches the client hints. + var verify_win = window.open("expect_client_hints_headers.html"); + assert_not_equals(verify_win, null, "Popup windows not allowed?"); +} + +// Fetching this webpage should cause user-agent to persist client hint +// preferences for the origin. +var win = window.open("resources/http_equiv_accept_ch_lifetime.html"); +assert_not_equals(win, null, "Popup windows not allowed?"); +win.addEventListener('load', acceptChLifetimeLoaded, false); + +</script> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/client-hints/http_equiv_accept_ch_lifetime_cross_origin_iframe.tentative.sub.https.html b/third_party/WebKit/LayoutTests/external/wpt/client-hints/http_equiv_accept_ch_lifetime_cross_origin_iframe.tentative.sub.https.html new file mode 100644 index 0000000..ab878f88 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/client-hints/http_equiv_accept_ch_lifetime_cross_origin_iframe.tentative.sub.https.html
@@ -0,0 +1,66 @@ +<html> +<title>Accept-CH-Lifetime test with cross-origin iframe</title> +<body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<!-- +Apart from this webpage, the test opens another html web page. One test is run +in this web page, and another in the second web page. +--> + +<script> + +// This test fetches resources/http_equiv_accept_ch_lifetime.html in a cross +// origin iframe. The response to that webpage contains Accept-CH and +// Accept-CH-Lifetime http-equiv headers. + +// Fetching that webpage should NOT cause the user-agent to persist origin +// preferences for the client hints specified. + +// Next, to verify if the origin preferences were NOT persisted by the user +// agent, this test fetches resources/do_not_expect_client_hints_headers.html +// in a new window. Fetching of +// resources/do_not_expect_client_hints_headers.html +// verifies that the user agent did not actually sent the client hints in the +// request headers. + +// Test is marked as tentative until https://github.com/whatwg/fetch/issues/726 +// is resolved. + +// First, verify the initial state to make sure that the browser does not have +// client hints preferences cached from a previous run of the test. +promise_test(t => { + return fetch("echo_client_hints_received.py").then(r => { + assert_equals(r.status, 200) + // Verify that the browser did not include client hints in the request + // headers when fetching echo_client_hints_received.py. + assert_false(r.headers.has("device-memory-received"), "device-memory-received"); + }); +}, "Precondition: Test that the browser does not have client hints preferences cached"); + +async_test(t => { + window.addEventListener('message', function(e) { + if(!e.source.location.pathname.includes("do_not_expect_client_hints_headers.html")) { + return; + } + if(typeof e.data != "string") + return; + assert_equals(e.data, "PASS"); + t.done(); + }) +}, "Loading of resources/do_not_expect_client_hints_headers.html did not finish."); + +function acceptChLifetimeLoaded() { + var verify_win = window.open("resources/do_not_expect_client_hints_headers.html"); + assert_not_equals(verify_win, null, "Popup windows not allowed?"); +} + +</script> + +<!-- Fetching this webpage should NOT cause user-agent to persist client hint + preferences for the origin.--> +<iframe onload="acceptChLifetimeLoaded()" src="https://{{hosts[][www]}}:{{ports[https][0]}}/client-hints/resources/http_equiv_accept_ch_lifetime.html"></iframe> + +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/client-hints/http_equiv_accept_ch_lifetime_same_origin_iframe.tentative.https.html b/third_party/WebKit/LayoutTests/external/wpt/client-hints/http_equiv_accept_ch_lifetime_same_origin_iframe.tentative.https.html new file mode 100644 index 0000000..9f7d1f3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/client-hints/http_equiv_accept_ch_lifetime_same_origin_iframe.tentative.https.html
@@ -0,0 +1,67 @@ +<html> +<title>Accept-CH-Lifetime test with same-origin iframe</title> +<body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<!-- +Apart from this webpage, the test opens another html web page. One test is run +in this web page, and another in the second web page. +--> + +<script> + +// This test fetches resources/http_equiv_accept_ch_lifetime.html in a same +// origin iframe. The response to that webpage contains Accept-CH and +// Accept-CH-Lifetime http-equiv headers. + +// Fetching that webpage should cause the user-agent to persist origin +// preferences for the client hints specified in Accept-CH header for a +// duration specified in the Accept-CH-Lifetime header. + +// Next, to verify if the origin preferences were persisted by the user +// agent, this test fetches resources/expect_client_hints_headers.html +// in a new window. Fetching of resources/expect_client_hints_headers.html +// verifies that the user agent actually sends the client hints in the request +// headers. + +// Test is marked as tentative until https://github.com/whatwg/fetch/issues/726 +// is resolved. + +// First, verify the initial state to make sure that the browser does not have +// client hints preferences cached from a previous run of the test. +promise_test(t => { + return fetch("echo_client_hints_received.py").then(r => { + assert_equals(r.status, 200) + // Verify that the browser did not include client hints in the request + // headers when fetching echo_client_hints_received.py. + assert_false(r.headers.has("device-memory-received"), "device-memory-received"); + }); +}, "Precondition: Test that the browser does not have client hints preferences cached"); + +async_test(t => { + window.addEventListener('message', function(e) { + if(!e.source.location.pathname.includes("expect_client_hints_headers.html")) { + return; + } + if(typeof e.data != "string") + return; + assert_equals(e.data, "PASS"); + t.done(); + }) +}, "Loading of resources/expect_client_hints_headers.html did not finish."); + +function acceptChLifetimeLoaded() { + // Open a new window. Verify that the user agent attaches the client hints. + var verify_win = window.open("resources/expect_client_hints_headers.html"); + assert_not_equals(verify_win, null, "Popup windows not allowed?"); +} + +</script> + +<!-- Fetching this webpage should cause user-agent to persist client hint + preferences for the origin.--> +<iframe onload="acceptChLifetimeLoaded()" src="resources/http_equiv_accept_ch_lifetime.html"></iframe> + +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/client-hints/http_equiv_accept_ch_lifetime_subresource.tentative.https.html b/third_party/WebKit/LayoutTests/external/wpt/client-hints/http_equiv_accept_ch_lifetime_subresource.tentative.https.html new file mode 100644 index 0000000..17f287d --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/client-hints/http_equiv_accept_ch_lifetime_subresource.tentative.https.html
@@ -0,0 +1,74 @@ +<html> +<title>Accept-CH-Lifetime test with subresource</title> +<body> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<!-- +Apart from this webpage, the test opens another html web page. One test is run +in this web page, and another in the second web page. +--> + +<script> + +// This test fetches resources/http_equiv_accept_ch_lifetime.html as a +// subresource. The response to that webpage contains Accept-CH and +// Accept-CH-Lifetime http-equiv headers. + +// Fetching that webpage as a subresource should NOT cause the user-agent to +// persist origin preferences for the client hints specified in Accept-CH +// header. + +// Next, to verify if the origin preferences were not persisted by the user +// agent, this test fetches resources/do_not_expect_client_hints_headers.html +// in a new window. Fetching of +// resources/do_not_expect_client_hints_headers.html verifies that the user +// agent does not send the client hints in the request headers. + +// Test is marked as tentative until https://github.com/whatwg/fetch/issues/726 +// is resolved. + +// First, verify the initial state to make sure that the browser does not have +// client hints preferences cached from a previous run of the test. +promise_test(t => { + return fetch("echo_client_hints_received.py").then(r => { + assert_equals(r.status, 200) + // Verify that the browser did not include client hints in the request + // headers when fetching echo_client_hints_received.py. + assert_false(r.headers.has("device-memory-received"), "device-memory-received"); + }); +}, "Precondition: Test that the browser does not have client hints preferences cached"); + +promise_test(t => { + // Fetching this web page as a subresource should NOT cause user-agent to + // persist client hint preferences for the origin. + return fetch("resources/http_equiv_accept_ch_lifetime.html").then(r => { + assert_equals(r.status, 200) + // Verify that the browser did not include client hints in the request + // headers. + assert_false(r.headers.has("device-memory-received"), "device-memory-received"); + + // Open a new window. Verify that the user agent does not attach the client + // hints. + var win = window.open("resources/do_not_expect_client_hints_headers.html"); + assert_not_equals(win, null, "Popup windows not allowed?"); + + }); +}, "Test receiving Accept-CH-Lifetime header"); + +async_test(t => { + window.addEventListener('message', function(e) { + if(!e.source.location.pathname.includes("do_not_expect_client_hints_headers.html")) { + return; + } + if(typeof e.data != "string") + return; + assert_equals(e.data, "PASS"); + t.done(); + }) +}, "Loading of resources/do_not_expect_client_hints_headers.html did not finish."); + + +</script> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/client-hints/resources/do_not_expect_client_hints_headers.html b/third_party/WebKit/LayoutTests/external/wpt/client-hints/resources/do_not_expect_client_hints_headers.html index 31da74b..b3cf5df 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/client-hints/resources/do_not_expect_client_hints_headers.html +++ b/third_party/WebKit/LayoutTests/external/wpt/client-hints/resources/do_not_expect_client_hints_headers.html
@@ -9,11 +9,11 @@ // of client hints it receives in the request headers. fetch("../echo_client_hints_received.py").then(r => { - if(r.status == 200 && r.headers.has("device-memory-received") != "device-memory-received") { + if(r.status == 200 && !r.headers.has("device-memory-received")) { window.top.opener.postMessage('PASS', '*'); } else { - window.top.opener.postMessage('FAIL '+ ex.message, '*'); + window.top.opener.postMessage('FAIL', '*'); } });
diff --git a/third_party/WebKit/LayoutTests/external/wpt/client-hints/resources/expect_client_hints_headers.html b/third_party/WebKit/LayoutTests/external/wpt/client-hints/resources/expect_client_hints_headers.html index 12d61e9..8e64b198 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/client-hints/resources/expect_client_hints_headers.html +++ b/third_party/WebKit/LayoutTests/external/wpt/client-hints/resources/expect_client_hints_headers.html
@@ -9,11 +9,11 @@ // of client hints it receives in the request headers. fetch("../echo_client_hints_received.py").then(r => { - if(r.status == 200 && r.headers.has("device-memory-received") == "device-memory-received") { + if(r.status == 200 && r.headers.has("device-memory-received")) { window.top.opener.postMessage('PASS', '*'); } else { - window.top.opener.postMessage('FAIL '+ ex.message, '*'); + window.top.opener.postMessage('FAIL', '*'); } });
diff --git a/third_party/WebKit/LayoutTests/external/wpt/client-hints/resources/http_equiv_accept_ch_lifetime.html b/third_party/WebKit/LayoutTests/external/wpt/client-hints/resources/http_equiv_accept_ch_lifetime.html new file mode 100644 index 0000000..2dd1806 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/client-hints/resources/http_equiv_accept_ch_lifetime.html
@@ -0,0 +1,6 @@ +<html> +<meta http-equiv="Accept-CH" content="device-memory"> +<meta http-equiv="Accept-CH-Lifetime" content="5"> +<body> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/parsing/background-color-valid.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/parsing/background-color-valid.html index e5f582f..d7a5d967 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/parsing/background-color-valid.html +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/parsing/background-color-valid.html
@@ -12,9 +12,8 @@ </head> <body> <script> -// Edge serializes as "currentColor". -test_valid_value("background-color", "currentcolor", ["currentcolor", "currentColor"]); -test_valid_value("background-color", "currentColor", ["currentcolor", "currentColor"]); +test_valid_value("background-color", "currentcolor", "currentcolor"); +test_valid_value("background-color", "currentColor", "currentcolor"); test_valid_value("background-color", "red"); test_valid_value("background-color", "#00FF00", "rgb(0, 255, 0)");
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/parsing/border-color-valid.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/parsing/border-color-valid.html index be78a06..6ee147c7 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/parsing/border-color-valid.html +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-backgrounds/parsing/border-color-valid.html
@@ -12,9 +12,8 @@ </head> <body> <script> -// Edge serializes as "currentColor". -test_valid_value("border-color", "currentcolor", ["currentcolor", "currentColor"]); -test_valid_value("border-color", "currentColor", ["currentcolor", "currentColor"]); +test_valid_value("border-color", "currentcolor", "currentcolor"); +test_valid_value("border-color", "currentColor", "currentcolor"); test_valid_value("border-color", "red yellow green blue");
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-color/parsing/color-valid.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-color/parsing/color-valid.html index 76e84847..e94eb38 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-color/parsing/color-valid.html +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-color/parsing/color-valid.html
@@ -12,7 +12,7 @@ </head> <body> <script> -test_valid_value("color", "currentcolor"); // Edge serializes as currentColor. +test_valid_value("color", "currentcolor"); test_valid_value("color", "transparent"); test_valid_value("color", "red"); test_valid_value("color", "magenta");
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-paint-api/registered-properties-in-custom-paint.https.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-paint-api/registered-properties-in-custom-paint.https.html index 01aac16..d9a63da 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-paint-api/registered-properties-in-custom-paint.https.html +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-paint-api/registered-properties-in-custom-paint.https.html
@@ -54,9 +54,9 @@ <script> try { - CSS.registerProperty({name: '--length', syntax: '<length>', initialValue: '0px'}); - CSS.registerProperty({name: '--length-initial', syntax: '<length>', initialValue: '20px'}); - CSS.registerProperty({name: '--number', syntax: '<number>', initialValue: '0'}); + CSS.registerProperty({name: '--length', syntax: '<length>', initialValue: '0px', inherits: false}); + CSS.registerProperty({name: '--length-initial', syntax: '<length>', initialValue: '20px', inherits: false}); + CSS.registerProperty({name: '--number', syntax: '<number>', initialValue: '0', inherits: false}); importWorkletAndTerminateTestAfterAsyncPaint(CSS.paintWorklet, document.getElementById('code').textContent); } catch(e) { document.body.textContent = e;
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-properties-values-api/register-property-syntax-parsing-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/css/css-properties-values-api/register-property-syntax-parsing-expected.txt index beae57d..f181f8d 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-properties-values-api/register-property-syntax-parsing-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-properties-values-api/register-property-syntax-parsing-expected.txt
@@ -85,7 +85,7 @@ PASS syntax:'*', initialValue:'initial' is invalid PASS syntax:'*', initialValue:'inherit' is invalid PASS syntax:'*', initialValue:'unset' is invalid -FAIL syntax:'*', initialValue:'revert' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue})" did not throw +FAIL syntax:'*', initialValue:'revert' is invalid assert_throws: function "() => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})" did not throw PASS syntax:'<custom-ident>', initialValue:'initial' is invalid PASS syntax:'<custom-ident>+', initialValue:'foo inherit bar' is invalid PASS syntax:'*', initialValue:')' is invalid
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-properties-values-api/register-property-syntax-parsing.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-properties-values-api/register-property-syntax-parsing.html index 500add40e..dbc96bb7 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-properties-values-api/register-property-syntax-parsing.html +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-properties-values-api/register-property-syntax-parsing.html
@@ -10,7 +10,7 @@ // No actual assertions, this just shouldn't throw test(function() { var name = '--syntax-test-' + (test_count++); - CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue}); + CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false}); }, "syntax:'" + syntax + "', initialValue:'" + initialValue + "' is valid"); } @@ -18,7 +18,7 @@ test(function(){ var name = '--syntax-test-' + (test_count++); assert_throws(new SyntaxError(), - () => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue})); + () => CSS.registerProperty({name: name, syntax: syntax, initialValue: initialValue, inherits: false})); }, "syntax:'" + syntax + "', initialValue:'" + initialValue + "' is invalid"); }
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-properties-values-api/register-property.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-properties-values-api/register-property.html index 597247c..62ad236 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-properties-values-api/register-property.html +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-properties-values-api/register-property.html
@@ -16,27 +16,33 @@ test(function() { // Valid property names, shouldn't throw - CSS.registerProperty({name: '--name1'}); - CSS.registerProperty({name: '--name2, no need for escapes'}); - CSS.registerProperty({name: ['--name', 3]}); + CSS.registerProperty({name: '--name1', inherits: false}); + CSS.registerProperty({name: '--name2, no need for escapes', inherits: false}); + CSS.registerProperty({name: ['--name', 3], inherits: false}); // Invalid property names assert_throws(new TypeError(), () => CSS.registerProperty({})); - assert_throws(new SyntaxError(), () => CSS.registerProperty({name: 'no-leading-dash'})); - assert_throws(new SyntaxError(), () => CSS.registerProperty({name: ''})); - assert_throws(new SyntaxError(), () => CSS.registerProperty({name: '\\--name'})); + assert_throws(new SyntaxError(), () => CSS.registerProperty({name: 'no-leading-dash', inherits: false})); + assert_throws(new SyntaxError(), () => CSS.registerProperty({name: '', inherits: false})); + assert_throws(new SyntaxError(), () => CSS.registerProperty({name: '\\--name', inherits: false})); }, "registerProperty requires a name matching <custom-property-name>"); test(function() { - CSS.registerProperty({name: '--syntax-test-1', syntax: '*'}); - CSS.registerProperty({name: '--syntax-test-2', syntax: ' * '}); + CSS.registerProperty({name: '--syntax-test-1', syntax: '*', inherits: false}); + CSS.registerProperty({name: '--syntax-test-2', syntax: ' * ', inherits: false}); assert_throws(new SyntaxError(), - () => CSS.registerProperty({name: '--syntax-test-3', syntax: 'length'})); -}, "registerProperty only allows omitting initialValue is syntax is '*'"); + () => CSS.registerProperty({name: '--syntax-test-3', syntax: 'length', inherits: false})); +}, "registerProperty only allows omitting initialValue if syntax is '*'"); test(function() { - CSS.registerProperty({name: '--re-register', syntax: '<length>', initialValue: '0px'}); + CSS.registerProperty({name: '--re-register', syntax: '<length>', initialValue: '0px', inherits: false}); assert_throws({name: 'InvalidModificationError'}, - () => CSS.registerProperty({name: '--re-register', syntax: '<percentage>', initialValue: '0%'})); + () => CSS.registerProperty({name: '--re-register', syntax: '<percentage>', initialValue: '0%', inherits: false})); }, "registerProperty fails for an already registered property"); + +test(function(){ + CSS.registerProperty({name: '--inherit-test-1', syntax: '<length>', initialValue: '0px', inherits: true}); + CSS.registerProperty({name: '--inherit-test-2', syntax: '<length>', initialValue: '0px', inherits: false}); + assert_throws(new TypeError(), () => CSS.registerProperty({name: '--inherit-test-3', syntax: '<length>', initialValue: '0px'})); +}, "registerProperty requires inherits"); </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-properties-values-api/registered-properties-inheritance.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-properties-values-api/registered-properties-inheritance.html index 393c0dc..20275a5 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-properties-values-api/registered-properties-inheritance.html +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-properties-values-api/registered-properties-inheritance.html
@@ -24,9 +24,9 @@ CSS.registerProperty({name: '--inherited-length-1', syntax: '<length>', initialValue: '1px', inherits: true}); CSS.registerProperty({name: '--inherited-length-2', syntax: '<length>', initialValue: '2px', inherits: true}); CSS.registerProperty({name: '--inherited-length-3', syntax: '<length>', initialValue: '3px', inherits: true}); - CSS.registerProperty({name: '--non-inherited-length-1', syntax: '<length>', initialValue: '4px'}); - CSS.registerProperty({name: '--non-inherited-length-2', syntax: '<length>', initialValue: '5px'}); - CSS.registerProperty({name: '--non-inherited-length-3', syntax: '<length>', initialValue: '6px'}); + CSS.registerProperty({name: '--non-inherited-length-1', syntax: '<length>', initialValue: '4px', inherits: false}); + CSS.registerProperty({name: '--non-inherited-length-2', syntax: '<length>', initialValue: '5px', inherits: false}); + CSS.registerProperty({name: '--non-inherited-length-3', syntax: '<length>', initialValue: '6px', inherits: false}); outerComputedStyle = getComputedStyle(outer); assert_equals(outerComputedStyle.getPropertyValue('--inherited-length-1'), '10px');
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-properties-values-api/registered-property-computation.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-properties-values-api/registered-property-computation.html index e204863..ddca2e4 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-properties-values-api/registered-property-computation.html +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-properties-values-api/registered-property-computation.html
@@ -36,20 +36,20 @@ <script> test(() => { - CSS.registerProperty({name: '--length-1', syntax: '<length>', initialValue: '0px'}); - CSS.registerProperty({name: '--length-2', syntax: '<length>', initialValue: '0px'}); - CSS.registerProperty({name: '--length-3', syntax: '<length>', initialValue: '0px'}); - CSS.registerProperty({name: '--length-4', syntax: '<length>', initialValue: '0px'}); - CSS.registerProperty({name: '--length-5', syntax: '<length>', initialValue: '0px'}); - CSS.registerProperty({name: '--length-6', syntax: '<length>', initialValue: '0px'}); - CSS.registerProperty({name: '--length-percentage-1', syntax: '<length-percentage>', initialValue: '0px'}); - CSS.registerProperty({name: '--length-percentage-2', syntax: '<length-percentage>', initialValue: '0px'}); - CSS.registerProperty({name: '--length-percentage-3', syntax: '<length-percentage>', initialValue: '0px'}); - CSS.registerProperty({name: '--list-1', syntax: '<length>+', initialValue: '0px'}); - CSS.registerProperty({name: '--list-2', syntax: '<length>+', initialValue: '0px'}); - CSS.registerProperty({name: '--list-3', syntax: '<length-percentage>+', initialValue: '0px'}); - CSS.registerProperty({name: '--list-4', syntax: '<length-percentage>+', initialValue: '0px'}); - CSS.registerProperty({name: '--font-size', syntax: '<length>', initialValue: '0px'}); + CSS.registerProperty({name: '--length-1', syntax: '<length>', initialValue: '0px', inherits: false}); + CSS.registerProperty({name: '--length-2', syntax: '<length>', initialValue: '0px', inherits: false}); + CSS.registerProperty({name: '--length-3', syntax: '<length>', initialValue: '0px', inherits: false}); + CSS.registerProperty({name: '--length-4', syntax: '<length>', initialValue: '0px', inherits: false}); + CSS.registerProperty({name: '--length-5', syntax: '<length>', initialValue: '0px', inherits: false}); + CSS.registerProperty({name: '--length-6', syntax: '<length>', initialValue: '0px', inherits: false}); + CSS.registerProperty({name: '--length-percentage-1', syntax: '<length-percentage>', initialValue: '0px', inherits: false}); + CSS.registerProperty({name: '--length-percentage-2', syntax: '<length-percentage>', initialValue: '0px', inherits: false}); + CSS.registerProperty({name: '--length-percentage-3', syntax: '<length-percentage>', initialValue: '0px', inherits: false}); + CSS.registerProperty({name: '--list-1', syntax: '<length>+', initialValue: '0px', inherits: false}); + CSS.registerProperty({name: '--list-2', syntax: '<length>+', initialValue: '0px', inherits: false}); + CSS.registerProperty({name: '--list-3', syntax: '<length-percentage>+', initialValue: '0px', inherits: false}); + CSS.registerProperty({name: '--list-4', syntax: '<length-percentage>+', initialValue: '0px', inherits: false}); + CSS.registerProperty({name: '--font-size', syntax: '<length>', initialValue: '0px', inherits: false}); }, "CSS.registerProperty"); for (var element of [divWithFontSizeSet, divWithFontSizeInherited]) {
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-properties-values-api/registered-property-cssom.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-properties-values-api/registered-property-cssom.html index d1641d2..019778e 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-properties-values-api/registered-property-cssom.html +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-properties-values-api/registered-property-cssom.html
@@ -38,7 +38,7 @@ }, "CSSOM setters function as expected for unregistered properties"); test(function() { - CSS.registerProperty({name: '--length', syntax: '<length>', initialValue: '0px'}); + CSS.registerProperty({name: '--length', syntax: '<length>', initialValue: '0px', inherits: false}); CSS.registerProperty({name: '--color', syntax: '<color>', initialValue: 'white', inherits: true}); }, "CSS.registerProperty");
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-properties-values-api/registered-property-initial.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-properties-values-api/registered-property-initial.html index 0e3e8545..585e9bc76 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-properties-values-api/registered-property-initial.html +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-properties-values-api/registered-property-initial.html
@@ -12,12 +12,12 @@ <div id=target></div> <script> test(function() { - CSS.registerProperty({name: '--length', syntax: '<length>', initialValue: 'calc(10px + 15px)'}); - CSS.registerProperty({name: '--length-percentage', syntax: '<length-percentage>', initialValue: 'calc(1in + 10% + 4px)'}); + CSS.registerProperty({name: '--length', syntax: '<length>', initialValue: 'calc(10px + 15px)', inherits: false}); + CSS.registerProperty({name: '--length-percentage', syntax: '<length-percentage>', initialValue: 'calc(1in + 10% + 4px)', inherits: false}); CSS.registerProperty({name: '--inherited-color', syntax: '<color>', initialValue: 'pink', inherits: true}); - CSS.registerProperty({name: '--non-inherited-color', syntax: '<color>', initialValue: 'purple'}); - CSS.registerProperty({name: '--single-transform-list', syntax: '<transform-list>', initialValue: 'scale(calc(2 + 2))'}); - CSS.registerProperty({name: '--multiple-transform-list', syntax: '<transform-list>', initialValue: 'scale(calc(2 + 1)) translateX(calc(3px + 1px))'}); + CSS.registerProperty({name: '--non-inherited-color', syntax: '<color>', initialValue: 'purple', inherits: false}); + CSS.registerProperty({name: '--single-transform-list', syntax: '<transform-list>', initialValue: 'scale(calc(2 + 2))', inherits: false}); + CSS.registerProperty({name: '--multiple-transform-list', syntax: '<transform-list>', initialValue: 'scale(calc(2 + 1)) translateX(calc(3px + 1px))', inherits: false}); computedStyle = getComputedStyle(target); assert_equals(computedStyle.getPropertyValue('--length'), '25px');
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-properties-values-api/var-reference-registered-properties-cycles.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-properties-values-api/var-reference-registered-properties-cycles.html index fdf8eaa..58d6c846 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-properties-values-api/var-reference-registered-properties-cycles.html +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-properties-values-api/var-reference-registered-properties-cycles.html
@@ -19,10 +19,10 @@ <div id=test1></div> <script> test(function() { - CSS.registerProperty({name: '--registered-1-a', syntax: '<length>', initialValue: '1px'}); - CSS.registerProperty({name: '--registered-1-b', syntax: '<length>', initialValue: '2px'}); - CSS.registerProperty({name: '--registered-1-c', syntax: '<length>', initialValue: '3px'}); - CSS.registerProperty({name: '--registered-1-d', syntax: '<length>', initialValue: '4px'}); + CSS.registerProperty({name: '--registered-1-a', syntax: '<length>', initialValue: '1px', inherits: false}); + CSS.registerProperty({name: '--registered-1-b', syntax: '<length>', initialValue: '2px', inherits: false}); + CSS.registerProperty({name: '--registered-1-c', syntax: '<length>', initialValue: '3px', inherits: false}); + CSS.registerProperty({name: '--registered-1-d', syntax: '<length>', initialValue: '4px', inherits: false}); computedStyle = getComputedStyle(test1); assert_equals(computedStyle.getPropertyValue('--registered-1-a'), '1px'); @@ -56,11 +56,11 @@ <div id=test2></div> <script> test(function() { - CSS.registerProperty({name: '--registered-2-a', syntax: '<length>', initialValue: '1px'}); - CSS.registerProperty({name: '--registered-2-b', syntax: '<length>', initialValue: '2px'}); - CSS.registerProperty({name: '--registered-2-c', syntax: '<length>', initialValue: '3px'}); - CSS.registerProperty({name: '--registered-2-d', syntax: '<length>', initialValue: '4px'}); - CSS.registerProperty({name: '--registered-2-e', syntax: '<length>', initialValue: '5px'}); + CSS.registerProperty({name: '--registered-2-a', syntax: '<length>', initialValue: '1px', inherits: false}); + CSS.registerProperty({name: '--registered-2-b', syntax: '<length>', initialValue: '2px', inherits: false}); + CSS.registerProperty({name: '--registered-2-c', syntax: '<length>', initialValue: '3px', inherits: false}); + CSS.registerProperty({name: '--registered-2-d', syntax: '<length>', initialValue: '4px', inherits: false}); + CSS.registerProperty({name: '--registered-2-e', syntax: '<length>', initialValue: '5px', inherits: false}); computedStyle = getComputedStyle(test2); assert_equals(computedStyle.getPropertyValue('--registered-2-a'), '1px'); @@ -95,10 +95,10 @@ <div id=test3></div> <script> test(function() { - CSS.registerProperty({name: '--registered-3-a', syntax: '<length>', initialValue: '1px'}); - CSS.registerProperty({name: '--registered-3-b', syntax: '<length>', initialValue: '2px'}); - CSS.registerProperty({name: '--registered-3-c', syntax: '<length>', initialValue: '3px'}); - CSS.registerProperty({name: '--registered-3-d', syntax: '<length>', initialValue: '4px'}); + CSS.registerProperty({name: '--registered-3-a', syntax: '<length>', initialValue: '1px', inherits: false}); + CSS.registerProperty({name: '--registered-3-b', syntax: '<length>', initialValue: '2px', inherits: false}); + CSS.registerProperty({name: '--registered-3-c', syntax: '<length>', initialValue: '3px', inherits: false}); + CSS.registerProperty({name: '--registered-3-d', syntax: '<length>', initialValue: '4px', inherits: false}); computedStyle = getComputedStyle(test3); assert_equals(computedStyle.getPropertyValue('--unregistered-3-a'), ''); @@ -128,9 +128,9 @@ <div id=test4></div> <script> test(function() { - CSS.registerProperty({name: '--registered-4-a', syntax: '*'}); - CSS.registerProperty({name: '--registered-4-b', syntax: '*', initialValue: 'moo'}); - CSS.registerProperty({name: '--registered-4-c', syntax: '*', initialValue: 'circle'}); + CSS.registerProperty({name: '--registered-4-a', syntax: '*', inherits: false}); + CSS.registerProperty({name: '--registered-4-b', syntax: '*', initialValue: 'moo', inherits: false}); + CSS.registerProperty({name: '--registered-4-c', syntax: '*', initialValue: 'circle', inherits: false}); computedStyle = getComputedStyle(test4); assert_equals(computedStyle.getPropertyValue('--registered-4-a'), '');
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-properties-values-api/var-reference-registered-properties.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-properties-values-api/var-reference-registered-properties.html index 2eb2d86..77ae299 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-properties-values-api/var-reference-registered-properties.html +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-properties-values-api/var-reference-registered-properties.html
@@ -27,19 +27,19 @@ <div id=element></div> <script> test(function() { - CSS.registerProperty({name: '--123px', syntax: '<length>', initialValue: '123px'}); + CSS.registerProperty({name: '--123px', syntax: '<length>', initialValue: '123px', inherits: false}); - CSS.registerProperty({name: '--registered-length-1', syntax: '<length>', initialValue: '0px'}); - CSS.registerProperty({name: '--registered-length-2', syntax: '<length>', initialValue: '0px'}); - CSS.registerProperty({name: '--registered-length-3', syntax: '<length>', initialValue: '0px'}); - CSS.registerProperty({name: '--registered-length-4', syntax: '<length>', initialValue: '0px'}); - CSS.registerProperty({name: '--registered-length-5', syntax: '<length>', initialValue: '0px'}); - CSS.registerProperty({name: '--registered-length-6', syntax: '<length>', initialValue: '0px'}); - CSS.registerProperty({name: '--registered-length-7', syntax: '<length>', initialValue: '0px'}); - CSS.registerProperty({name: '--registered-length-invalid', syntax: '<length>', initialValue: '15px'}); + CSS.registerProperty({name: '--registered-length-1', syntax: '<length>', initialValue: '0px', inherits: false}); + CSS.registerProperty({name: '--registered-length-2', syntax: '<length>', initialValue: '0px', inherits: false}); + CSS.registerProperty({name: '--registered-length-3', syntax: '<length>', initialValue: '0px', inherits: false}); + CSS.registerProperty({name: '--registered-length-4', syntax: '<length>', initialValue: '0px', inherits: false}); + CSS.registerProperty({name: '--registered-length-5', syntax: '<length>', initialValue: '0px', inherits: false}); + CSS.registerProperty({name: '--registered-length-6', syntax: '<length>', initialValue: '0px', inherits: false}); + CSS.registerProperty({name: '--registered-length-7', syntax: '<length>', initialValue: '0px', inherits: false}); + CSS.registerProperty({name: '--registered-length-invalid', syntax: '<length>', initialValue: '15px', inherits: false}); - CSS.registerProperty({name: '--registered-token-stream-1', syntax: '*'}); - CSS.registerProperty({name: '--registered-token-stream-2', syntax: '*'}); + CSS.registerProperty({name: '--registered-token-stream-1', syntax: '*', inherits: false}); + CSS.registerProperty({name: '--registered-token-stream-2', syntax: '*', inherits: false}); computedStyle = getComputedStyle(element); assert_equals(computedStyle.getPropertyValue('--registered-length-1'), '10px');
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-tables/anonymous-table-cell-margin-collapsing.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-tables/anonymous-table-cell-margin-collapsing.html new file mode 100644 index 0000000..23b467eb --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-tables/anonymous-table-cell-margin-collapsing.html
@@ -0,0 +1,20 @@ +<!DOCTYPE html> +<title>Anonymous table cells with semi-complex margin collapsing inside</title> +<link rel="author" title="Morten Stenshorne" href="mstensho@chromium.org"> +<link rel="help" href="https://www.w3.org/TR/CSS22/visuren.html#block-formatting" title="9.4.1 Block formatting contexts"> +<link rel="match" href="../reference/ref-filled-green-100px-square.xht"> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div style="display:table; height:100px; background:red;"> + <div style="display:table-row; background:green;"> + <div style="width:100px; margin:50px 0;"> + <div style="margin:50px 0;"></div> + </div> + <div style="margin:50px 0;"></div> + </div> + <div style="display:table-row; background:green;"> + <div style="margin:50px 0;"></div> + </div> + <!-- The above rows should use all available height, and the last + row should get nothing (or there'll be red). --> + <div style="display:table-row;"></div> +</div>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/selectors/focus-visible-005.html b/third_party/WebKit/LayoutTests/external/wpt/css/selectors/focus-visible-005.html index 706bd1e..b5d5843 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/selectors/focus-visible-005.html +++ b/third_party/WebKit/LayoutTests/external/wpt/css/selectors/focus-visible-005.html
@@ -7,15 +7,17 @@ <link rel="help" href="https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo" /> <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> <style> :focus-visible { - outline: darkgreen dotted 1px; /* fallback for Edge */ - outline: darkgreen auto 5px; + outline: red dotted 1px; /* fallback for Edge */ + outline: red auto 5px; } :focus:not(:focus-visible) { outline: 0; - background-color: tomato; + background-color: darkseagreen; } </style> </head> @@ -34,12 +36,12 @@ el.focus(); }); async_test(function(t) { - el.addEventListener("focus", t.step_func(() => { - assert_equals(getComputedStyle(el).outlineColor, "rgb(0, 100, 0)"); + el.addEventListener("focus", t.step_func(function() { + assert_equals(getComputedStyle(el).outlineStyle, "none"); t.done(); })); - el.focus(); - }, "Programmatic focus should always match :focus-visible"); + test_driver.click(button); + }, "Programmatic focus after click should not match :focus-visible"); </script> </body> </html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/selectors/focus-visible-008.html b/third_party/WebKit/LayoutTests/external/wpt/css/selectors/focus-visible-008.html new file mode 100644 index 0000000..b7f61d2f --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/selectors/focus-visible-008.html
@@ -0,0 +1,44 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="utf-8" /> + <title>CSS Test (Selectors): Keyboard focus enables :focus-visible</title> + <link rel="author" title="Alice Boxhall" href="aboxhall@chromium.org" /> + <link rel="help" href="https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo" /> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <style> + :focus-visible { + outline: darkgreen auto 5px; + } + + #el:focus:not(:focus-visible) { + background-color: tomato;; + outline: 0; + } + </style> +</head> +<body> + This test checks that programmatically focusing an element after a keypress causes <code>:focus-visible</code> to match. + <ol id="instructions"> + <li>Use the tab key to move focus to the button below that says "Tab to me and press ENTER."</li> + <li>Press ENTER.</li> + <li>If the element that says "I will be focused programmatically." has a red background, then the test result is FAILURE. If the element has a green outline, then the test result is SUCCESS.</li> + </ol> + <br /> + <button id="button">Tab to me and press ENTER.</button> + <div id="el" tabindex="-1">I will be focused programmatically.</el> + <script> + button.addEventListener("click", () => { + el.focus(); + }); + async_test(function(t) { + el.addEventListener("focus", t.step_func(function() { + assert_equals(getComputedStyle(el).outlineColor, "rgb(0, 100, 0)"); + t.done(); + })); + el.focus(); + }, "Programmatic focus after keypress should match :focus-visible"); + </script> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/selectors/focus-visible-009.html b/third_party/WebKit/LayoutTests/external/wpt/css/selectors/focus-visible-009.html new file mode 100644 index 0000000..c7d682ba --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/selectors/focus-visible-009.html
@@ -0,0 +1,44 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="utf-8" /> + <title>CSS Test (Selectors): Keyboard focus enables :focus-visible</title> + <link rel="author" title="Alice Boxhall" href="aboxhall@chromium.org" /> + <link rel="help" href="https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo" /> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <style> + :focus-visible { + outline: darkgreen auto 5px; + } + + #button:focus:not(:focus-visible) { + background-color: tomato;; + outline: 0; + } + </style> +</head> +<body> + This test checks that any element focused via an <code>autofocus</code> attribute will have <code>:focus-visible</code> matching enabled. + <ul id="instructions"> + <li>If the button that says "I will be focused automatically" has a red background, then the test result is FAILURE. If it has a green outline, then the test result is SUCCESS.</li> + </ul> + <br /> + <button id="button" autofocus tabindex="-1">I will be focused automatically.</button> + <script> + async_test(function(t) { + button.addEventListener("focus", t.step_func(function() { + assert_equals(getComputedStyle(button).outlineColor, "rgb(0, 100, 0)"); + t.done(); + })); + + // Handle the case where the button is focused before the test runs. + if (document.activeButtonement === button) { + assert_equals(getComputedStyle(button).outlineColor, "rgb(0, 100, 0)"); + t.done(); + } + + }, "Autofocus should match :focus-visible"); + </script> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/selectors/focus-visible-010.html b/third_party/WebKit/LayoutTests/external/wpt/css/selectors/focus-visible-010.html new file mode 100644 index 0000000..eb01204b --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/selectors/focus-visible-010.html
@@ -0,0 +1,41 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="utf-8" /> + <title>CSS Test (Selectors): Keyboard focus enables :focus-visible</title> + <link rel="author" title="Alice Boxhall" href="aboxhall@chromium.org" /> + <link rel="help" href="https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo" /> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <style> + :focus-visible { + outline: darkgreen auto 5px; + } + + :focus:not(:focus-visible) { + background-color: tomato; + outline: 0; + } + </style> +</head> +<body> + This test checks that any element focused programmatically on page load will have <code>:focus-visible</code> matching enabled. + <ul id="instructions"> + <li>If the element that says "I will be focused automatically" has a red background, then the test result is FAILURE. If the element has a green outline, then the test result is SUCCESS.</li> + </ul> + <br /> + <div id="el" tabindex="-1">I will be focused automatically.</el> + <script> + window.addEventListener('load', () => { + el.focus(); + }); + + async_test(function(t) { + el.addEventListener("focus", t.step_func(function() { + assert_equals(getComputedStyle(el).outlineColor, "rgb(0, 100, 0)"); + t.done(); + })); + }, "Programmatic focus on page load bshould match :focus-visible"); + </script> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/svg/historical.html b/third_party/WebKit/LayoutTests/external/wpt/svg/historical.html index 4b8686b..1b73ca8 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/svg/historical.html +++ b/third_party/WebKit/LayoutTests/external/wpt/svg/historical.html
@@ -12,6 +12,7 @@ "SVGICCColor", "SVGLangSpace", "SVGLocatable", + "SVGTransformable", "SVGPaint", "SVGPathSeg", "SVGStylable",
diff --git a/third_party/WebKit/LayoutTests/external/wpt/svg/types/elements/SVGGeometryElement-rect-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/svg/types/elements/SVGGeometryElement-rect-expected.txt new file mode 100644 index 0000000..5594cfb2 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/svg/types/elements/SVGGeometryElement-rect-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +PASS getTotalLength and getPointAtLength do not take pathLength into account +FAIL getPointAtLength() returns instance of DOMPoint assert_true: expected true got false +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/svg/types/elements/SVGGeometryElement-rect.svg b/third_party/WebKit/LayoutTests/external/wpt/svg/types/elements/SVGGeometryElement-rect.svg index 5391d91a..d4b278f 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/svg/types/elements/SVGGeometryElement-rect.svg +++ b/third_party/WebKit/LayoutTests/external/wpt/svg/types/elements/SVGGeometryElement-rect.svg
@@ -14,9 +14,9 @@ <h:script src="/resources/testharness.js"/> <h:script src="/resources/testharnessreport.js"/> <script><![CDATA[ - test(function() { - var box = document.getElementById('box'); + var box = document.getElementById('box'); + test(function() { assert_equals(box.pathLength.baseVal, 6); assert_equals(box.getTotalLength(), 600); @@ -24,5 +24,9 @@ assert_equals(box.getPointAtLength(210).x, 250); assert_equals(box.getPointAtLength(210).y, 60); }, 'getTotalLength and getPointAtLength do not take pathLength into account'); + + test(function() { + assert_true(box.getPointAtLength(210) instanceof DOMPoint); + }, 'getPointAtLength() returns instance of DOMPoint'); ]]></script> </svg>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGAnimatedRect-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGAnimatedRect-expected.txt new file mode 100644 index 0000000..cdc41ca --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGAnimatedRect-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL SVGAnimatedRect interface - utilizing the viewBox property of SVGSVGElement assert_true: expected true got false +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGAnimatedRect.html b/third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGAnimatedRect.html index 011f44ee..eb5bb1db 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGAnimatedRect.html +++ b/third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGAnimatedRect.html
@@ -10,8 +10,9 @@ // Check initial viewBox value. assert_true(svgElement.viewBox instanceof SVGAnimatedRect); - assert_true(svgElement.viewBox.baseVal instanceof SVGRect); + assert_true(svgElement.viewBox.baseVal instanceof DOMRect); assert_equals(svgElement.viewBox.baseVal.x, 0); + assert_true(svgElement.viewBox.animVal instanceof DOMRectReadOnly); // Check that rects are dynamic, caching value in a local variable and modifying it, should take effect. var numRef = svgElement.viewBox.baseVal; @@ -28,6 +29,6 @@ assert_equals(svgElement.viewBox.baseVal.x, 100); // Check that the viewBox baseVal type has not been changed. - assert_true(svgElement.viewBox.baseVal instanceof SVGRect); + assert_true(svgElement.viewBox.baseVal instanceof DOMRect); }); </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGGraphicsElement-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGGraphicsElement-expected.txt new file mode 100644 index 0000000..402bbd5e --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGGraphicsElement-expected.txt
@@ -0,0 +1,6 @@ +This is a testharness.js-based test. +FAIL getBBox() returns instance of DOMRect assert_true: expected true got false +FAIL getCTM() returns instance of DOMMatrix assert_true: expected true got false +FAIL getScreenCTM() returns instance of DOMMatrix assert_true: expected true got false +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGGraphicsElement.svg b/third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGGraphicsElement.svg new file mode 100644 index 0000000..8d5808f0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/svg/types/scripted/SVGGraphicsElement.svg
@@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg xmlns="http://www.w3.org/2000/svg" + xmlns:h="http://www.w3.org/1999/xhtml"> + <title>SVGGraphicsElement</title> + <metadata> + <h:link rel="help" href="https://svgwg.org/svg2-draft/types.html#InterfaceSVGGraphicsElement"/> + </metadata> + <h:script src="/resources/testharness.js"/> + <h:script src="/resources/testharnessreport.js"/> + <script><![CDATA[ + var el = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + + test(function() { + assert_true(el.getBBox() instanceof DOMRect); + }, 'getBBox() returns instance of DOMRect'); + + test(function() { + assert_true(el.getCTM() instanceof DOMMatrix); + }, 'getCTM() returns instance of DOMMatrix'); + + test(function() { + assert_true(el.getScreenCTM() instanceof DOMMatrix); + }, 'getScreenCTM() returns instance of DOMMatrix'); + ]]></script> +</svg>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-animations/META.yml b/third_party/WebKit/LayoutTests/external/wpt/web-animations/META.yml index 43195c1..45d0266b 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/web-animations/META.yml +++ b/third_party/WebKit/LayoutTests/external/wpt/web-animations/META.yml
@@ -1,2 +1,5 @@ suggested_reviewers: - birtles + - flackr + - graouts + - stephenmcgruer
diff --git a/third_party/WebKit/LayoutTests/fast/scrolling/scrollbar-mousedown-move-mouseup-expected.txt b/third_party/WebKit/LayoutTests/fast/scrolling/scrollbar-mousedown-move-mouseup-expected.txt deleted file mode 100644 index bf57267..0000000 --- a/third_party/WebKit/LayoutTests/fast/scrolling/scrollbar-mousedown-move-mouseup-expected.txt +++ /dev/null
@@ -1,12 +0,0 @@ -This is a scrollable div. - -PASS events['scrollme'].length is 2 -PASS events['notscrollme'].length is 0 -PASS events['scrollme'][0].type is "mousedown" -PASS events['scrollme'][0].which is 1 -PASS events['scrollme'][1].type is "mouseup" -PASS events['scrollme'][1].which is 1 -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/fast/scrolling/scrollbar-mousedown-move-mouseup.html b/third_party/WebKit/LayoutTests/fast/scrolling/scrollbar-mousedown-move-mouseup.html index 5f9538f..b0e8d4e1 100644 --- a/third_party/WebKit/LayoutTests/fast/scrolling/scrollbar-mousedown-move-mouseup.html +++ b/third_party/WebKit/LayoutTests/fast/scrolling/scrollbar-mousedown-move-mouseup.html
@@ -1,63 +1,83 @@ <!DOCTYPE html> -<html> -<head> - <script src="../../resources/js-test.js"></script> - <script> - window.jsTestIsAsync = true; +<script src='../../resources/testharness.js'></script> +<script src='../../resources/testharnessreport.js'></script> +<script src='../../resources/gesture-util.js'></script> - function initEventHandlers(element) { - element.addEventListener('mousedown', handleEvent); - element.addEventListener('mouseup', handleEvent); - } +<style> + #scrollme, + #notscrollme { + width: 100px; + height: 100px; + overflow: auto; + } - window.events = { - 'scrollme': [], - 'notscrollme': [] - }; - function handleEvent(e) { - window.events[e.target.id].push(e); - } + #scrollme p { + height: 1000px; + } +</style> - function finish() { - shouldBe("events['scrollme'].length", "2"); - shouldBe("events['notscrollme'].length", "0"); - shouldBeEqualToString("events['scrollme'][0].type", "mousedown"); - shouldBe("events['scrollme'][0].which", "1"); - shouldBeEqualToString("events['scrollme'][1].type", "mouseup"); - shouldBe("events['scrollme'][1].which", "1"); - finishJSTest(); - } +<div id='scrollme'> + <p>This is a scrollable div.</p> +</div> +<div id='notscrollme'></div> - window.onload = function () { - var d1 = document.querySelector('#scrollme'); - var d2 = document.querySelector('#notscrollme'); - initEventHandlers(d1); - initEventHandlers(d2); +<script> + function initEventHandlers(element) { + element.addEventListener('mousedown', handleEvent); + element.addEventListener('mouseup', handleEvent); + } - if (window.eventSender) { - eventSender.mouseMoveTo(d1.offsetLeft + d1.offsetWidth - 4, d1.offsetTop + 4); - eventSender.mouseDown(); - eventSender.mouseMoveTo(d2.offsetLeft + d2.offsetWidth - 4, d2.offsetTop + 4); - eventSender.mouseUp(); - finish(); - } else - debug('This test requires eventSender. Click the scrollbar to play manually.'); - }; - </script> - <style> - #scrollme, #notscrollme { - width: 100px; - height: 100px; - overflow: auto; - } - #scrollme p { - height: 1000px; - } - </style> -</head> -<body> - <div id="scrollme"><p>This is a scrollable div.</p></div> - <div id="notscrollme"></div> - <pre id="console"></pre> -</body> -</html> + window.events = { + 'scrollme': [], + 'notscrollme': [] + }; + + function handleEvent(e) { + window.events[e.target.id].push(e); + } + + window.onload = async () => { + let d1 = document.querySelector('#scrollme'); + let d2 = document.querySelector('#notscrollme'); + + initEventHandlers(d1); + initEventHandlers(d2); + + internals.settings.setScrollAnimatorEnabled(false); + + promise_test(async () => { + await waitForCompositorCommit(); + await mouseDragAndDrop(d1.offsetLeft + d1.offsetWidth - 4, + d1.offsetTop + 30, + d2.offsetLeft + d2.offsetWidth - 4, + d2.offsetTop + 4); + await waitFor(() => { return events['scrollme'].length == 2; }); + + assert_greater_than(d1.scrollTop, 0); + assert_equals(d2.scrollTop, 0); + assert_equals(events['notscrollme'].length, 0); + assert_equals(events['scrollme'][0].type, 'mousedown'); + assert_equals(events['scrollme'][0].which, 1); + assert_equals(events['scrollme'][1].type, 'mouseup'); + assert_equals(events['scrollme'][1].which, 1); + + d1.scrollTop = 0; + await waitForCompositorCommit(); + await mouseDragAndDrop(d1.offsetLeft + d1.offsetWidth - 4, + d1.offsetTop + 30, + d2.offsetLeft + d2.offsetWidth - 4, + d2.offsetTop + 4, + 'middle'); + await waitFor(() => { return events['scrollme'].length == 4; }); + + assert_greater_than(d1.scrollTop, 0); + assert_equals(d2.scrollTop, 0); + assert_equals(events['notscrollme'].length, 0); + assert_equals(events['scrollme'][2].type, 'mousedown'); + assert_equals(events['scrollme'][2].which, 2); + assert_equals(events['scrollme'][3].type, 'mouseup'); + assert_equals(events['scrollme'][3].which, 2); + }, 'Drag a scrollbar and release it on another DIV, only the DIV owns the' + + ' dragging scrollbar receive mouse events'); + } +</script> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/display-table-text-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/display-table-text-expected.png new file mode 100644 index 0000000..14f18c4 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/display-table-text-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/display-table-text-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/display-table-text-expected.txt new file mode 100644 index 0000000..3a76e20 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/editing/selection/display-table-text-expected.txt
@@ -0,0 +1,14 @@ +EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutNGBlockFlow {HTML} at (0,0) size 800x600 + LayoutNGBlockFlow {BODY} at (8,8) size 784x584 + LayoutTable {DIV} at (0,0) size 348x20 + LayoutTableSection (anonymous) at (0,0) size 348x20 + LayoutTableRow (anonymous) at (0,0) size 348x20 + LayoutNGTableCell (anonymous) at (0,0) size 348x20 [r=0 c=0 rs=1 cs=1] + LayoutText {#text} at (0,0) size 348x19 + text run at (0,0) width 348: "Only the third word in this sentence should be selected." +selection start: position 9 of child 0 {#text} of child 1 {DIV} of body +selection end: position 14 of child 0 {#text} of child 1 {DIV} of body
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/gradients/list-item-gradient-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/gradients/list-item-gradient-expected.png new file mode 100644 index 0000000..db8d852d --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/gradients/list-item-gradient-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/gradients/list-item-gradient-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/gradients/list-item-gradient-expected.txt new file mode 100644 index 0000000..ff92490 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/gradients/list-item-gradient-expected.txt
@@ -0,0 +1,21 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutNGBlockFlow {HTML} at (0,0) size 800x600 + LayoutNGBlockFlow {BODY} at (8,8) size 784x576 + LayoutNGBlockFlow {UL} at (0,0) size 784x60 + LayoutNGListItem {LI} at (40,0) size 744x20 + LayoutNGListMarker (anonymous) at (-14.50,7.50) size 7.50x7.50 + LayoutImage (anonymous) at (0,0) size 7.50x7.50 + LayoutText {#text} at (0,0) size 59x19 + text run at (0,0) width 59: "Item One" + LayoutNGListItem {LI} at (40,20) size 744x20 + LayoutNGListMarker (anonymous) at (-14.50,7.50) size 7.50x7.50 + LayoutImage (anonymous) at (0,0) size 7.50x7.50 + LayoutText {#text} at (0,0) size 61x19 + text run at (0,0) width 61: "Item Two" + LayoutNGListItem {LI} at (40,40) size 744x20 + LayoutNGListMarker (anonymous) at (-14.50,7.50) size 7.50x7.50 + LayoutImage (anonymous) at (0,0) size 7.50x7.50 + LayoutText {#text} at (0,0) size 69x19 + text run at (0,0) width 69: "Item Three"
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/gradients/unprefixed-list-item-gradient-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/gradients/unprefixed-list-item-gradient-expected.png new file mode 100644 index 0000000..5419680 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/gradients/unprefixed-list-item-gradient-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/table/css-table-max-height-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/table/css-table-max-height-expected.txt new file mode 100644 index 0000000..ad62cae --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/table/css-table-max-height-expected.txt
@@ -0,0 +1,38 @@ +Testcase for Bug http://wkbug.com/98633. The testcase checks if the height of a css table does not exceed the max-height value. The height of the table can be greater than max-height value when either min-height is greater than max-height or computed height of the content is greater than the max-height. + +This sub-test checks that when min-height is lesser than max-height, max-height is applied to a table with auto layout. +PASS +This sub-test checks that when min-height is greater than max-height, min-height is applied to a table with auto layout. +PASS +This sub-test checks that max-height with fixed value is applied to a table with auto layout. +PASS +This sub-test checks that max-height with percent value is applied to a table with auto layout. +PASS +This sub-test checks that max-height with viewport percent height value is applied to a table with auto layout. +PASS +This sub-test checks that max-height with viewport percent width value is applied to a table with auto layout. +PASS +This sub-test checks that when content height is greater than max-height, content height is applied to the table with auto layout. + +FILLER TEXT TO INCREASE CONTENT HEIGHT. +PASS +This test checks that when height of an auto-table is auto, there is are no asserts. No crash means the test passed. +PASS +This sub-test checks that when min-height is lesser than max-height, max-height is applied to a table with fixed layout. +PASS +This sub-test checks that when min-height is greater than max-height, min-height is applied to a table with fixed layout. +PASS +This sub-test checks that max-height with fixed value is applied to a table with fixed layout. +PASS +This sub-test checks that max-height with percent value is applied to a table with fixed layout. +PASS +This sub-test checks that max-height with viewport percent height value is applied to a table with fixed layout. +PASS +This sub-test checks that max-height with viewport percent width value is applied to a table with fixed layout. +PASS +This sub-test checks that when content height is greater than max-height, content height is applied to a table with fixed layout. + +FILLER TEXT TO INCREASE CONTENT HEIGHT. +PASS +This test checks that when height of a fixed table is auto, there is are no asserts. No crash means the test passed. +PASS
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/table/quote-text-around-iframe-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/table/quote-text-around-iframe-expected.png new file mode 100644 index 0000000..345005c --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/table/quote-text-around-iframe-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/table/quote-text-around-iframe-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/table/quote-text-around-iframe-expected.txt new file mode 100644 index 0000000..54dc01cc --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/table/quote-text-around-iframe-expected.txt
@@ -0,0 +1,28 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x349 + LayoutNGBlockFlow {HTML} at (0,0) size 800x349 + LayoutNGBlockFlow {BODY} at (16,16) size 768x317 + LayoutTable (anonymous) at (0,0) size 694x317 + LayoutTableSection (anonymous) at (0,0) size 694x317 + LayoutTableRow {Q} at (0,0) size 694x317 + LayoutNGTableCell (anonymous) at (0,0) size 694x317 [r=0 c=0 rs=1 cs=1] + LayoutInline {<pseudo:before>} at (0,0) size 13x36 + LayoutQuote (anonymous) at (0,0) size 13x36 + LayoutTextFragment (anonymous) at (0,280) size 13x36 + text run at (0,280) width 13: "\"" + LayoutText {#text} at (13,280) size 29x36 + text run at (13,280) width 29: " A" + LayoutText {#text} at (650,280) size 29x36 + text run at (650,280) width 29: "B " + LayoutInline {<pseudo:after>} at (0,0) size 13x36 + LayoutQuote (anonymous) at (0,0) size 13x36 + LayoutTextFragment (anonymous) at (679,280) size 13x36 + text run at (679,280) width 13: "\"" +layer at (58,16) size 608x308 + LayoutIFrame {IFRAME} at (42,0) size 608x308 [border: (4px inset #EEEEEE)] + layer at (0,0) size 600x300 + LayoutView at (0,0) size 600x300 + layer at (0,0) size 600x300 + LayoutNGBlockFlow {HTML} at (0,0) size 600x300 + LayoutNGBlockFlow {BODY} at (8,8) size 584x284
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/table/section-in-table-before-misnested-text-crash-css-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/table/section-in-table-before-misnested-text-crash-css-expected.txt new file mode 100644 index 0000000..9036ca1 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/table/section-in-table-before-misnested-text-crash-css-expected.txt
@@ -0,0 +1,4 @@ +This test checks whether a particular odd arrangement of DOM nodes results in render tree consistency violations. +0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99xxx +Whee +QQQ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/table/section-in-table-before-misnested-text-crash-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/table/section-in-table-before-misnested-text-crash-expected.txt new file mode 100644 index 0000000..9036ca1 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/fast/table/section-in-table-before-misnested-text-crash-expected.txt
@@ -0,0 +1,4 @@ +This test checks whether a particular odd arrangement of DOM nodes results in render tree consistency violations. +0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99xxx +Whee +QQQ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/selection/text-selection-rect-in-overflow-2-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/selection/text-selection-rect-in-overflow-2-expected.png new file mode 100644 index 0000000..7fe2482 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/selection/text-selection-rect-in-overflow-2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/selection/text-selection-rect-in-overflow-2-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/selection/text-selection-rect-in-overflow-2-expected.txt new file mode 100644 index 0000000..3274248 --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/paint/invalidation/selection/text-selection-rect-in-overflow-2-expected.txt
@@ -0,0 +1,35 @@ +{ + "layers": [ + { + "name": "LayoutView #document", + "bounds": [800, 600], + "drawsContent": false, + "backgroundColor": "#FFFFFF" + }, + { + "name": "Scrolling Layer", + "bounds": [800, 600], + "drawsContent": false + }, + { + "name": "Scrolling Contents Layer", + "bounds": [800, 600], + "contentsOpaque": true, + "backgroundColor": "#FFFFFF", + "paintInvalidations": [ + { + "object": "NGPaintFragment", + "rect": [18, 18, 234, 20], + "reason": "selection" + } + ] + } + ], + "objectPaintInvalidations": [ + { + "object": "NGPaintFragment", + "reason": "selection" + } + ] +} +
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug2479-2-expected.png b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug2479-2-expected.png new file mode 100644 index 0000000..cd2ca26f --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug2479-2-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug2479-2-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug2479-2-expected.txt new file mode 100644 index 0000000..bd0966c --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/enable-blink-features=LayoutNG/tables/mozilla/bugs/bug2479-2-expected.txt
@@ -0,0 +1,114 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x553 + LayoutNGBlockFlow {HTML} at (0,0) size 800x553 + LayoutNGBlockFlow {BODY} at (57,64) size 686x425 [bgcolor=#99FFCC] [border: (3px solid #000000)] + LayoutNGBlockFlow {P} at (3,3) size 680x64 + LayoutText {#text} at (0,7) size 679x50 + text run at (0,7) width 679: "These links are in an element with display table-row, and the li elements have display: table-cell." + text run at (0,39) width 115: "They disappear:" + LayoutTable (anonymous) at (3,67) size 264x19 + LayoutTableSection (anonymous) at (0,0) size 264x19 + LayoutTableRow {UL} at (0,0) size 264x19 [bgcolor=#00CC99] + LayoutNGTableCell {LI} at (0,0) size 66x19 [r=0 c=0 rs=1 cs=1] + LayoutInline {A} at (0,0) size 50x18 [color=#0000EE] + LayoutText {#text} at (8,0) size 50x18 + text run at (8,0) width 50: "people" + LayoutNGTableCell {LI} at (66,0) size 66x19 [r=0 c=1 rs=1 cs=1] + LayoutInline {A} at (0,0) size 48x18 [color=#0000EE] + LayoutText {#text} at (9,0) size 48x18 + text run at (9,0) width 48: "places" + LayoutNGTableCell {LI} at (132,0) size 66x19 [r=0 c=2 rs=1 cs=1] + LayoutInline {A} at (0,0) size 66x18 [color=#0000EE] + LayoutText {#text} at (0,0) size 66x18 + text run at (0,0) width 66: "members" + LayoutNGTableCell {LI} at (198,0) size 66x19 [r=0 c=3 rs=1 cs=1] + LayoutInline {A} at (0,0) size 34x18 [color=#0000EE] + LayoutText {#text} at (16,0) size 34x18 + text run at (16,0) width 34: "links" + LayoutNGBlockFlow {DIV} at (3,86) size 680x336 + LayoutNGBlockFlow (anonymous) at (16,16) size 648x19 + LayoutText {#text} at (0,0) size 434x18 + text run at (0,0) width 434: "This text is not in the form. The form should be indented 40px." + LayoutNGBlockFlow {FORM} at (96,35) size 568x285 + LayoutNGBlockFlow {P} at (0,0) size 568x64 + LayoutText {#text} at (0,7) size 556x50 + text run at (0,7) width 556: "This is text in the form. It should be indented 40px. The form itself has the same" + text run at (0,39) width 270: "table-row/table-cell problem as above." + LayoutNGBlockFlow {P} at (0,64) size 568x63 + LayoutTable {SPAN} at (0,3) size 149x60 + LayoutTableSection (anonymous) at (0,0) size 149x60 + LayoutTableRow {SPAN} at (0,0) size 149x28 + LayoutNGTableCell (anonymous) at (0,0) size 149x28 [r=0 c=0 rs=1 cs=1] + LayoutText {#text} at (0,6) size 137x16 + text run at (0,6) width 137: "First Name (required)" + LayoutTableRow (anonymous) at (0,28) size 149x32 + LayoutNGTableCell (anonymous) at (0,28) size 149x32 [r=1 c=0 rs=1 cs=1] + LayoutTextControl {INPUT} at (0,6) size 149x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] + LayoutText {#text} at (149,7) size 4x18 + text run at (149,7) width 4: " " + LayoutTable {SPAN} at (153,3) size 149x60 + LayoutTableSection (anonymous) at (0,0) size 149x60 + LayoutTableRow {SPAN} at (0,0) size 149x28 + LayoutNGTableCell (anonymous) at (0,0) size 149x28 [r=0 c=0 rs=1 cs=1] + LayoutText {#text} at (0,6) size 136x16 + text run at (0,6) width 136: "Last Name (required)" + LayoutTableRow (anonymous) at (0,28) size 149x32 + LayoutNGTableCell (anonymous) at (0,28) size 149x32 [r=1 c=0 rs=1 cs=1] + LayoutTextControl {INPUT} at (0,6) size 149x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] + LayoutText {#text} at (0,0) size 0x0 + LayoutNGBlockFlow {P} at (0,127) size 568x63 + LayoutTable {SPAN} at (0,3) size 341x60 + LayoutTableSection (anonymous) at (0,0) size 341x60 + LayoutTableRow {SPAN} at (0,0) size 341x28 + LayoutNGTableCell (anonymous) at (0,0) size 341x28 [r=0 c=0 rs=1 cs=1] + LayoutText {#text} at (0,6) size 90x16 + text run at (0,6) width 90: "Email Address" + LayoutTableRow (anonymous) at (0,28) size 341x32 + LayoutNGTableCell (anonymous) at (0,28) size 341x32 [r=1 c=0 rs=1 cs=1] + LayoutTextControl {INPUT} at (0,6) size 341x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] + LayoutText {#text} at (0,0) size 0x0 + LayoutNGBlockFlow {P} at (0,190) size 568x63 + LayoutTable {SPAN} at (0,3) size 149x60 + LayoutTableSection (anonymous) at (0,0) size 149x60 + LayoutTableRow {SPAN} at (0,0) size 149x28 + LayoutNGTableCell (anonymous) at (0,0) size 149x28 [r=0 c=0 rs=1 cs=1] + LayoutText {#text} at (0,6) size 103x16 + text run at (0,6) width 103: "Company Name" + LayoutTableRow (anonymous) at (0,28) size 149x32 + LayoutNGTableCell (anonymous) at (0,28) size 149x32 [r=1 c=0 rs=1 cs=1] + LayoutTextControl {INPUT} at (0,6) size 149x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] + LayoutText {#text} at (149,7) size 4x18 + text run at (149,7) width 4: " " + LayoutTable {SPAN} at (153,3) size 149x60 + LayoutTableSection (anonymous) at (0,0) size 149x60 + LayoutTableRow {SPAN} at (0,0) size 149x28 + LayoutNGTableCell (anonymous) at (0,0) size 149x28 [r=0 c=0 rs=1 cs=1] + LayoutText {#text} at (0,6) size 26x16 + text run at (0,6) width 26: "Title" + LayoutTableRow (anonymous) at (0,28) size 149x32 + LayoutNGTableCell (anonymous) at (0,28) size 149x32 [r=1 c=0 rs=1 cs=1] + LayoutTextControl {INPUT} at (0,6) size 149x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)] + LayoutText {#text} at (0,0) size 0x0 + LayoutNGBlockFlow {P} at (0,253) size 568x32 + LayoutButton {INPUT} at (0,6) size 61x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)] + LayoutBlockFlow (anonymous) at (8,3) size 45x16 + LayoutText {#text} at (0,0) size 45x16 + text run at (0,0) width 45: "Submit!" + LayoutText {#text} at (61,7) size 4x18 + text run at (61,7) width 4: " " + LayoutButton {INPUT} at (65,6) size 80x22 [bgcolor=#C0C0C0] [border: (2px outset #C0C0C0)] + LayoutBlockFlow (anonymous) at (8,3) size 64x16 + LayoutText {#text} at (0,0) size 64x16 + text run at (0,0) width 64: "Clear Form" + LayoutText {#text} at (0,0) size 0x0 +layer at (158,289) size 145x16 + LayoutBlockFlow {DIV} at (2,3) size 145x16 +layer at (311,289) size 145x16 + LayoutBlockFlow {DIV} at (2,3) size 145x16 +layer at (158,352) size 337x16 + LayoutBlockFlow {DIV} at (2,3) size 337x16 +layer at (158,415) size 145x16 + LayoutBlockFlow {DIV} at (2,3) size 145x16 +layer at (311,415) size 145x16 + LayoutBlockFlow {DIV} at (2,3) size 145x16
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/postMessage/target-origin-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/postMessage/target-origin-expected.txt index 58360e77..a04f62c 100644 --- a/third_party/WebKit/LayoutTests/http/tests/security/postMessage/target-origin-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/security/postMessage/target-origin-expected.txt
@@ -1,8 +1,8 @@ window.location.href = http://127.0.0.1:8000/security/postMessage/target-origin.html waiting... -Error sending message to null. SyntaxError: Failed to execute 'postMessage' on 'Window': Invalid target origin '' in a call to 'postMessage'. -Error sending message to undefined. SyntaxError: Failed to execute 'postMessage' on 'Window': Invalid target origin '' in a call to 'postMessage'. +Error sending message to null. SyntaxError: Failed to execute 'postMessage' on 'Window': Invalid target origin 'null' in a call to 'postMessage'. +Error sending message to undefined. SyntaxError: Failed to execute 'postMessage' on 'Window': Invalid target origin 'undefined' in a call to 'postMessage'. Error sending message to //. SyntaxError: Failed to execute 'postMessage' on 'Window': Invalid target origin '//' in a call to 'postMessage'. Received message: data="Received message: data="Trying origin=*" origin="http://127.0.0.1:8000"" origin="http://localhost:8000" Received message: data="Received message: data="Trying origin=/" origin="http://127.0.0.1:8000"" origin="http://127.0.0.1:8000"
diff --git a/third_party/WebKit/LayoutTests/media/controls/modern/overflow-button-disabled-no-source.html b/third_party/WebKit/LayoutTests/media/controls/modern/overflow-button-disabled-no-source.html index 27d1daa..53d40dc9 100644 --- a/third_party/WebKit/LayoutTests/media/controls/modern/overflow-button-disabled-no-source.html +++ b/third_party/WebKit/LayoutTests/media/controls/modern/overflow-button-disabled-no-source.html
@@ -4,21 +4,21 @@ <script src="../../../resources/testharness.js"></script> <script src="../../../resources/testharnessreport.js"></script> <script src="../../media-controls.js"></script> -<video controls width=400 controlsList=nodownload></video> +<video controls width=400 controlsList=nodownload disablePictureInPicture></video> <script> async_test(t => { const video = document.querySelector('video'); // Make sure the button is visible and disabled. assert_true(overflowButton(video).disabled); - assert_equals('', overflowButton(video).style.display); + assert_equals(overflowButton(video).style.display, ''); // Set the source and start playing. video.src = '../../content/60_sec_video.webm'; video.play().then(t.step_func_done(() => { // Make sure the button has been hidden and is no longer disabled. assert_false(overflowButton(video).disabled); - assert_equals('none', overflowButton(video).style.display); + assert_equals(overflowButton(video).style.display, 'none'); }), t.unreached_func()); }); </script>
diff --git a/third_party/WebKit/LayoutTests/media/controls/overflow-menu-keyboard-navigation.html b/third_party/WebKit/LayoutTests/media/controls/overflow-menu-keyboard-navigation.html index 53904b2c..eb635c3f 100644 --- a/third_party/WebKit/LayoutTests/media/controls/overflow-menu-keyboard-navigation.html +++ b/third_party/WebKit/LayoutTests/media/controls/overflow-menu-keyboard-navigation.html
@@ -78,6 +78,9 @@ const elements = [ menu.lastElementChild, menu.lastElementChild.previousSibling ]; + if (document.pictureInPictureEnabled) + elements.push(menu.lastElementChild.previousSibling.previousSibling); + testNavigation(internals.shadowRoot(video), elements, () => { eventSender.keyDown('ArrowUp'); }, () => { eventSender.keyDown('ArrowDown'); });
diff --git a/third_party/WebKit/LayoutTests/media/controls/video-controls-overflow-menu-text.html b/third_party/WebKit/LayoutTests/media/controls/video-controls-overflow-menu-text.html index 32f3876..21c10b68 100644 --- a/third_party/WebKit/LayoutTests/media/controls/video-controls-overflow-menu-text.html +++ b/third_party/WebKit/LayoutTests/media/controls/video-controls-overflow-menu-text.html
@@ -19,7 +19,7 @@ internals.mediaPlayerRemoteRouteAvailabilityChanged(video, true); video.onloadeddata = t.step_func_done(function() { - var overflowList = getOverflowList(video); + var overflowList = getOverflowList(video); var children = overflowList.children; // Ensure that all of the buttons are visible in the right order for (var i = 0; i < children.length; i++) {
diff --git a/third_party/WebKit/LayoutTests/media/overflow-menu.js b/third_party/WebKit/LayoutTests/media/overflow-menu.js index 616f765..3f65dfa 100644 --- a/third_party/WebKit/LayoutTests/media/overflow-menu.js +++ b/third_party/WebKit/LayoutTests/media/overflow-menu.js
@@ -33,3 +33,6 @@ // Default text within the overflow menu var overflowMenuText = ["Play", "Fullscreen", "Download", "Mute", "Cast", "CaptionsOff"]; + +if (document.pictureInPictureEnabled) + overflowMenuText.push('Picture-in-Picture');
diff --git a/third_party/WebKit/LayoutTests/media/video-controls-overflow-menu-fullscreen-button.html b/third_party/WebKit/LayoutTests/media/video-controls-overflow-menu-fullscreen-button.html index f9a4e86..d5708b9 100644 --- a/third_party/WebKit/LayoutTests/media/video-controls-overflow-menu-fullscreen-button.html +++ b/third_party/WebKit/LayoutTests/media/video-controls-overflow-menu-fullscreen-button.html
@@ -7,7 +7,7 @@ <!--Padding ensures the overflow menu is visible for the tests. --> <body style="padding-top: 200px; padding-left: 100px"> -<video controls></video> +<video controls disablePictureInPicture></video> <script> async_test(function(t) { // Set up video
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-after-reload-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-after-reload-expected.png index ae694e3..1539890e 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-after-reload-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-after-reload-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-after-reload-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-after-reload-expected.txt index 1a25d65..b70da92 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-after-reload-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-after-reload-expected.txt
@@ -29,7 +29,8 @@ LayoutBlockFlow {DIV} at (51,0) size 39x48 [color=#FFFFFF] LayoutText {#text} at (0,15) size 39x18 text run at (0,15) width 39: "/ 0:06" - LayoutBlockFlow {DIV} at (90,48) size 134x0 + LayoutBlockFlow {DIV} at (90,48) size 86x0 + LayoutButton {INPUT} at (176,0) size 48x48 LayoutButton {INPUT} at (224,0) size 48x48 LayoutButton {INPUT} at (272,0) size 48x48 layer at (8,268) size 320x16
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-strict-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-strict-expected.png index 76b830a..68f2e707 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-strict-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-strict-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-strict-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-strict-expected.txt index 830bc45..b72e0eb9 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-strict-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-strict-expected.txt
@@ -29,7 +29,8 @@ LayoutBlockFlow {DIV} at (51,0) size 39x48 [color=#FFFFFF] LayoutText {#text} at (0,15) size 39x18 text run at (0,15) width 39: "/ 0:06" - LayoutBlockFlow {DIV} at (90,48) size 134x0 + LayoutBlockFlow {DIV} at (90,48) size 86x0 + LayoutButton {INPUT} at (176,0) size 48x48 LayoutButton {INPUT} at (224,0) size 48x48 LayoutButton {INPUT} at (272,0) size 48x48 layer at (8,276) size 320x16
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-styling-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-styling-expected.png index 688d91f..b10ac3a 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-styling-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-styling-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-styling-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-styling-expected.txt index 15a6206b7..171fd5e 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-styling-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-styling-expected.txt
@@ -33,7 +33,8 @@ LayoutBlockFlow {DIV} at (51,0) size 69x48 [color=#FFFFFF] LayoutText {#text} at (0,15) size 69x18 text run at (0,15) width 69: "/ 0:06" - LayoutBlockFlow {DIV} at (120,48) size 104x0 + LayoutBlockFlow {DIV} at (120,48) size 56x0 + LayoutButton {INPUT} at (176,0) size 48x48 LayoutButton {INPUT} at (224,0) size 48x48 LayoutButton {INPUT} at (272,0) size 48x48 layer at (18,268) size 320x16 @@ -68,7 +69,8 @@ LayoutBlockFlow {DIV} at (51,0) size 39x48 [color=#FFFFFF] LayoutText {#text} at (0,15) size 39x18 text run at (0,15) width 39: "/ 0:06" - LayoutBlockFlow {DIV} at (90,48) size 134x0 + LayoutBlockFlow {DIV} at (90,48) size 86x0 + LayoutButton {INPUT} at (176,0) size 48x48 LayoutButton {INPUT} at (224,0) size 48x48 LayoutButton {INPUT} at (272,0) size 48x48 layer at (8,508) size 320x16
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-styling-strict-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-styling-strict-expected.png index 394a004..c2831754 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-styling-strict-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-styling-strict-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-styling-strict-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-styling-strict-expected.txt index 3306805..fbb6577 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-styling-strict-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-styling-strict-expected.txt
@@ -33,7 +33,8 @@ LayoutBlockFlow {DIV} at (51,0) size 39x48 [color=#FFFFFF] LayoutText {#text} at (0,15) size 39x18 text run at (0,15) width 39: "/ 0:06" - LayoutBlockFlow {DIV} at (90,48) size 134x0 + LayoutBlockFlow {DIV} at (90,48) size 86x0 + LayoutButton {INPUT} at (176,0) size 48x48 LayoutButton {INPUT} at (224,0) size 48x48 LayoutButton {INPUT} at (272,0) size 48x48 layer at (8,276) size 320x16 @@ -68,7 +69,8 @@ LayoutBlockFlow {DIV} at (51,0) size 39x48 [color=#FFFFFF] LayoutText {#text} at (0,15) size 39x18 text run at (0,15) width 39: "/ 0:06" - LayoutBlockFlow {DIV} at (90,48) size 134x0 + LayoutBlockFlow {DIV} at (90,48) size 86x0 + LayoutButton {INPUT} at (176,0) size 48x48 LayoutButton {INPUT} at (224,0) size 48x48 LayoutButton {INPUT} at (272,0) size 48x48 layer at (332,276) size 320x16
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-without-preload-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-without-preload-expected.png index ea509a60..2f6e4572 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-without-preload-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-without-preload-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-without-preload-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-without-preload-expected.txt index 6f7d3f5..146f50e0 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-without-preload-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls-without-preload-expected.txt
@@ -29,7 +29,8 @@ LayoutBlockFlow {DIV} at (51,0) size 39x48 [color=#FFFFFF] LayoutText {#text} at (0,15) size 39x18 text run at (0,15) width 39: "/ 0:06" - LayoutBlockFlow {DIV} at (90,48) size 134x0 + LayoutBlockFlow {DIV} at (90,48) size 86x0 + LayoutButton {INPUT} at (176,0) size 48x48 LayoutButton {INPUT} at (224,0) size 48x48 LayoutButton {INPUT} at (272,0) size 48x48 layer at (8,268) size 320x16
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/lazy-loaded-style-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/lazy-loaded-style-expected.txt index 93f7b360..c17403e 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/lazy-loaded-style-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/lazy-loaded-style-expected.txt
@@ -25,7 +25,8 @@ LayoutBlockFlow {DIV} at (51,0) size 39x48 [color=#FFFFFF] LayoutText {#text} at (0,15) size 39x18 text run at (0,15) width 39: "/ 0:06" - LayoutBlockFlow {DIV} at (90,48) size 214x0 + LayoutBlockFlow {DIV} at (90,48) size 166x0 + LayoutButton {INPUT} at (256,0) size 48x48 LayoutButton {INPUT} at (304,0) size 48x48 LayoutButton {INPUT} at (352,0) size 48x48 layer at (8,292) size 400x16
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png index fee87dd9..1a5b4d7 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.txt index 21a7179..14df27b 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.txt
@@ -25,10 +25,11 @@ LayoutBlockFlow {DIV} at (51,0) size 39x48 [color=#FFFFFF] LayoutText {#text} at (0,15) size 39x18 text run at (0,15) width 39: "/ 0:09" - LayoutBlockFlow {DIV} at (90,48) size 214x0 + LayoutBlockFlow {DIV} at (90,48) size 166x0 + LayoutButton {INPUT} at (304,0) size 48x48 LayoutButton {INPUT} at (352,0) size 48x48 -layer at (312,271) size 48x48 transparent - LayoutButton {INPUT} at (304,0) size 48x48 [color=#808080] +layer at (264,271) size 48x48 transparent + LayoutButton {INPUT} at (256,0) size 48x48 [color=#808080] layer at (8,319) size 400x16 LayoutSlider {INPUT} at (0,311.27) size 400x16 [color=#9D968E] LayoutFlexibleBox {DIV} at (16,0) size 368x4
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-expected.png index fee87dd9..1a5b4d7 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-expected.txt index 21a7179..14df27b 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-expected.txt
@@ -25,10 +25,11 @@ LayoutBlockFlow {DIV} at (51,0) size 39x48 [color=#FFFFFF] LayoutText {#text} at (0,15) size 39x18 text run at (0,15) width 39: "/ 0:09" - LayoutBlockFlow {DIV} at (90,48) size 214x0 + LayoutBlockFlow {DIV} at (90,48) size 166x0 + LayoutButton {INPUT} at (304,0) size 48x48 LayoutButton {INPUT} at (352,0) size 48x48 -layer at (312,271) size 48x48 transparent - LayoutButton {INPUT} at (304,0) size 48x48 [color=#808080] +layer at (264,271) size 48x48 transparent + LayoutButton {INPUT} at (256,0) size 48x48 [color=#808080] layer at (8,319) size 400x16 LayoutSlider {INPUT} at (0,311.27) size 400x16 [color=#9D968E] LayoutFlexibleBox {DIV} at (16,0) size 368x4
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-controls-rendering-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-controls-rendering-expected.png index 4acbe8d..dba0a91 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-controls-rendering-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-controls-rendering-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-controls-rendering-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-controls-rendering-expected.txt index 83be889..dee9f38c 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-controls-rendering-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-controls-rendering-expected.txt
@@ -34,7 +34,8 @@ LayoutBlockFlow {DIV} at (51,0) size 39x48 [color=#FFFFFF] LayoutText {#text} at (0,15) size 39x18 text run at (0,15) width 39: "/ 0:06" - LayoutBlockFlow {DIV} at (90,48) size 134x0 + LayoutBlockFlow {DIV} at (90,48) size 86x0 + LayoutButton {INPUT} at (176,0) size 48x48 LayoutButton {INPUT} at (224,0) size 48x48 LayoutButton {INPUT} at (272,0) size 48x48 layer at (8,268) size 320x16 @@ -69,7 +70,8 @@ LayoutBlockFlow {DIV} at (51,0) size 39x48 [color=#FFFFFF] LayoutText {#text} at (0,15) size 39x18 text run at (0,15) width 39: "/ 0:06" - LayoutBlockFlow {DIV} at (90,48) size 134x0 + LayoutBlockFlow {DIV} at (90,48) size 86x0 + LayoutButton {INPUT} at (176,0) size 48x48 LayoutButton {INPUT} at (224,0) size 48x48 LayoutButton {INPUT} at (272,0) size 48x48 layer at (8,508) size 320x16 @@ -106,7 +108,8 @@ LayoutBlockFlow {DIV} at (51,0) size 39x48 [color=#FFFFFF] LayoutText {#text} at (0,15) size 39x18 text run at (0,15) width 39: "/ 0:06" - LayoutBlockFlow {DIV} at (90,48) size 134x0 + LayoutBlockFlow {DIV} at (90,48) size 86x0 + LayoutButton {INPUT} at (176,0) size 48x48 LayoutButton {INPUT} at (224,0) size 48x48 LayoutButton {INPUT} at (272,0) size 48x48 layer at (8,748) size 320x16 backgroundClip at (8,524) size 320x76 clip at (8,524) size 320x76
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-display-toggle-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-display-toggle-expected.png index c383bc1..5d8056c 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-display-toggle-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-display-toggle-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-display-toggle-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-display-toggle-expected.txt index c1d14ad..f0c57a6 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-display-toggle-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-display-toggle-expected.txt
@@ -28,7 +28,8 @@ LayoutBlockFlow {DIV} at (51,0) size 39x48 [color=#FFFFFF] LayoutText {#text} at (0,15) size 39x18 text run at (0,15) width 39: "/ 0:06" - LayoutBlockFlow {DIV} at (90,48) size 134x0 + LayoutBlockFlow {DIV} at (90,48) size 86x0 + LayoutButton {INPUT} at (176,0) size 48x48 LayoutButton {INPUT} at (224,0) size 48x48 LayoutButton {INPUT} at (272,0) size 48x48 layer at (8,252) size 320x16
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-no-audio-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-no-audio-expected.png index 8b6c3bd..f7cfee5 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-no-audio-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-no-audio-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-no-audio-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-no-audio-expected.txt index 1a6eb83..bf9d6c1 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-no-audio-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-no-audio-expected.txt
@@ -29,10 +29,11 @@ LayoutBlockFlow {DIV} at (51,0) size 39x48 [color=#FFFFFF] LayoutText {#text} at (0,15) size 39x18 text run at (0,15) width 39: "/ 0:09" - LayoutBlockFlow {DIV} at (90,48) size 166x0 + LayoutBlockFlow {DIV} at (90,48) size 118x0 + LayoutButton {INPUT} at (256,0) size 48x48 LayoutButton {INPUT} at (304,0) size 48x48 -layer at (264,268) size 48x48 transparent - LayoutButton {INPUT} at (256,0) size 48x48 [color=#808080] +layer at (216,268) size 48x48 transparent + LayoutButton {INPUT} at (208,0) size 48x48 [color=#808080] layer at (8,316) size 352x16 LayoutSlider {INPUT} at (0,272) size 352x16 [color=#9D968E] LayoutFlexibleBox {DIV} at (16,0) size 320x4
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-zoom-controls-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-zoom-controls-expected.txt index 1c827e3..381706f42 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-zoom-controls-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/video-surface-layer/media/video-zoom-controls-expected.txt
@@ -19,7 +19,7 @@ LayoutButton (relative positioned) {INPUT} at (0,0) size 240x156 [border: (3px outset #C0C0C0)] LayoutFlexibleBox (anonymous) at (12,42) size 216x72 LayoutBlockFlow {DIV} at (72,0) size 72x72 [bgcolor=#FFFFFFE6] -layer at (57,169) size 240x72 scrollWidth 266 +layer at (57,169) size 240x72 scrollWidth 338 LayoutFlexibleBox (relative positioned) {DIV} at (0,84) size 240x72 LayoutBlockFlow {DIV} at (24,0) size 46x72 [color=#FFFFFF] LayoutText {#text} at (0,22) size 46x27 @@ -31,6 +31,7 @@ LayoutBlockFlow {DIV} at (122,72) size 0x0 LayoutButton {INPUT} at (122,0) size 72x72 LayoutButton {INPUT} at (194,0) size 72x72 + LayoutButton {INPUT} at (266,0) size 72x72 layer at (57,241) size 240x24 LayoutSlider {INPUT} at (0,156) size 240x24 [color=#9D968E] LayoutFlexibleBox {DIV} at (24,0) size 192x6 @@ -57,7 +58,7 @@ LayoutButton (relative positioned) {INPUT} at (0,0) size 240x156 [border: (3px outset #C0C0C0)] LayoutFlexibleBox (anonymous) at (12,42) size 216x72 LayoutBlockFlow {DIV} at (72,0) size 72x72 [bgcolor=#FFFFFFE6] -layer at (57,394) size 240x72 backgroundClip at (47,373) size 249x113 clip at (57,394) size 239x72 scrollWidth 266 +layer at (57,394) size 240x72 backgroundClip at (47,373) size 249x113 clip at (57,394) size 239x72 scrollWidth 338 LayoutFlexibleBox (relative positioned) {DIV} at (0,84) size 240x72 LayoutBlockFlow {DIV} at (24,0) size 46x72 [color=#FFFFFF] LayoutText {#text} at (0,22) size 46x27 @@ -69,6 +70,7 @@ LayoutBlockFlow {DIV} at (122,72) size 0x0 LayoutButton {INPUT} at (122,0) size 72x72 LayoutButton {INPUT} at (194,0) size 72x72 + LayoutButton {INPUT} at (266,0) size 72x72 layer at (57,466) size 240x24 LayoutSlider {INPUT} at (0,156) size 240x24 [color=#9D968E] LayoutFlexibleBox {DIV} at (24,0) size 192x6
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/compositing/gestures/gesture-tapHighlight-pixel-rotated-div-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/compositing/gestures/gesture-tapHighlight-pixel-rotated-div-expected.png new file mode 100644 index 0000000..b3deb01 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/compositing/gestures/gesture-tapHighlight-pixel-rotated-div-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/compositing/gestures/gesture-tapHighlight-pixel-rotated-link-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/compositing/gestures/gesture-tapHighlight-pixel-rotated-link-expected.png new file mode 100644 index 0000000..643828e --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/compositing/gestures/gesture-tapHighlight-pixel-rotated-link-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/compositing/gestures/gesture-tapHighlight-pixel-transparent-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/compositing/gestures/gesture-tapHighlight-pixel-transparent-expected.png new file mode 100644 index 0000000..4f9bc5f --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/compositing/gestures/gesture-tapHighlight-pixel-transparent-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls-after-reload-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls-after-reload-expected.png index b9f0e181..a523051f 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls-after-reload-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls-after-reload-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls-strict-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls-strict-expected.png index b38bb981..a06bec55 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls-strict-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls-strict-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls-styling-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls-styling-expected.png index b2d28693..460f055 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls-styling-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls-styling-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls-styling-strict-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls-styling-strict-expected.png index 364edda1..59b15f8 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls-styling-strict-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls-styling-strict-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls-without-preload-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls-without-preload-expected.png index e28f6fd..92a7f39a 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls-without-preload-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls-without-preload-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png index 301fd4ee..6339e039 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-expected.png index 301fd4ee..6339e039 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/video-controls-rendering-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/video-controls-rendering-expected.png index e1f07b084..bad430af 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/video-controls-rendering-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/video-controls-rendering-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/video-display-toggle-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/video-display-toggle-expected.png index e476c2eb..434cf68 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/video-display-toggle-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/video-surface-layer/media/video-display-toggle-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.12/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-expected.png new file mode 100644 index 0000000..72827d5d --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls-after-reload-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls-after-reload-expected.png new file mode 100644 index 0000000..05b83d8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls-after-reload-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls-after-reload-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls-after-reload-expected.txt new file mode 100644 index 0000000..d3fa271 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls-after-reload-expected.txt
@@ -0,0 +1,48 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutBlockFlow {HTML} at (0,0) size 800x600 + LayoutBlockFlow {BODY} at (8,8) size 784x584 + LayoutBlockFlow {P} at (0,0) size 784x18 + LayoutText {#text} at (0,0) size 368x18 + text run at (0,0) width 368: "Making sure the controller looks ok after a second load()." + LayoutBlockFlow (anonymous) at (0,34) size 784x240 + LayoutText {#text} at (0,0) size 0x0 +layer at (8,42) size 320x240 + LayoutVideo {VIDEO} at (0,0) size 320x240 +layer at (8,42) size 320x240 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x240 + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (8,42) size 320x240 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 320x240 +layer at (8,42) size 320x240 + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (8,42) size 320x224 clip at (9,43) size 318x222 + LayoutButton (relative positioned) {INPUT} at (0,0) size 320x224 [border: (1px solid #D8D8D8) (1px solid #D1D1D1) (1px solid #BABABA) (1px solid #D1D1D1)] + LayoutFlexibleBox (anonymous) at (8,81.50) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] +layer at (8,218) size 320x48 + LayoutFlexibleBox (relative positioned) {DIV} at (0,176) size 320x48 + LayoutBlockFlow {DIV} at (16,0) size 31.14x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 32x18 + text run at (0,15) width 32: "0:00" + LayoutBlockFlow {DIV} at (51.14,0) size 40.03x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 41x18 + text run at (0,15) width 41: "/ 0:06" + LayoutBlockFlow {DIV} at (91.17,48) size 84.83x0 + LayoutButton {INPUT} at (176,0) size 48x48 + LayoutButton {INPUT} at (224,0) size 48x48 + LayoutButton {INPUT} at (272,0) size 48x48 +layer at (8,266) size 320x16 + LayoutSlider {INPUT} at (0,224) size 320x16 [color=#909090] + LayoutFlexibleBox {DIV} at (16,0) size 288x4 +layer at (24,266) size 288x4 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF4D] +layer at (24,262) size 12x12 + LayoutBlockFlow (relative positioned) {DIV} at (0,-4) size 12x12 [bgcolor=#FFFFFF] +layer at (24,266) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 +layer at (24,266) size 0x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#FFFFFF] +layer at (24,266) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF8A]
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls-strict-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls-strict-expected.png new file mode 100644 index 0000000..1dd02d7 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls-strict-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls-strict-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls-strict-expected.txt new file mode 100644 index 0000000..7c08a0bd --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls-strict-expected.txt
@@ -0,0 +1,48 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x302 + LayoutBlockFlow {HTML} at (0,0) size 800x302 + LayoutBlockFlow {BODY} at (8,16) size 784x278 + LayoutBlockFlow {P} at (0,0) size 784x18 + LayoutText {#text} at (0,0) size 232x18 + text run at (0,0) width 232: "Drawing the controls in strict mode." + LayoutBlockFlow (anonymous) at (0,34) size 784x244 + LayoutText {#text} at (0,0) size 0x0 +layer at (8,50) size 320x240 + LayoutVideo {VIDEO} at (0,0) size 320x240 +layer at (8,50) size 320x240 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x240 + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (8,50) size 320x240 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 320x240 +layer at (8,50) size 320x240 + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (8,50) size 320x224 clip at (9,51) size 318x222 + LayoutButton (relative positioned) {INPUT} at (0,0) size 320x224 [border: (1px solid #D8D8D8) (1px solid #D1D1D1) (1px solid #BABABA) (1px solid #D1D1D1)] + LayoutFlexibleBox (anonymous) at (8,81.50) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] +layer at (8,226) size 320x48 + LayoutFlexibleBox (relative positioned) {DIV} at (0,176) size 320x48 + LayoutBlockFlow {DIV} at (16,0) size 31.14x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 32x18 + text run at (0,15) width 32: "0:00" + LayoutBlockFlow {DIV} at (51.14,0) size 40.03x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 41x18 + text run at (0,15) width 41: "/ 0:06" + LayoutBlockFlow {DIV} at (91.17,48) size 84.83x0 + LayoutButton {INPUT} at (176,0) size 48x48 + LayoutButton {INPUT} at (224,0) size 48x48 + LayoutButton {INPUT} at (272,0) size 48x48 +layer at (8,274) size 320x16 + LayoutSlider {INPUT} at (0,224) size 320x16 [color=#909090] + LayoutFlexibleBox {DIV} at (16,0) size 288x4 +layer at (24,274) size 288x4 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF4D] +layer at (24,270) size 12x12 + LayoutBlockFlow (relative positioned) {DIV} at (0,-4) size 12x12 [bgcolor=#FFFFFF] +layer at (24,274) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 +layer at (24,274) size 0x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#FFFFFF] +layer at (24,274) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF8A]
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls-styling-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls-styling-expected.png new file mode 100644 index 0000000..5c401b0d --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls-styling-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls-styling-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls-styling-expected.txt new file mode 100644 index 0000000..2c855f5 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls-styling-expected.txt
@@ -0,0 +1,88 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutBlockFlow {HTML} at (0,0) size 800x600 + LayoutBlockFlow {BODY} at (8,8) size 784x584 + LayoutBlockFlow {P} at (0,0) size 784x18 + LayoutText {#text} at (0,0) size 279x18 + text run at (0,0) width 279: "The look of the controls should not change." + LayoutBlockFlow {DIV} at (0,34) size 784x240 [color=#0000FF] + LayoutText {#text} at (0,0) size 0x0 + LayoutBlockFlow (anonymous) at (0,274) size 784x240 + LayoutText {#text} at (0,0) size 0x0 +layer at (18,42) size 320x240 + LayoutVideo {VIDEO} at (10,0) size 320x240 +layer at (8,282) size 320x240 + LayoutVideo {VIDEO} at (0,0) size 320x240 +layer at (18,42) size 320x240 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x240 [color=#000000] + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (18,42) size 320x240 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 320x240 +layer at (18,42) size 320x240 + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (18,42) size 320x224 clip at (19,43) size 318x222 + LayoutButton (relative positioned) {INPUT} at (0,0) size 320x224 [border: (1px solid #D8D8D8) (1px solid #D1D1D1) (1px solid #BABABA) (1px solid #D1D1D1)] + LayoutFlexibleBox (anonymous) at (8,81.50) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] +layer at (18,218) size 320x48 + LayoutFlexibleBox (relative positioned) {DIV} at (0,176) size 320x48 + LayoutBlockFlow {DIV} at (16,0) size 31.14x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 32x18 + text run at (0,15) width 32: "0:00" + LayoutBlockFlow {DIV} at (51.14,0) size 70.03x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 71x18 + text run at (0,15) width 71: "/ 0:06" + LayoutBlockFlow {DIV} at (121.17,48) size 54.83x0 + LayoutButton {INPUT} at (176,0) size 48x48 + LayoutButton {INPUT} at (224,0) size 48x48 + LayoutButton {INPUT} at (272,0) size 48x48 +layer at (18,266) size 320x16 + LayoutSlider {INPUT} at (0,224) size 320x16 [color=#909090] + LayoutFlexibleBox {DIV} at (16,0) size 288x4 +layer at (34,266) size 288x4 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF4D] +layer at (34,262) size 12x12 + LayoutBlockFlow (relative positioned) {DIV} at (0,-4) size 12x12 [bgcolor=#FFFFFF] +layer at (34,266) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 +layer at (34,266) size 0x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#FFFFFF] +layer at (34,266) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF8A] +layer at (8,282) size 320x240 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x240 + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (8,282) size 320x240 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 320x240 +layer at (8,282) size 320x240 + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (8,282) size 320x224 clip at (9,283) size 318x222 + LayoutButton (relative positioned) {INPUT} at (0,0) size 320x224 [border: (1px solid #D8D8D8) (1px solid #D1D1D1) (1px solid #BABABA) (1px solid #D1D1D1)] + LayoutFlexibleBox (anonymous) at (8,81.50) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] +layer at (8,458) size 320x48 + LayoutFlexibleBox (relative positioned) {DIV} at (0,176) size 320x48 + LayoutBlockFlow {DIV} at (16,0) size 31.14x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 32x18 + text run at (0,15) width 32: "0:00" + LayoutBlockFlow {DIV} at (51.14,0) size 40.03x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 41x18 + text run at (0,15) width 41: "/ 0:06" + LayoutBlockFlow {DIV} at (91.17,48) size 84.83x0 + LayoutButton {INPUT} at (176,0) size 48x48 + LayoutButton {INPUT} at (224,0) size 48x48 + LayoutButton {INPUT} at (272,0) size 48x48 +layer at (8,506) size 320x16 + LayoutSlider {INPUT} at (0,224) size 320x16 [color=#909090] + LayoutFlexibleBox {DIV} at (16,0) size 288x4 +layer at (24,506) size 288x4 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF4D] +layer at (24,502) size 12x12 + LayoutBlockFlow (relative positioned) {DIV} at (0,-4) size 12x12 [bgcolor=#FFFFFF] +layer at (24,506) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 +layer at (24,506) size 0x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#FFFFFF] +layer at (24,506) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF8A]
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls-styling-strict-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls-styling-strict-expected.png new file mode 100644 index 0000000..2546bdd --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls-styling-strict-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls-styling-strict-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls-styling-strict-expected.txt new file mode 100644 index 0000000..27944218 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls-styling-strict-expected.txt
@@ -0,0 +1,88 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x302 + LayoutBlockFlow {HTML} at (0,0) size 800x302 + LayoutBlockFlow {BODY} at (8,16) size 784x278 + LayoutBlockFlow {P} at (0,0) size 784x18 + LayoutText {#text} at (0,0) size 475x18 + text run at (0,0) width 475: "The look of the controls should not change when styled under strict mode." + LayoutBlockFlow (anonymous) at (0,34) size 784x244 + LayoutText {#text} at (320,226) size 4x18 + text run at (320,226) width 4: " " + LayoutText {#text} at (0,0) size 0x0 +layer at (8,50) size 320x240 + LayoutVideo {VIDEO} at (0,0) size 320x240 [color=#FF0000] +layer at (332,50) size 320x240 + LayoutVideo {VIDEO} at (324,0) size 320x240 +layer at (8,50) size 320x240 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x240 [color=#000000] + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (8,50) size 320x240 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 320x240 +layer at (8,50) size 320x240 + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (8,50) size 320x224 clip at (9,51) size 318x222 + LayoutButton (relative positioned) {INPUT} at (0,0) size 320x224 [border: (1px solid #D8D8D8) (1px solid #D1D1D1) (1px solid #BABABA) (1px solid #D1D1D1)] + LayoutFlexibleBox (anonymous) at (8,81.50) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] +layer at (8,226) size 320x48 + LayoutFlexibleBox (relative positioned) {DIV} at (0,176) size 320x48 + LayoutBlockFlow {DIV} at (16,0) size 31.14x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 32x18 + text run at (0,15) width 32: "0:00" + LayoutBlockFlow {DIV} at (51.14,0) size 40.03x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 41x18 + text run at (0,15) width 41: "/ 0:06" + LayoutBlockFlow {DIV} at (91.17,48) size 84.83x0 + LayoutButton {INPUT} at (176,0) size 48x48 + LayoutButton {INPUT} at (224,0) size 48x48 + LayoutButton {INPUT} at (272,0) size 48x48 +layer at (8,274) size 320x16 + LayoutSlider {INPUT} at (0,224) size 320x16 [color=#909090] + LayoutFlexibleBox {DIV} at (16,0) size 288x4 +layer at (24,274) size 288x4 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF4D] +layer at (24,270) size 12x12 + LayoutBlockFlow (relative positioned) {DIV} at (0,-4) size 12x12 [bgcolor=#FFFFFF] +layer at (24,274) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 +layer at (24,274) size 0x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#FFFFFF] +layer at (24,274) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF8A] +layer at (332,50) size 320x240 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x240 + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (332,50) size 320x240 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 320x240 +layer at (332,50) size 320x240 + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (332,50) size 320x224 clip at (333,51) size 318x222 + LayoutButton (relative positioned) {INPUT} at (0,0) size 320x224 [border: (1px solid #D8D8D8) (1px solid #D1D1D1) (1px solid #BABABA) (1px solid #D1D1D1)] + LayoutFlexibleBox (anonymous) at (8,81.50) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] +layer at (332,226) size 320x48 + LayoutFlexibleBox (relative positioned) {DIV} at (0,176) size 320x48 + LayoutBlockFlow {DIV} at (16,0) size 31.14x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 32x18 + text run at (0,15) width 32: "0:00" + LayoutBlockFlow {DIV} at (51.14,0) size 40.03x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 41x18 + text run at (0,15) width 41: "/ 0:06" + LayoutBlockFlow {DIV} at (91.17,48) size 84.83x0 + LayoutButton {INPUT} at (176,0) size 48x48 + LayoutButton {INPUT} at (224,0) size 48x48 + LayoutButton {INPUT} at (272,0) size 48x48 +layer at (332,274) size 320x16 + LayoutSlider {INPUT} at (0,224) size 320x16 [color=#909090] + LayoutFlexibleBox {DIV} at (16,0) size 288x4 +layer at (348,274) size 288x4 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF4D] +layer at (348,270) size 12x12 + LayoutBlockFlow (relative positioned) {DIV} at (0,-4) size 12x12 [bgcolor=#FFFFFF] +layer at (348,274) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 +layer at (348,274) size 0x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#FFFFFF] +layer at (348,274) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF8A]
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls-without-preload-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls-without-preload-expected.png new file mode 100644 index 0000000..70c0512 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls-without-preload-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls-without-preload-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls-without-preload-expected.txt new file mode 100644 index 0000000..0d5382e --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls-without-preload-expected.txt
@@ -0,0 +1,48 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutBlockFlow {HTML} at (0,0) size 800x600 + LayoutBlockFlow {BODY} at (8,8) size 784x584 + LayoutBlockFlow {P} at (0,0) size 784x18 + LayoutText {#text} at (0,0) size 317x18 + text run at (0,0) width 317: "The controls should not depend on preload value." + LayoutBlockFlow (anonymous) at (0,34) size 784x240 + LayoutText {#text} at (0,0) size 0x0 +layer at (8,42) size 320x240 + LayoutVideo {VIDEO} at (0,0) size 320x240 +layer at (8,42) size 320x240 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x240 + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (8,42) size 320x240 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 320x240 +layer at (8,42) size 320x240 + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (8,42) size 320x224 clip at (9,43) size 318x222 + LayoutButton (relative positioned) {INPUT} at (0,0) size 320x224 [border: (1px solid #D8D8D8) (1px solid #D1D1D1) (1px solid #BABABA) (1px solid #D1D1D1)] + LayoutFlexibleBox (anonymous) at (8,81.50) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] +layer at (8,218) size 320x48 + LayoutFlexibleBox (relative positioned) {DIV} at (0,176) size 320x48 + LayoutBlockFlow {DIV} at (16,0) size 31.14x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 32x18 + text run at (0,15) width 32: "0:00" + LayoutBlockFlow {DIV} at (51.14,0) size 40.03x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 41x18 + text run at (0,15) width 41: "/ 0:06" + LayoutBlockFlow {DIV} at (91.17,48) size 84.83x0 + LayoutButton {INPUT} at (176,0) size 48x48 + LayoutButton {INPUT} at (224,0) size 48x48 + LayoutButton {INPUT} at (272,0) size 48x48 +layer at (8,266) size 320x16 + LayoutSlider {INPUT} at (0,224) size 320x16 [color=#909090] + LayoutFlexibleBox {DIV} at (16,0) size 288x4 +layer at (24,266) size 288x4 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF4D] +layer at (24,262) size 12x12 + LayoutBlockFlow (relative positioned) {DIV} at (0,-4) size 12x12 [bgcolor=#FFFFFF] +layer at (24,266) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 +layer at (24,266) size 0x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#FFFFFF] +layer at (24,266) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF8A]
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls/lazy-loaded-style-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls/lazy-loaded-style-expected.txt new file mode 100644 index 0000000..777b926d --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls/lazy-loaded-style-expected.txt
@@ -0,0 +1,44 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x320 + LayoutBlockFlow {HTML} at (0,0) size 800x320 + LayoutBlockFlow {BODY} at (8,8) size 784x304 + LayoutText {#text} at (0,0) size 0x0 +layer at (8,8) size 400x300 + LayoutVideo {VIDEO} at (0,0) size 400x300 +layer at (8,8) size 400x300 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 400x300 + LayoutFlexibleBox {DIV} at (0,0) size 400x300 +layer at (8,8) size 400x300 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 400x300 +layer at (8,8) size 400x300 + LayoutFlexibleBox {DIV} at (0,0) size 400x300 +layer at (8,8) size 400x284 clip at (9,9) size 398x282 + LayoutButton (relative positioned) {INPUT} at (0,0) size 400x284 [border: (1px solid #D8D8D8) (1px solid #D1D1D1) (1px solid #BABABA) (1px solid #D1D1D1)] + LayoutFlexibleBox (anonymous) at (8,104) size 384x75 + LayoutBlockFlow {DIV} at (154.50,0) size 75x75 [bgcolor=#FFFFFFE6] +layer at (8,244) size 400x48 + LayoutFlexibleBox (relative positioned) {DIV} at (0,236) size 400x48 + LayoutBlockFlow {DIV} at (16,0) size 31.14x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 32x18 + text run at (0,15) width 32: "0:00" + LayoutBlockFlow {DIV} at (51.14,0) size 40.03x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 41x18 + text run at (0,15) width 41: "/ 0:06" + LayoutBlockFlow {DIV} at (91.17,48) size 164.83x0 + LayoutButton {INPUT} at (256,0) size 48x48 + LayoutButton {INPUT} at (304,0) size 48x48 + LayoutButton {INPUT} at (352,0) size 48x48 +layer at (8,292) size 400x16 + LayoutSlider {INPUT} at (0,284) size 400x16 [color=#909090] + LayoutFlexibleBox {DIV} at (16,0) size 368x4 +layer at (24,292) size 368x4 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 368x4 [bgcolor=#FFFFFF4D] +layer at (24,288) size 12x12 + LayoutBlockFlow (relative positioned) {DIV} at (0,-4) size 12x12 [bgcolor=#FFFFFF] +layer at (24,292) size 368x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 368x4 +layer at (24,292) size 0x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#FFFFFF] +layer at (24,292) size 368x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 368x4 [bgcolor=#FFFFFF8A]
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png new file mode 100644 index 0000000..72827d5d --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.txt new file mode 100644 index 0000000..27b11d9 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.txt
@@ -0,0 +1,45 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x347 + LayoutBlockFlow {HTML} at (0,0) size 800x347.27 + LayoutBlockFlow {BODY} at (8,8) size 784x331.27 + LayoutText {#text} at (0,0) size 0x0 +layer at (8,8) size 400x327 + LayoutVideo {VIDEO} at (0,0) size 400x327.27 +layer at (8,8) size 400x327 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 400x327.27 + LayoutFlexibleBox {DIV} at (0,0) size 400x327.27 +layer at (8,8) size 400x327 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 400x327.27 +layer at (8,8) size 400x327 + LayoutFlexibleBox {DIV} at (0,0) size 400x327.27 +layer at (8,8) size 400x311 clip at (9,9) size 398x309 + LayoutButton (relative positioned) {INPUT} at (0,0) size 400x311.27 [border: (1px solid #D8D8D8) (1px solid #D1D1D1) (1px solid #BABABA) (1px solid #D1D1D1)] + LayoutFlexibleBox (anonymous) at (8,114.25) size 384x81.75 + LayoutBlockFlow {DIV} at (151.13,0) size 81.75x81.75 [bgcolor=#FFFFFFE6] +layer at (8,271) size 400x48 + LayoutFlexibleBox (relative positioned) {DIV} at (0,263.27) size 400x48 + LayoutBlockFlow {DIV} at (16,0) size 31.14x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 32x18 + text run at (0,15) width 32: "0:00" + LayoutBlockFlow {DIV} at (51.14,0) size 40.03x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 41x18 + text run at (0,15) width 41: "/ 0:09" + LayoutBlockFlow {DIV} at (91.17,48) size 164.83x0 + LayoutButton {INPUT} at (304,0) size 48x48 + LayoutButton {INPUT} at (352,0) size 48x48 +layer at (264,271) size 48x48 transparent + LayoutButton {INPUT} at (256,0) size 48x48 [color=#7F7F7F] +layer at (8,319) size 400x16 + LayoutSlider {INPUT} at (0,311.27) size 400x16 [color=#909090] + LayoutFlexibleBox {DIV} at (16,0) size 368x4 +layer at (24,319) size 368x4 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 368x4 [bgcolor=#FFFFFF4D] +layer at (24,315) size 12x12 + LayoutBlockFlow (relative positioned) {DIV} at (0,-4) size 12x12 [bgcolor=#FFFFFF] +layer at (24,319) size 368x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 368x4 +layer at (24,319) size 0x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#FFFFFF] +layer at (24,319) size 368x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 368x4 [bgcolor=#FFFFFF8A]
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-expected.png new file mode 100644 index 0000000..819ea7d --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-expected.txt new file mode 100644 index 0000000..27b11d9 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-expected.txt
@@ -0,0 +1,45 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x347 + LayoutBlockFlow {HTML} at (0,0) size 800x347.27 + LayoutBlockFlow {BODY} at (8,8) size 784x331.27 + LayoutText {#text} at (0,0) size 0x0 +layer at (8,8) size 400x327 + LayoutVideo {VIDEO} at (0,0) size 400x327.27 +layer at (8,8) size 400x327 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 400x327.27 + LayoutFlexibleBox {DIV} at (0,0) size 400x327.27 +layer at (8,8) size 400x327 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 400x327.27 +layer at (8,8) size 400x327 + LayoutFlexibleBox {DIV} at (0,0) size 400x327.27 +layer at (8,8) size 400x311 clip at (9,9) size 398x309 + LayoutButton (relative positioned) {INPUT} at (0,0) size 400x311.27 [border: (1px solid #D8D8D8) (1px solid #D1D1D1) (1px solid #BABABA) (1px solid #D1D1D1)] + LayoutFlexibleBox (anonymous) at (8,114.25) size 384x81.75 + LayoutBlockFlow {DIV} at (151.13,0) size 81.75x81.75 [bgcolor=#FFFFFFE6] +layer at (8,271) size 400x48 + LayoutFlexibleBox (relative positioned) {DIV} at (0,263.27) size 400x48 + LayoutBlockFlow {DIV} at (16,0) size 31.14x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 32x18 + text run at (0,15) width 32: "0:00" + LayoutBlockFlow {DIV} at (51.14,0) size 40.03x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 41x18 + text run at (0,15) width 41: "/ 0:09" + LayoutBlockFlow {DIV} at (91.17,48) size 164.83x0 + LayoutButton {INPUT} at (304,0) size 48x48 + LayoutButton {INPUT} at (352,0) size 48x48 +layer at (264,271) size 48x48 transparent + LayoutButton {INPUT} at (256,0) size 48x48 [color=#7F7F7F] +layer at (8,319) size 400x16 + LayoutSlider {INPUT} at (0,311.27) size 400x16 [color=#909090] + LayoutFlexibleBox {DIV} at (16,0) size 368x4 +layer at (24,319) size 368x4 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 368x4 [bgcolor=#FFFFFF4D] +layer at (24,315) size 12x12 + LayoutBlockFlow (relative positioned) {DIV} at (0,-4) size 12x12 [bgcolor=#FFFFFF] +layer at (24,319) size 368x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 368x4 +layer at (24,319) size 0x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#FFFFFF] +layer at (24,319) size 368x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 368x4 [bgcolor=#FFFFFF8A]
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/video-controls-rendering-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/video-controls-rendering-expected.png new file mode 100644 index 0000000..c1d6149 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/video-controls-rendering-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/video-controls-rendering-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/video-controls-rendering-expected.txt new file mode 100644 index 0000000..f1e1691 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/video-controls-rendering-expected.txt
@@ -0,0 +1,127 @@ +layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 762 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 785x600 + LayoutBlockFlow {HTML} at (0,0) size 785x600 + LayoutBlockFlow {BODY} at (8,8) size 769x584 + LayoutBlockFlow {P} at (0,0) size 769x18 + LayoutText {#text} at (0,0) size 156x18 + text run at (0,0) width 156: "Test controls placement." + LayoutBlockFlow {DIV} at (0,34) size 769x240 + LayoutText {#text} at (0,0) size 0x0 + LayoutBlockFlow {DIV} at (0,274) size 769x240 + LayoutText {#text} at (0,0) size 0x0 + LayoutBlockFlow {DIV} at (0,514) size 769x0 +layer at (8,42) size 320x240 + LayoutVideo {VIDEO} at (0,0) size 320x240 +layer at (8,282) size 320x240 + LayoutVideo {VIDEO} at (0,0) size 320x240 +layer at (8,42) size 320x240 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x240 + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (8,42) size 320x240 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 320x240 +layer at (8,42) size 320x240 + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (8,42) size 320x224 clip at (9,43) size 318x222 + LayoutButton (relative positioned) {INPUT} at (0,0) size 320x224 [border: (1px solid #D8D8D8) (1px solid #D1D1D1) (1px solid #BABABA) (1px solid #D1D1D1)] + LayoutFlexibleBox (anonymous) at (8,81.50) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] +layer at (8,218) size 320x48 + LayoutFlexibleBox (relative positioned) {DIV} at (0,176) size 320x48 + LayoutBlockFlow {DIV} at (16,0) size 31.14x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 32x18 + text run at (0,15) width 32: "0:00" + LayoutBlockFlow {DIV} at (51.14,0) size 40.03x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 41x18 + text run at (0,15) width 41: "/ 0:06" + LayoutBlockFlow {DIV} at (91.17,48) size 84.83x0 + LayoutButton {INPUT} at (176,0) size 48x48 + LayoutButton {INPUT} at (224,0) size 48x48 + LayoutButton {INPUT} at (272,0) size 48x48 +layer at (8,266) size 320x16 + LayoutSlider {INPUT} at (0,224) size 320x16 [color=#909090] + LayoutFlexibleBox {DIV} at (16,0) size 288x4 +layer at (24,266) size 288x4 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF4D] +layer at (24,262) size 12x12 + LayoutBlockFlow (relative positioned) {DIV} at (0,-4) size 12x12 [bgcolor=#FFFFFF] +layer at (24,266) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 +layer at (24,266) size 0x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#FFFFFF] +layer at (24,266) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF8A] +layer at (8,282) size 320x240 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x240 + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (8,282) size 320x240 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 320x240 +layer at (8,282) size 320x240 + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (8,282) size 320x224 clip at (9,283) size 318x222 + LayoutButton (relative positioned) {INPUT} at (0,0) size 320x224 [border: (1px solid #D8D8D8) (1px solid #D1D1D1) (1px solid #BABABA) (1px solid #D1D1D1)] + LayoutFlexibleBox (anonymous) at (8,81.50) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] +layer at (8,458) size 320x48 + LayoutFlexibleBox (relative positioned) {DIV} at (0,176) size 320x48 + LayoutBlockFlow {DIV} at (16,0) size 31.14x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 32x18 + text run at (0,15) width 32: "0:00" + LayoutBlockFlow {DIV} at (51.14,0) size 40.03x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 41x18 + text run at (0,15) width 41: "/ 0:06" + LayoutBlockFlow {DIV} at (91.17,48) size 84.83x0 + LayoutButton {INPUT} at (176,0) size 48x48 + LayoutButton {INPUT} at (224,0) size 48x48 + LayoutButton {INPUT} at (272,0) size 48x48 +layer at (8,506) size 320x16 + LayoutSlider {INPUT} at (0,224) size 320x16 [color=#909090] + LayoutFlexibleBox {DIV} at (16,0) size 288x4 +layer at (24,506) size 288x4 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF4D] +layer at (24,502) size 12x12 + LayoutBlockFlow (relative positioned) {DIV} at (0,-4) size 12x12 [bgcolor=#FFFFFF] +layer at (24,506) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 +layer at (24,506) size 0x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#FFFFFF] +layer at (24,506) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF8A] +layer at (8,522) size 320x240 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600 + LayoutVideo (positioned) {VIDEO} at (8,522) size 320x240 +layer at (8,522) size 320x240 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x240 + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (8,522) size 320x240 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 320x240 +layer at (8,522) size 320x240 backgroundClip at (8,522) size 320x78 clip at (8,522) size 320x78 + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (8,522) size 320x224 backgroundClip at (8,522) size 320x78 clip at (9,523) size 318x77 + LayoutButton (relative positioned) {INPUT} at (0,0) size 320x224 [border: (1px solid #D8D8D8) (1px solid #D1D1D1) (1px solid #BABABA) (1px solid #D1D1D1)] + LayoutFlexibleBox (anonymous) at (8,81.50) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] +layer at (8,698) size 320x48 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0 + LayoutFlexibleBox (relative positioned) {DIV} at (0,176) size 320x48 + LayoutBlockFlow {DIV} at (16,0) size 31.14x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 32x18 + text run at (0,15) width 32: "0:00" + LayoutBlockFlow {DIV} at (51.14,0) size 40.03x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 41x18 + text run at (0,15) width 41: "/ 0:06" + LayoutBlockFlow {DIV} at (91.17,48) size 84.83x0 + LayoutButton {INPUT} at (176,0) size 48x48 + LayoutButton {INPUT} at (224,0) size 48x48 + LayoutButton {INPUT} at (272,0) size 48x48 +layer at (8,746) size 320x16 backgroundClip at (8,522) size 320x78 clip at (8,522) size 320x78 + LayoutSlider {INPUT} at (0,224) size 320x16 [color=#909090] + LayoutFlexibleBox {DIV} at (16,0) size 288x4 +layer at (24,746) size 288x4 backgroundClip at (8,522) size 320x78 clip at (8,522) size 320x78 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF4D] +layer at (24,742) size 12x12 backgroundClip at (8,522) size 320x78 clip at (8,522) size 320x78 + LayoutBlockFlow (relative positioned) {DIV} at (0,-4) size 12x12 [bgcolor=#FFFFFF] +layer at (24,746) size 288x4 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 +layer at (24,746) size 0x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#FFFFFF] +layer at (24,746) size 288x4 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF8A]
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/video-display-toggle-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/video-display-toggle-expected.png new file mode 100644 index 0000000..b9cda72 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/video-display-toggle-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/video-display-toggle-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/video-display-toggle-expected.txt new file mode 100644 index 0000000..8abe823a --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/video-surface-layer/media/video-display-toggle-expected.txt
@@ -0,0 +1,47 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutBlockFlow {HTML} at (0,0) size 800x600 + LayoutBlockFlow {BODY} at (8,8) size 784x584 + LayoutText {#text} at (0,0) size 504x18 + text run at (0,0) width 504: "This tests that toggling the display property won't make the controls disappear." + LayoutBR {BR} at (503,14) size 1x0 + LayoutText {#text} at (0,0) size 0x0 +layer at (8,26) size 320x240 + LayoutVideo {VIDEO} at (0,18) size 320x240 +layer at (8,26) size 320x240 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x240 + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (8,26) size 320x240 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 320x240 +layer at (8,26) size 320x240 + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (8,26) size 320x224 clip at (9,27) size 318x222 + LayoutButton (relative positioned) {INPUT} at (0,0) size 320x224 [border: (1px solid #D8D8D8) (1px solid #D1D1D1) (1px solid #BABABA) (1px solid #D1D1D1)] + LayoutFlexibleBox (anonymous) at (8,81.50) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] +layer at (8,202) size 320x48 + LayoutFlexibleBox (relative positioned) {DIV} at (0,176) size 320x48 + LayoutBlockFlow {DIV} at (16,0) size 31.14x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 32x18 + text run at (0,15) width 32: "0:00" + LayoutBlockFlow {DIV} at (51.14,0) size 40.03x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 41x18 + text run at (0,15) width 41: "/ 0:06" + LayoutBlockFlow {DIV} at (91.17,48) size 84.83x0 + LayoutButton {INPUT} at (176,0) size 48x48 + LayoutButton {INPUT} at (224,0) size 48x48 + LayoutButton {INPUT} at (272,0) size 48x48 +layer at (8,250) size 320x16 + LayoutSlider {INPUT} at (0,224) size 320x16 [color=#909090] + LayoutFlexibleBox {DIV} at (16,0) size 288x4 +layer at (24,250) size 288x4 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF4D] +layer at (24,246) size 12x12 + LayoutBlockFlow (relative positioned) {DIV} at (0,-4) size 12x12 [bgcolor=#FFFFFF] +layer at (24,250) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 +layer at (24,250) size 0x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#FFFFFF] +layer at (24,250) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF8A]
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls-after-reload-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls-after-reload-expected.png new file mode 100644 index 0000000..eef0cb3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls-after-reload-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls-after-reload-expected.txt b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls-after-reload-expected.txt new file mode 100644 index 0000000..d33878f --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls-after-reload-expected.txt
@@ -0,0 +1,48 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutBlockFlow {HTML} at (0,0) size 800x600 + LayoutBlockFlow {BODY} at (8,8) size 784x584 + LayoutBlockFlow {P} at (0,0) size 784x20 + LayoutText {#text} at (0,0) size 348x19 + text run at (0,0) width 348: "Making sure the controller looks ok after a second load()." + LayoutBlockFlow (anonymous) at (0,36) size 784x240 + LayoutText {#text} at (0,0) size 0x0 +layer at (8,44) size 320x240 + LayoutVideo {VIDEO} at (0,0) size 320x240 +layer at (8,44) size 320x240 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x240 + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (8,44) size 320x240 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 320x240 +layer at (8,44) size 320x240 + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (8,44) size 320x224 clip at (10,46) size 316x220 + LayoutButton (relative positioned) {INPUT} at (0,0) size 320x224 [border: (2px outset #C0C0C0)] + LayoutFlexibleBox (anonymous) at (8,82) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] +layer at (8,220) size 320x48 + LayoutFlexibleBox (relative positioned) {DIV} at (0,176) size 320x48 + LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 31x18 + text run at (0,15) width 31: "0:00" + LayoutBlockFlow {DIV} at (51,0) size 39x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 39x18 + text run at (0,15) width 39: "/ 0:06" + LayoutBlockFlow {DIV} at (90,48) size 86x0 + LayoutButton {INPUT} at (176,0) size 48x48 + LayoutButton {INPUT} at (224,0) size 48x48 + LayoutButton {INPUT} at (272,0) size 48x48 +layer at (8,268) size 320x16 + LayoutSlider {INPUT} at (0,224) size 320x16 [color=#C4C4C4] + LayoutFlexibleBox {DIV} at (16,0) size 288x4 +layer at (24,268) size 288x4 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF4D] +layer at (24,264) size 12x12 + LayoutBlockFlow (relative positioned) {DIV} at (0,-4) size 12x12 [bgcolor=#FFFFFF] +layer at (24,268) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 +layer at (24,268) size 0x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#FFFFFF] +layer at (24,268) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF8A]
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls-strict-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls-strict-expected.png new file mode 100644 index 0000000..2871916 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls-strict-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls-strict-expected.txt b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls-strict-expected.txt new file mode 100644 index 0000000..eb8794e5 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls-strict-expected.txt
@@ -0,0 +1,48 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x305 + LayoutBlockFlow {HTML} at (0,0) size 800x305 + LayoutBlockFlow {BODY} at (8,16) size 784x281 + LayoutBlockFlow {P} at (0,0) size 784x20 + LayoutText {#text} at (0,0) size 214x19 + text run at (0,0) width 214: "Drawing the controls in strict mode." + LayoutBlockFlow (anonymous) at (0,36) size 784x245 + LayoutText {#text} at (0,0) size 0x0 +layer at (8,52) size 320x240 + LayoutVideo {VIDEO} at (0,0) size 320x240 +layer at (8,52) size 320x240 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x240 + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (8,52) size 320x240 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 320x240 +layer at (8,52) size 320x240 + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (8,52) size 320x224 clip at (10,54) size 316x220 + LayoutButton (relative positioned) {INPUT} at (0,0) size 320x224 [border: (2px outset #C0C0C0)] + LayoutFlexibleBox (anonymous) at (8,82) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] +layer at (8,228) size 320x48 + LayoutFlexibleBox (relative positioned) {DIV} at (0,176) size 320x48 + LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 31x18 + text run at (0,15) width 31: "0:00" + LayoutBlockFlow {DIV} at (51,0) size 39x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 39x18 + text run at (0,15) width 39: "/ 0:06" + LayoutBlockFlow {DIV} at (90,48) size 86x0 + LayoutButton {INPUT} at (176,0) size 48x48 + LayoutButton {INPUT} at (224,0) size 48x48 + LayoutButton {INPUT} at (272,0) size 48x48 +layer at (8,276) size 320x16 + LayoutSlider {INPUT} at (0,224) size 320x16 [color=#C4C4C4] + LayoutFlexibleBox {DIV} at (16,0) size 288x4 +layer at (24,276) size 288x4 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF4D] +layer at (24,272) size 12x12 + LayoutBlockFlow (relative positioned) {DIV} at (0,-4) size 12x12 [bgcolor=#FFFFFF] +layer at (24,276) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 +layer at (24,276) size 0x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#FFFFFF] +layer at (24,276) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF8A]
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls-styling-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls-styling-expected.png new file mode 100644 index 0000000..7e13b6d --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls-styling-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls-styling-expected.txt b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls-styling-expected.txt new file mode 100644 index 0000000..320de3d4 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls-styling-expected.txt
@@ -0,0 +1,88 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutBlockFlow {HTML} at (0,0) size 800x600 + LayoutBlockFlow {BODY} at (8,8) size 784x584 + LayoutBlockFlow {P} at (0,0) size 784x20 + LayoutText {#text} at (0,0) size 260x19 + text run at (0,0) width 260: "The look of the controls should not change." + LayoutBlockFlow {DIV} at (0,36) size 784x240 [color=#0000FF] + LayoutText {#text} at (0,0) size 0x0 + LayoutBlockFlow (anonymous) at (0,276) size 784x240 + LayoutText {#text} at (0,0) size 0x0 +layer at (18,44) size 320x240 + LayoutVideo {VIDEO} at (10,0) size 320x240 +layer at (8,284) size 320x240 + LayoutVideo {VIDEO} at (0,0) size 320x240 +layer at (18,44) size 320x240 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x240 [color=#000000] + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (18,44) size 320x240 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 320x240 +layer at (18,44) size 320x240 + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (18,44) size 320x224 clip at (20,46) size 316x220 + LayoutButton (relative positioned) {INPUT} at (0,0) size 320x224 [border: (2px outset #C0C0C0)] + LayoutFlexibleBox (anonymous) at (8,82) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] +layer at (18,220) size 320x48 + LayoutFlexibleBox (relative positioned) {DIV} at (0,176) size 320x48 + LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 31x18 + text run at (0,15) width 31: "0:00" + LayoutBlockFlow {DIV} at (51,0) size 69x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 69x18 + text run at (0,15) width 69: "/ 0:06" + LayoutBlockFlow {DIV} at (120,48) size 56x0 + LayoutButton {INPUT} at (176,0) size 48x48 + LayoutButton {INPUT} at (224,0) size 48x48 + LayoutButton {INPUT} at (272,0) size 48x48 +layer at (18,268) size 320x16 + LayoutSlider {INPUT} at (0,224) size 320x16 [color=#C4C4C4] + LayoutFlexibleBox {DIV} at (16,0) size 288x4 +layer at (34,268) size 288x4 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF4D] +layer at (34,264) size 12x12 + LayoutBlockFlow (relative positioned) {DIV} at (0,-4) size 12x12 [bgcolor=#FFFFFF] +layer at (34,268) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 +layer at (34,268) size 0x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#FFFFFF] +layer at (34,268) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF8A] +layer at (8,284) size 320x240 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x240 + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (8,284) size 320x240 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 320x240 +layer at (8,284) size 320x240 + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (8,284) size 320x224 clip at (10,286) size 316x220 + LayoutButton (relative positioned) {INPUT} at (0,0) size 320x224 [border: (2px outset #C0C0C0)] + LayoutFlexibleBox (anonymous) at (8,82) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] +layer at (8,460) size 320x48 + LayoutFlexibleBox (relative positioned) {DIV} at (0,176) size 320x48 + LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 31x18 + text run at (0,15) width 31: "0:00" + LayoutBlockFlow {DIV} at (51,0) size 39x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 39x18 + text run at (0,15) width 39: "/ 0:06" + LayoutBlockFlow {DIV} at (90,48) size 86x0 + LayoutButton {INPUT} at (176,0) size 48x48 + LayoutButton {INPUT} at (224,0) size 48x48 + LayoutButton {INPUT} at (272,0) size 48x48 +layer at (8,508) size 320x16 + LayoutSlider {INPUT} at (0,224) size 320x16 [color=#C4C4C4] + LayoutFlexibleBox {DIV} at (16,0) size 288x4 +layer at (24,508) size 288x4 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF4D] +layer at (24,504) size 12x12 + LayoutBlockFlow (relative positioned) {DIV} at (0,-4) size 12x12 [bgcolor=#FFFFFF] +layer at (24,508) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 +layer at (24,508) size 0x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#FFFFFF] +layer at (24,508) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF8A]
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls-styling-strict-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls-styling-strict-expected.png new file mode 100644 index 0000000..ce20a09 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls-styling-strict-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls-styling-strict-expected.txt b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls-styling-strict-expected.txt new file mode 100644 index 0000000..37311f6 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls-styling-strict-expected.txt
@@ -0,0 +1,88 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x305 + LayoutBlockFlow {HTML} at (0,0) size 800x305 + LayoutBlockFlow {BODY} at (8,16) size 784x281 + LayoutBlockFlow {P} at (0,0) size 784x20 + LayoutText {#text} at (0,0) size 444x19 + text run at (0,0) width 444: "The look of the controls should not change when styled under strict mode." + LayoutBlockFlow (anonymous) at (0,36) size 784x245 + LayoutText {#text} at (320,225) size 4x19 + text run at (320,225) width 4: " " + LayoutText {#text} at (0,0) size 0x0 +layer at (8,52) size 320x240 + LayoutVideo {VIDEO} at (0,0) size 320x240 [color=#FF0000] +layer at (332,52) size 320x240 + LayoutVideo {VIDEO} at (324,0) size 320x240 +layer at (8,52) size 320x240 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x240 [color=#000000] + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (8,52) size 320x240 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 320x240 +layer at (8,52) size 320x240 + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (8,52) size 320x224 clip at (10,54) size 316x220 + LayoutButton (relative positioned) {INPUT} at (0,0) size 320x224 [border: (2px outset #C0C0C0)] + LayoutFlexibleBox (anonymous) at (8,82) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] +layer at (8,228) size 320x48 + LayoutFlexibleBox (relative positioned) {DIV} at (0,176) size 320x48 + LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 31x18 + text run at (0,15) width 31: "0:00" + LayoutBlockFlow {DIV} at (51,0) size 39x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 39x18 + text run at (0,15) width 39: "/ 0:06" + LayoutBlockFlow {DIV} at (90,48) size 86x0 + LayoutButton {INPUT} at (176,0) size 48x48 + LayoutButton {INPUT} at (224,0) size 48x48 + LayoutButton {INPUT} at (272,0) size 48x48 +layer at (8,276) size 320x16 + LayoutSlider {INPUT} at (0,224) size 320x16 [color=#C4C4C4] + LayoutFlexibleBox {DIV} at (16,0) size 288x4 +layer at (24,276) size 288x4 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF4D] +layer at (24,272) size 12x12 + LayoutBlockFlow (relative positioned) {DIV} at (0,-4) size 12x12 [bgcolor=#FFFFFF] +layer at (24,276) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 +layer at (24,276) size 0x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#FFFFFF] +layer at (24,276) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF8A] +layer at (332,52) size 320x240 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x240 + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (332,52) size 320x240 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 320x240 +layer at (332,52) size 320x240 + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (332,52) size 320x224 clip at (334,54) size 316x220 + LayoutButton (relative positioned) {INPUT} at (0,0) size 320x224 [border: (2px outset #C0C0C0)] + LayoutFlexibleBox (anonymous) at (8,82) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] +layer at (332,228) size 320x48 + LayoutFlexibleBox (relative positioned) {DIV} at (0,176) size 320x48 + LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 31x18 + text run at (0,15) width 31: "0:00" + LayoutBlockFlow {DIV} at (51,0) size 39x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 39x18 + text run at (0,15) width 39: "/ 0:06" + LayoutBlockFlow {DIV} at (90,48) size 86x0 + LayoutButton {INPUT} at (176,0) size 48x48 + LayoutButton {INPUT} at (224,0) size 48x48 + LayoutButton {INPUT} at (272,0) size 48x48 +layer at (332,276) size 320x16 + LayoutSlider {INPUT} at (0,224) size 320x16 [color=#C4C4C4] + LayoutFlexibleBox {DIV} at (16,0) size 288x4 +layer at (348,276) size 288x4 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF4D] +layer at (348,272) size 12x12 + LayoutBlockFlow (relative positioned) {DIV} at (0,-4) size 12x12 [bgcolor=#FFFFFF] +layer at (348,276) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 +layer at (348,276) size 0x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#FFFFFF] +layer at (348,276) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF8A]
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls-without-preload-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls-without-preload-expected.png new file mode 100644 index 0000000..8e94be13 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls-without-preload-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls-without-preload-expected.txt b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls-without-preload-expected.txt new file mode 100644 index 0000000..0e5c7f6 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls-without-preload-expected.txt
@@ -0,0 +1,48 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutBlockFlow {HTML} at (0,0) size 800x600 + LayoutBlockFlow {BODY} at (8,8) size 784x584 + LayoutBlockFlow {P} at (0,0) size 784x20 + LayoutText {#text} at (0,0) size 298x19 + text run at (0,0) width 298: "The controls should not depend on preload value." + LayoutBlockFlow (anonymous) at (0,36) size 784x240 + LayoutText {#text} at (0,0) size 0x0 +layer at (8,44) size 320x240 + LayoutVideo {VIDEO} at (0,0) size 320x240 +layer at (8,44) size 320x240 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x240 + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (8,44) size 320x240 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 320x240 +layer at (8,44) size 320x240 + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (8,44) size 320x224 clip at (10,46) size 316x220 + LayoutButton (relative positioned) {INPUT} at (0,0) size 320x224 [border: (2px outset #C0C0C0)] + LayoutFlexibleBox (anonymous) at (8,82) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] +layer at (8,220) size 320x48 + LayoutFlexibleBox (relative positioned) {DIV} at (0,176) size 320x48 + LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 31x18 + text run at (0,15) width 31: "0:00" + LayoutBlockFlow {DIV} at (51,0) size 39x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 39x18 + text run at (0,15) width 39: "/ 0:06" + LayoutBlockFlow {DIV} at (90,48) size 86x0 + LayoutButton {INPUT} at (176,0) size 48x48 + LayoutButton {INPUT} at (224,0) size 48x48 + LayoutButton {INPUT} at (272,0) size 48x48 +layer at (8,268) size 320x16 + LayoutSlider {INPUT} at (0,224) size 320x16 [color=#C4C4C4] + LayoutFlexibleBox {DIV} at (16,0) size 288x4 +layer at (24,268) size 288x4 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF4D] +layer at (24,264) size 12x12 + LayoutBlockFlow (relative positioned) {DIV} at (0,-4) size 12x12 [bgcolor=#FFFFFF] +layer at (24,268) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 +layer at (24,268) size 0x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#FFFFFF] +layer at (24,268) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF8A]
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls/lazy-loaded-style-expected.txt b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls/lazy-loaded-style-expected.txt new file mode 100644 index 0000000..8616e70 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls/lazy-loaded-style-expected.txt
@@ -0,0 +1,44 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x321 + LayoutBlockFlow {HTML} at (0,0) size 800x321 + LayoutBlockFlow {BODY} at (8,8) size 784x305 + LayoutText {#text} at (0,0) size 0x0 +layer at (8,8) size 400x300 + LayoutVideo {VIDEO} at (0,0) size 400x300 +layer at (8,8) size 400x300 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 400x300 + LayoutFlexibleBox {DIV} at (0,0) size 400x300 +layer at (8,8) size 400x300 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 400x300 +layer at (8,8) size 400x300 + LayoutFlexibleBox {DIV} at (0,0) size 400x300 +layer at (8,8) size 400x284 clip at (10,10) size 396x280 + LayoutButton (relative positioned) {INPUT} at (0,0) size 400x284 [border: (2px outset #C0C0C0)] + LayoutFlexibleBox (anonymous) at (8,104.50) size 384x75 + LayoutBlockFlow {DIV} at (154.50,0) size 75x75 [bgcolor=#FFFFFFE6] +layer at (8,244) size 400x48 + LayoutFlexibleBox (relative positioned) {DIV} at (0,236) size 400x48 + LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 31x18 + text run at (0,15) width 31: "0:00" + LayoutBlockFlow {DIV} at (51,0) size 39x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 39x18 + text run at (0,15) width 39: "/ 0:06" + LayoutBlockFlow {DIV} at (90,48) size 166x0 + LayoutButton {INPUT} at (256,0) size 48x48 + LayoutButton {INPUT} at (304,0) size 48x48 + LayoutButton {INPUT} at (352,0) size 48x48 +layer at (8,292) size 400x16 + LayoutSlider {INPUT} at (0,284) size 400x16 [color=#C4C4C4] + LayoutFlexibleBox {DIV} at (16,0) size 368x4 +layer at (24,292) size 368x4 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 368x4 [bgcolor=#FFFFFF4D] +layer at (24,288) size 12x12 + LayoutBlockFlow (relative positioned) {DIV} at (0,-4) size 12x12 [bgcolor=#FFFFFF] +layer at (24,292) size 368x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 368x4 +layer at (24,292) size 0x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#FFFFFF] +layer at (24,292) size 368x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 368x4 [bgcolor=#FFFFFF8A]
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png new file mode 100644 index 0000000..5d40014 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.txt b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.txt new file mode 100644 index 0000000..db54d4e --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-custom-bg-expected.txt
@@ -0,0 +1,45 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x348 + LayoutBlockFlow {HTML} at (0,0) size 800x348.27 + LayoutBlockFlow {BODY} at (8,8) size 784x332.27 + LayoutText {#text} at (0,0) size 0x0 +layer at (8,8) size 400x327 + LayoutVideo {VIDEO} at (0,0) size 400x327.27 +layer at (8,8) size 400x327 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 400x327.27 + LayoutFlexibleBox {DIV} at (0,0) size 400x327.27 +layer at (8,8) size 400x327 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 400x327.27 +layer at (8,8) size 400x327 + LayoutFlexibleBox {DIV} at (0,0) size 400x327.27 +layer at (8,8) size 400x311 clip at (10,10) size 396x307 + LayoutButton (relative positioned) {INPUT} at (0,0) size 400x311.27 [border: (2px outset #C0C0C0)] + LayoutFlexibleBox (anonymous) at (8,114.75) size 384x81.75 + LayoutBlockFlow {DIV} at (151.13,0) size 81.75x81.75 [bgcolor=#FFFFFFE6] +layer at (8,271) size 400x48 + LayoutFlexibleBox (relative positioned) {DIV} at (0,263.27) size 400x48 + LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 31x18 + text run at (0,15) width 31: "0:00" + LayoutBlockFlow {DIV} at (51,0) size 39x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 39x18 + text run at (0,15) width 39: "/ 0:09" + LayoutBlockFlow {DIV} at (90,48) size 166x0 + LayoutButton {INPUT} at (304,0) size 48x48 + LayoutButton {INPUT} at (352,0) size 48x48 +layer at (264,271) size 48x48 transparent + LayoutButton {INPUT} at (256,0) size 48x48 [color=#808080] +layer at (8,319) size 400x16 + LayoutSlider {INPUT} at (0,311.27) size 400x16 [color=#C4C4C4] + LayoutFlexibleBox {DIV} at (16,0) size 368x4 +layer at (24,319) size 368x4 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 368x4 [bgcolor=#FFFFFF4D] +layer at (24,315) size 12x12 + LayoutBlockFlow (relative positioned) {DIV} at (0,-4) size 12x12 [bgcolor=#FFFFFF] +layer at (24,319) size 368x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 368x4 +layer at (24,319) size 0x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#FFFFFF] +layer at (24,319) size 368x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 368x4 [bgcolor=#FFFFFF8A]
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-expected.png new file mode 100644 index 0000000..5d40014 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-expected.txt b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-expected.txt new file mode 100644 index 0000000..db54d4e --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/controls/paint-controls-webkit-appearance-none-expected.txt
@@ -0,0 +1,45 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x348 + LayoutBlockFlow {HTML} at (0,0) size 800x348.27 + LayoutBlockFlow {BODY} at (8,8) size 784x332.27 + LayoutText {#text} at (0,0) size 0x0 +layer at (8,8) size 400x327 + LayoutVideo {VIDEO} at (0,0) size 400x327.27 +layer at (8,8) size 400x327 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 400x327.27 + LayoutFlexibleBox {DIV} at (0,0) size 400x327.27 +layer at (8,8) size 400x327 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 400x327.27 +layer at (8,8) size 400x327 + LayoutFlexibleBox {DIV} at (0,0) size 400x327.27 +layer at (8,8) size 400x311 clip at (10,10) size 396x307 + LayoutButton (relative positioned) {INPUT} at (0,0) size 400x311.27 [border: (2px outset #C0C0C0)] + LayoutFlexibleBox (anonymous) at (8,114.75) size 384x81.75 + LayoutBlockFlow {DIV} at (151.13,0) size 81.75x81.75 [bgcolor=#FFFFFFE6] +layer at (8,271) size 400x48 + LayoutFlexibleBox (relative positioned) {DIV} at (0,263.27) size 400x48 + LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 31x18 + text run at (0,15) width 31: "0:00" + LayoutBlockFlow {DIV} at (51,0) size 39x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 39x18 + text run at (0,15) width 39: "/ 0:09" + LayoutBlockFlow {DIV} at (90,48) size 166x0 + LayoutButton {INPUT} at (304,0) size 48x48 + LayoutButton {INPUT} at (352,0) size 48x48 +layer at (264,271) size 48x48 transparent + LayoutButton {INPUT} at (256,0) size 48x48 [color=#808080] +layer at (8,319) size 400x16 + LayoutSlider {INPUT} at (0,311.27) size 400x16 [color=#C4C4C4] + LayoutFlexibleBox {DIV} at (16,0) size 368x4 +layer at (24,319) size 368x4 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 368x4 [bgcolor=#FFFFFF4D] +layer at (24,315) size 12x12 + LayoutBlockFlow (relative positioned) {DIV} at (0,-4) size 12x12 [bgcolor=#FFFFFF] +layer at (24,319) size 368x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 368x4 +layer at (24,319) size 0x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#FFFFFF] +layer at (24,319) size 368x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 368x4 [bgcolor=#FFFFFF8A]
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/video-controls-rendering-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/video-controls-rendering-expected.png new file mode 100644 index 0000000..3b93cbe --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/video-controls-rendering-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/video-controls-rendering-expected.txt b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/video-controls-rendering-expected.txt new file mode 100644 index 0000000..630f45f9 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/video-controls-rendering-expected.txt
@@ -0,0 +1,127 @@ +layer at (0,0) size 800x600 clip at (0,0) size 785x600 scrollHeight 764 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 785x600 + LayoutBlockFlow {HTML} at (0,0) size 785x600 + LayoutBlockFlow {BODY} at (8,8) size 769x584 + LayoutBlockFlow {P} at (0,0) size 769x20 + LayoutText {#text} at (0,0) size 146x19 + text run at (0,0) width 146: "Test controls placement." + LayoutBlockFlow {DIV} at (0,36) size 769x240 + LayoutText {#text} at (0,0) size 0x0 + LayoutBlockFlow {DIV} at (0,276) size 769x240 + LayoutText {#text} at (0,0) size 0x0 + LayoutBlockFlow {DIV} at (0,516) size 769x0 +layer at (8,44) size 320x240 + LayoutVideo {VIDEO} at (0,0) size 320x240 +layer at (8,284) size 320x240 + LayoutVideo {VIDEO} at (0,0) size 320x240 +layer at (8,44) size 320x240 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x240 + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (8,44) size 320x240 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 320x240 +layer at (8,44) size 320x240 + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (8,44) size 320x224 clip at (10,46) size 316x220 + LayoutButton (relative positioned) {INPUT} at (0,0) size 320x224 [border: (2px outset #C0C0C0)] + LayoutFlexibleBox (anonymous) at (8,82) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] +layer at (8,220) size 320x48 + LayoutFlexibleBox (relative positioned) {DIV} at (0,176) size 320x48 + LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 31x18 + text run at (0,15) width 31: "0:00" + LayoutBlockFlow {DIV} at (51,0) size 39x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 39x18 + text run at (0,15) width 39: "/ 0:06" + LayoutBlockFlow {DIV} at (90,48) size 86x0 + LayoutButton {INPUT} at (176,0) size 48x48 + LayoutButton {INPUT} at (224,0) size 48x48 + LayoutButton {INPUT} at (272,0) size 48x48 +layer at (8,268) size 320x16 + LayoutSlider {INPUT} at (0,224) size 320x16 [color=#C4C4C4] + LayoutFlexibleBox {DIV} at (16,0) size 288x4 +layer at (24,268) size 288x4 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF4D] +layer at (24,264) size 12x12 + LayoutBlockFlow (relative positioned) {DIV} at (0,-4) size 12x12 [bgcolor=#FFFFFF] +layer at (24,268) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 +layer at (24,268) size 0x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#FFFFFF] +layer at (24,268) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF8A] +layer at (8,284) size 320x240 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x240 + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (8,284) size 320x240 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 320x240 +layer at (8,284) size 320x240 + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (8,284) size 320x224 clip at (10,286) size 316x220 + LayoutButton (relative positioned) {INPUT} at (0,0) size 320x224 [border: (2px outset #C0C0C0)] + LayoutFlexibleBox (anonymous) at (8,82) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] +layer at (8,460) size 320x48 + LayoutFlexibleBox (relative positioned) {DIV} at (0,176) size 320x48 + LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 31x18 + text run at (0,15) width 31: "0:00" + LayoutBlockFlow {DIV} at (51,0) size 39x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 39x18 + text run at (0,15) width 39: "/ 0:06" + LayoutBlockFlow {DIV} at (90,48) size 86x0 + LayoutButton {INPUT} at (176,0) size 48x48 + LayoutButton {INPUT} at (224,0) size 48x48 + LayoutButton {INPUT} at (272,0) size 48x48 +layer at (8,508) size 320x16 + LayoutSlider {INPUT} at (0,224) size 320x16 [color=#C4C4C4] + LayoutFlexibleBox {DIV} at (16,0) size 288x4 +layer at (24,508) size 288x4 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF4D] +layer at (24,504) size 12x12 + LayoutBlockFlow (relative positioned) {DIV} at (0,-4) size 12x12 [bgcolor=#FFFFFF] +layer at (24,508) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 +layer at (24,508) size 0x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#FFFFFF] +layer at (24,508) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF8A] +layer at (8,524) size 320x240 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600 + LayoutVideo (positioned) {VIDEO} at (8,524) size 320x240 +layer at (8,524) size 320x240 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x240 + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (8,524) size 320x240 backgroundClip at (0,0) size 785x600 clip at (0,0) size 785x600 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 320x240 +layer at (8,524) size 320x240 backgroundClip at (8,524) size 320x76 clip at (8,524) size 320x76 + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (8,524) size 320x224 backgroundClip at (8,524) size 320x76 clip at (10,526) size 316x74 + LayoutButton (relative positioned) {INPUT} at (0,0) size 320x224 [border: (2px outset #C0C0C0)] + LayoutFlexibleBox (anonymous) at (8,82) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] +layer at (8,700) size 320x48 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0 + LayoutFlexibleBox (relative positioned) {DIV} at (0,176) size 320x48 + LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 31x18 + text run at (0,15) width 31: "0:00" + LayoutBlockFlow {DIV} at (51,0) size 39x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 39x18 + text run at (0,15) width 39: "/ 0:06" + LayoutBlockFlow {DIV} at (90,48) size 86x0 + LayoutButton {INPUT} at (176,0) size 48x48 + LayoutButton {INPUT} at (224,0) size 48x48 + LayoutButton {INPUT} at (272,0) size 48x48 +layer at (8,748) size 320x16 backgroundClip at (8,524) size 320x76 clip at (8,524) size 320x76 + LayoutSlider {INPUT} at (0,224) size 320x16 [color=#C4C4C4] + LayoutFlexibleBox {DIV} at (16,0) size 288x4 +layer at (24,748) size 288x4 backgroundClip at (8,524) size 320x76 clip at (8,524) size 320x76 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF4D] +layer at (24,744) size 12x12 backgroundClip at (8,524) size 320x76 clip at (8,524) size 320x76 + LayoutBlockFlow (relative positioned) {DIV} at (0,-4) size 12x12 [bgcolor=#FFFFFF] +layer at (24,748) size 288x4 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 +layer at (24,748) size 0x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#FFFFFF] +layer at (24,748) size 288x4 backgroundClip at (0,0) size 0x0 clip at (0,0) size 0x0 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF8A]
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/video-display-toggle-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/video-display-toggle-expected.png new file mode 100644 index 0000000..f4e0d0d --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/video-display-toggle-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/video-display-toggle-expected.txt b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/video-display-toggle-expected.txt new file mode 100644 index 0000000..9c7d05b8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/video-display-toggle-expected.txt
@@ -0,0 +1,47 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutBlockFlow {HTML} at (0,0) size 800x600 + LayoutBlockFlow {BODY} at (8,8) size 784x584 + LayoutText {#text} at (0,0) size 470x19 + text run at (0,0) width 470: "This tests that toggling the display property won't make the controls disappear." + LayoutBR {BR} at (470,15) size 0x0 + LayoutText {#text} at (0,0) size 0x0 +layer at (8,28) size 320x240 + LayoutVideo {VIDEO} at (0,20) size 320x240 +layer at (8,28) size 320x240 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 320x240 + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (8,28) size 320x240 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 320x240 +layer at (8,28) size 320x240 + LayoutFlexibleBox {DIV} at (0,0) size 320x240 +layer at (8,28) size 320x224 clip at (10,30) size 316x220 + LayoutButton (relative positioned) {INPUT} at (0,0) size 320x224 [border: (2px outset #C0C0C0)] + LayoutFlexibleBox (anonymous) at (8,82) size 304x60 + LayoutBlockFlow {DIV} at (122,0) size 60x60 [bgcolor=#FFFFFFE6] +layer at (8,204) size 320x48 + LayoutFlexibleBox (relative positioned) {DIV} at (0,176) size 320x48 + LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 31x18 + text run at (0,15) width 31: "0:00" + LayoutBlockFlow {DIV} at (51,0) size 39x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 39x18 + text run at (0,15) width 39: "/ 0:06" + LayoutBlockFlow {DIV} at (90,48) size 86x0 + LayoutButton {INPUT} at (176,0) size 48x48 + LayoutButton {INPUT} at (224,0) size 48x48 + LayoutButton {INPUT} at (272,0) size 48x48 +layer at (8,252) size 320x16 + LayoutSlider {INPUT} at (0,224) size 320x16 [color=#C4C4C4] + LayoutFlexibleBox {DIV} at (16,0) size 288x4 +layer at (24,252) size 288x4 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF4D] +layer at (24,248) size 12x12 + LayoutBlockFlow (relative positioned) {DIV} at (0,-4) size 12x12 [bgcolor=#FFFFFF] +layer at (24,252) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 +layer at (24,252) size 0x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#FFFFFF] +layer at (24,252) size 288x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x4 [bgcolor=#FFFFFF8A]
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/video-no-audio-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/video-no-audio-expected.png new file mode 100644 index 0000000..8b0aec58 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/video-no-audio-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/video-no-audio-expected.txt b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/video-no-audio-expected.txt new file mode 100644 index 0000000..e2579c18b --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/video-no-audio-expected.txt
@@ -0,0 +1,49 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutBlockFlow {HTML} at (0,0) size 800x600 + LayoutBlockFlow {BODY} at (8,8) size 784x584 + LayoutBlockFlow {P} at (0,0) size 784x20 + LayoutText {#text} at (0,0) size 391x19 + text run at (0,0) width 391: "Movie with no audio track. The volume button should not render." + LayoutBlockFlow (anonymous) at (0,36) size 784x288 + LayoutText {#text} at (0,0) size 0x0 +layer at (8,44) size 352x288 + LayoutVideo {VIDEO} at (0,0) size 352x288 +layer at (8,44) size 352x288 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 352x288 + LayoutFlexibleBox {DIV} at (0,0) size 352x288 +layer at (8,44) size 352x288 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 352x288 +layer at (8,44) size 352x288 + LayoutFlexibleBox {DIV} at (0,0) size 352x288 +layer at (8,44) size 352x272 clip at (10,46) size 348x268 + LayoutButton (relative positioned) {INPUT} at (0,0) size 352x272 [border: (2px outset #C0C0C0)] + LayoutFlexibleBox (anonymous) at (8,100) size 336x72 + LayoutBlockFlow {DIV} at (132,0) size 72x72 [bgcolor=#FFFFFFE6] +layer at (8,268) size 352x48 + LayoutFlexibleBox (relative positioned) {DIV} at (0,224) size 352x48 + LayoutBlockFlow {DIV} at (16,0) size 31x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 31x18 + text run at (0,15) width 31: "0:00" + LayoutBlockFlow {DIV} at (51,0) size 39x48 [color=#FFFFFF] + LayoutText {#text} at (0,15) size 39x18 + text run at (0,15) width 39: "/ 0:09" + LayoutBlockFlow {DIV} at (90,48) size 118x0 + LayoutButton {INPUT} at (256,0) size 48x48 + LayoutButton {INPUT} at (304,0) size 48x48 +layer at (216,268) size 48x48 transparent + LayoutButton {INPUT} at (208,0) size 48x48 [color=#808080] +layer at (8,316) size 352x16 + LayoutSlider {INPUT} at (0,272) size 352x16 [color=#C4C4C4] + LayoutFlexibleBox {DIV} at (16,0) size 320x4 +layer at (24,316) size 320x4 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 320x4 [bgcolor=#FFFFFF4D] +layer at (24,312) size 12x12 + LayoutBlockFlow (relative positioned) {DIV} at (0,-4) size 12x12 [bgcolor=#FFFFFF] +layer at (24,316) size 320x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 320x4 +layer at (24,316) size 0x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x4 [bgcolor=#FFFFFF] +layer at (24,316) size 320x4 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 320x4 [bgcolor=#FFFFFF8A]
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/video-zoom-controls-expected.txt b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/video-zoom-controls-expected.txt new file mode 100644 index 0000000..684068a0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/video-surface-layer/media/video-zoom-controls-expected.txt
@@ -0,0 +1,86 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutBlockFlow {HTML} at (0,0) size 800x600 + LayoutBlockFlow {BODY} at (12,12) size 776x543 + LayoutBlockFlow {P} at (0,0) size 776x28 + LayoutText {#text} at (0,0) size 275x27 + text run at (0,0) width 275: "Zoomed video with controls." +layer at (57,85) size 240x180 + LayoutVideo {VIDEO} at (45,73) size 240x180 +layer at (57,85) size 240x180 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 240x180 + LayoutFlexibleBox {DIV} at (0,0) size 240x180 +layer at (57,85) size 240x180 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 240x180 +layer at (57,85) size 240x180 + LayoutFlexibleBox {DIV} at (0,0) size 240x180 +layer at (57,85) size 240x156 clip at (60,88) size 234x150 + LayoutButton (relative positioned) {INPUT} at (0,0) size 240x156 [border: (3px outset #C0C0C0)] + LayoutFlexibleBox (anonymous) at (12,42) size 216x72 + LayoutBlockFlow {DIV} at (72,0) size 72x72 [bgcolor=#FFFFFFE6] +layer at (57,169) size 240x72 scrollWidth 338 + LayoutFlexibleBox (relative positioned) {DIV} at (0,84) size 240x72 + LayoutBlockFlow {DIV} at (24,0) size 46x72 [color=#FFFFFF] + LayoutText {#text} at (0,22) size 46x27 + text run at (0,22) width 46: "0:00" + LayoutBlockFlow {DIV} at (76,-72) size 46x144 [color=#FFFFFF] + LayoutText {#text} at (0,22) size 46x99 + text run at (0,22) width 7: "/" + text run at (0,94) width 46: "0:06" + LayoutBlockFlow {DIV} at (122,72) size 0x0 + LayoutButton {INPUT} at (122,0) size 72x72 + LayoutButton {INPUT} at (194,0) size 72x72 + LayoutButton {INPUT} at (266,0) size 72x72 +layer at (57,241) size 240x24 + LayoutSlider {INPUT} at (0,156) size 240x24 [color=#C4C4C4] + LayoutFlexibleBox {DIV} at (24,0) size 192x6 +layer at (81,241) size 192x6 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 192x6 [bgcolor=#FFFFFF4D] +layer at (81,235) size 18x18 + LayoutBlockFlow (relative positioned) {DIV} at (0,-6) size 18x18 [bgcolor=#FFFFFF] +layer at (81,241) size 192x6 scrollWidth 288 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 192x6 +layer at (81,241) size 0x6 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x6 [bgcolor=#FFFFFF] +layer at (81,241) size 288x6 backgroundClip at (81,241) size 192x6 clip at (81,241) size 192x6 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x6 [bgcolor=#FFFFFF8A] +layer at (57,310) size 240x180 + LayoutVideo {VIDEO} at (45,298) size 240x180 +layer at (57,310) size 240x180 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 240x180 + LayoutFlexibleBox {DIV} at (0,0) size 240x180 +layer at (57,310) size 240x180 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 240x180 +layer at (57,310) size 240x180 + LayoutFlexibleBox {DIV} at (0,0) size 240x180 +layer at (57,310) size 240x156 clip at (60,313) size 234x150 + LayoutButton (relative positioned) {INPUT} at (0,0) size 240x156 [border: (3px outset #C0C0C0)] + LayoutFlexibleBox (anonymous) at (12,42) size 216x72 + LayoutBlockFlow {DIV} at (72,0) size 72x72 [bgcolor=#FFFFFFE6] +layer at (57,394) size 240x72 backgroundClip at (47,373) size 249x113 clip at (57,394) size 239x72 scrollWidth 338 + LayoutFlexibleBox (relative positioned) {DIV} at (0,84) size 240x72 + LayoutBlockFlow {DIV} at (24,0) size 46x72 [color=#FFFFFF] + LayoutText {#text} at (0,22) size 46x27 + text run at (0,22) width 46: "0:00" + LayoutBlockFlow {DIV} at (76,-72) size 46x144 [color=#FFFFFF] + LayoutText {#text} at (0,22) size 46x99 + text run at (0,22) width 7: "/" + text run at (0,94) width 46: "0:06" + LayoutBlockFlow {DIV} at (122,72) size 0x0 + LayoutButton {INPUT} at (122,0) size 72x72 + LayoutButton {INPUT} at (194,0) size 72x72 + LayoutButton {INPUT} at (266,0) size 72x72 +layer at (57,466) size 240x24 + LayoutSlider {INPUT} at (0,156) size 240x24 [color=#C4C4C4] + LayoutFlexibleBox {DIV} at (24,0) size 192x6 +layer at (81,466) size 192x6 + LayoutBlockFlow (relative positioned) {DIV} at (0,0) size 192x6 [bgcolor=#FFFFFF4D] +layer at (81,460) size 18x18 + LayoutBlockFlow (relative positioned) {DIV} at (0,-6) size 18x18 [bgcolor=#FFFFFF] +layer at (81,466) size 192x6 backgroundClip at (70,448) size 190x40 clip at (81,466) size 179x6 scrollWidth 288 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 192x6 +layer at (81,466) size 0x6 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 0x6 [bgcolor=#FFFFFF] +layer at (81,466) size 288x6 backgroundClip at (70,448) size 190x40 clip at (70,448) size 190x40 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 288x6 [bgcolor=#FFFFFF8A]
diff --git a/third_party/WebKit/LayoutTests/resources/gesture-util.js b/third_party/WebKit/LayoutTests/resources/gesture-util.js index e31c716..1084bc42 100644 --- a/third_party/WebKit/LayoutTests/resources/gesture-util.js +++ b/third_party/WebKit/LayoutTests/resources/gesture-util.js
@@ -197,16 +197,16 @@ // Simulate a mouse drag and drop. mouse down at {start_x, start_y}, move to // {end_x, end_y} and release. -function mouseDragAndDrop(start_x, start_y, end_x, end_y) { +function mouseDragAndDrop(start_x, start_y, end_x, end_y, button = 'left') { return new Promise((resolve, reject) => { if (chrome && chrome.gpuBenchmarking) { let pointerActions = [{ source: 'mouse', actions: [ { 'name': 'pointerMove', 'x': start_x, 'y': start_y }, - { 'name': 'pointerDown', 'x': start_x, 'y': start_y }, + { 'name': 'pointerDown', 'x': start_x, 'y': start_y, 'button': button }, { 'name': 'pointerMove', 'x': end_x, 'y': end_y }, - { 'name': 'pointerUp' }, + { 'name': 'pointerUp', 'button': button }, ] }]; chrome.gpuBenchmarking.pointerActionSequence(pointerActions, resolve);
diff --git a/third_party/WebKit/LayoutTests/virtual/picture-in-picture/external/wpt/feature-policy/README.txt b/third_party/WebKit/LayoutTests/virtual/picture-in-picture/external/wpt/feature-policy/README.txt deleted file mode 100644 index e808a099..0000000 --- a/third_party/WebKit/LayoutTests/virtual/picture-in-picture/external/wpt/feature-policy/README.txt +++ /dev/null
@@ -1 +0,0 @@ -This suite runs Picture-in-Picture tests with the UseSurfaceLayerForVideo feature enabled.
diff --git a/third_party/WebKit/LayoutTests/virtual/picture-in-picture/media/picture-in-picture/README.txt b/third_party/WebKit/LayoutTests/virtual/picture-in-picture/media/picture-in-picture/README.txt deleted file mode 100644 index 72016a7..0000000 --- a/third_party/WebKit/LayoutTests/virtual/picture-in-picture/media/picture-in-picture/README.txt +++ /dev/null
@@ -1 +0,0 @@ -This suite runs Picture-in-Picture tests with PictureInPicture and UseSurfaceLayerForVideo features enabled.
diff --git a/third_party/WebKit/LayoutTests/virtual/video-surface-layer/external/wpt/feature-policy/README.txt b/third_party/WebKit/LayoutTests/virtual/video-surface-layer/external/wpt/feature-policy/README.txt new file mode 100644 index 0000000..ba4315e --- /dev/null +++ b/third_party/WebKit/LayoutTests/virtual/video-surface-layer/external/wpt/feature-policy/README.txt
@@ -0,0 +1 @@ +This suite runs Feature Policy tests with the UseSurfaceLayerForVideo feature enabled.
diff --git a/third_party/WebKit/LayoutTests/virtual/picture-in-picture/external/wpt/picture-in-picture/README.txt b/third_party/WebKit/LayoutTests/virtual/video-surface-layer/external/wpt/picture-in-picture/README.txt similarity index 100% rename from third_party/WebKit/LayoutTests/virtual/picture-in-picture/external/wpt/picture-in-picture/README.txt rename to third_party/WebKit/LayoutTests/virtual/video-surface-layer/external/wpt/picture-in-picture/README.txt
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt index a2ce21b..f20fb32 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -9146,7 +9146,7 @@ interface XRInputSource attribute @@toStringTag getter handedness - getter pointerOrigin + getter targetRayMode method constructor interface XRInputSourceEvent : Event attribute @@toStringTag
diff --git a/third_party/WebKit/LayoutTests/xr/getInputPose_hand.html b/third_party/WebKit/LayoutTests/xr/getInputPose_hand.html index 1984a81..80f665e 100644 --- a/third_party/WebKit/LayoutTests/xr/getInputPose_hand.html +++ b/third_party/WebKit/LayoutTests/xr/getInputPose_hand.html
@@ -19,7 +19,7 @@ setPose(VALID_POSE); let input_source = new MockXRInputSource(); - input_source.pointerOrigin = "hand"; + input_source.targetRayMode = "pointing"; input_source.handedness = "right"; // Don't set a grip matrix yet @@ -37,7 +37,7 @@ t.step( () => { // The input pose should be null when no grip matrix is provided. - assert_equals(source.pointerOrigin, "hand"); + assert_equals(source.targetRayMode, "pointing"); assert_equals(input_pose, null); });
diff --git a/third_party/WebKit/LayoutTests/xr/resources/xr-device-mocking.js b/third_party/WebKit/LayoutTests/xr/resources/xr-device-mocking.js index b13ceec2..476bffc 100644 --- a/third_party/WebKit/LayoutTests/xr/resources/xr-device-mocking.js +++ b/third_party/WebKit/LayoutTests/xr/resources/xr-device-mocking.js
@@ -596,7 +596,7 @@ this.primary_input_clicked_ = false; this.grip_ = null; - this.pointer_origin_ = "head"; + this.target_ray_mode_ = "gazing"; this.pointer_offset_ = null; this.emulated_position_ = false; this.handedness_ = ""; @@ -630,14 +630,14 @@ this.grip_.matrix = new Float32Array(value); } - get pointerOrigin() { - return this.pointer_origin_; + get targetRayMode() { + return this.target_ray_mode_; } - set pointerOrigin(value) { - if (this.pointer_origin_ != value) { + set targetRayMode(value) { + if (this.target_ray_mode_ != value) { this.desc_dirty_ = true; - this.pointer_origin_ = value; + this.target_ray_mode_ = value; } } @@ -695,12 +695,12 @@ input_desc.emulatedPosition = this.emulated_position_; - switch (this.pointer_origin_) { - case "head": - input_desc.pointerOrigin = device.mojom.XRPointerOrigin.HEAD; + switch (this.target_ray_mode_) { + case "gazing": + input_desc.targetRayMode = device.mojom.XRTargetRayMode.GAZING; break; - case "hand": - input_desc.pointerOrigin = device.mojom.XRPointerOrigin.HAND; + case "pointing": + input_desc.targetRayMode = device.mojom.XRTargetRayMode.POINTING; break; }
diff --git a/third_party/WebKit/LayoutTests/xr/xrInputSource_add_remove.html b/third_party/WebKit/LayoutTests/xr/xrInputSource_add_remove.html index e215aff..a496105b 100644 --- a/third_party/WebKit/LayoutTests/xr/xrInputSource_add_remove.html +++ b/third_party/WebKit/LayoutTests/xr/xrInputSource_add_remove.html
@@ -25,7 +25,7 @@ }); let input_source_1 = new MockXRInputSource(); - input_source_1.pointerOrigin = "hand"; + input_source_1.targetRayMode = "pointing"; input_source_1.handedness = "right"; addInputSource(input_source_1); @@ -35,12 +35,12 @@ t.step( () => { assert_equals(input_sources.length, 1); - assert_equals(input_sources[0].pointerOrigin, "hand"); + assert_equals(input_sources[0].targetRayMode, "pointing"); assert_equals(input_sources[0].handedness, "right"); }); let input_source_2 = new MockXRInputSource(); - input_source_2.pointerOrigin = "head"; + input_source_2.targetRayMode = "gazing"; input_source_2.emulatedPosition = "true"; addInputSource(input_source_2); @@ -49,7 +49,7 @@ t.step( () => { assert_equals(input_sources.length, 2); - assert_equals(input_sources[1].pointerOrigin, "head"); + assert_equals(input_sources[1].targetRayMode, "gazing"); assert_equals(input_sources[1].handedness, ""); }); @@ -60,7 +60,7 @@ t.step( () => { assert_equals(input_sources.length, 1); - assert_equals(input_sources[0].pointerOrigin, "head"); + assert_equals(input_sources[0].targetRayMode, "gazing"); assert_equals(input_sources[0].handedness, ""); });
diff --git a/third_party/blink/perf_tests/layout/large-spanning-grid-item.html b/third_party/blink/perf_tests/layout/large-spanning-grid-item.html new file mode 100644 index 0000000..520bbf14 --- /dev/null +++ b/third_party/blink/perf_tests/layout/large-spanning-grid-item.html
@@ -0,0 +1,35 @@ +<!DOCTYPE html> +<style> +.gridItem { + grid-column: span 100; + grid-row: span 100; +} +#grid { + display: grid; + grid-auto-rows: 2px; + grid-auto-columns: 5px; +} +</style> +<script src="../resources/runner.js"></script> +<script> +function startTest() { + PerfTestRunner.forceLayout(); + + var index = 0; + var grid = document.getElementById("grid"); + PerfTestRunner.measureRunsPerSecond({ + description: "Measures performance of layout on a page using CSS grid layout (item placement).", + run: function() { + // This style change forces the grid to place the item again, and thus regenerate the data structure holding the grid. + grid.style.gridAutoFlow = ++index % 2 ? "row" : "column"; + PerfTestRunner.forceLayout(); + } + }); +} +</script> + +<body onload="startTest()"> +<div id="grid""> + <div class="gridItem" style="background: lime"></div> +</div> +</body>
diff --git a/third_party/blink/public/BUILD.gn b/third_party/blink/public/BUILD.gn index 3e0a2f4..3bbc183 100644 --- a/third_party/blink/public/BUILD.gn +++ b/third_party/blink/public/BUILD.gn
@@ -739,7 +739,6 @@ ":web_client_hints_types_mojo_bindings", ":web_feature_mojo_bindings", "//components/payments/mojom", - "//components/services/font/public/interfaces", "//device/bluetooth/public/mojom", "//mojo/public/mojom/base", "//services/device/public/mojom",
diff --git a/third_party/blink/public/platform/web_feature.mojom b/third_party/blink/public/platform/web_feature.mojom index 44e91a0..c164976 100644 --- a/third_party/blink/public/platform/web_feature.mojom +++ b/third_party/blink/public/platform/web_feature.mojom
@@ -1956,6 +1956,7 @@ kDocumentOpenTwoArgs = 2494, kDocumentOpenTwoArgsWithReplace = 2495, kDocumentOpenThreeArgs = 2496, + kV8FunctionTokenOffsetTooLongForToString = 2497, // 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_rtc_peer_connection_handler_client.h b/third_party/blink/public/platform/web_rtc_peer_connection_handler_client.h index 13bfabd..8116803 100644 --- a/third_party/blink/public/platform/web_rtc_peer_connection_handler_client.h +++ b/third_party/blink/public/platform/web_rtc_peer_connection_handler_client.h
@@ -72,8 +72,8 @@ webrtc::PeerConnectionInterface::SignalingState) = 0; virtual void DidChangeICEGatheringState(ICEGatheringState) = 0; virtual void DidChangeICEConnectionState(ICEConnectionState) = 0; - virtual void DidAddRemoteTrack(std::unique_ptr<WebRTCRtpReceiver>) = 0; - virtual void DidRemoveRemoteTrack(std::unique_ptr<WebRTCRtpReceiver>) = 0; + virtual void DidAddReceiver(std::unique_ptr<WebRTCRtpReceiver>) = 0; + virtual void DidRemoveReceiver(std::unique_ptr<WebRTCRtpReceiver>) = 0; virtual void DidAddRemoteDataChannel(WebRTCDataChannelHandler*) = 0; virtual void ReleasePeerConnectionHandler() = 0; virtual void ClosePeerConnection();
diff --git a/third_party/blink/public/platform/web_rtc_rtp_receiver.h b/third_party/blink/public/platform/web_rtc_rtp_receiver.h index b822485a..36accec0 100644 --- a/third_party/blink/public/platform/web_rtc_rtp_receiver.h +++ b/third_party/blink/public/platform/web_rtc_rtp_receiver.h
@@ -13,7 +13,6 @@ namespace blink { -class WebMediaStream; class WebMediaStreamTrack; class WebRTCRtpContributingSource; @@ -29,7 +28,7 @@ // the same |id|. virtual uintptr_t Id() const = 0; virtual const WebMediaStreamTrack& Track() const = 0; - virtual WebVector<WebMediaStream> Streams() const = 0; + virtual WebVector<WebString> StreamIds() const = 0; virtual WebVector<std::unique_ptr<WebRTCRtpContributingSource>> GetSources() = 0; virtual void GetStats(std::unique_ptr<blink::WebRTCStatsReportCallback>) = 0;
diff --git a/third_party/blink/public/platform/web_rtc_rtp_sender.h b/third_party/blink/public/platform/web_rtc_rtp_sender.h index c34e4c92..dbf7ac96 100644 --- a/third_party/blink/public/platform/web_rtc_rtp_sender.h +++ b/third_party/blink/public/platform/web_rtc_rtp_sender.h
@@ -13,7 +13,6 @@ namespace blink { -class WebMediaStream; class WebMediaStreamTrack; class WebRTCDTMFSenderHandler; @@ -30,7 +29,7 @@ // allowed to be reused after a sender is destroyed. virtual uintptr_t Id() const = 0; virtual WebMediaStreamTrack Track() const = 0; - virtual WebVector<WebMediaStream> Streams() const = 0; + virtual WebVector<WebString> StreamIds() const = 0; // TODO(hbos): Replace WebRTCVoidRequest by something resolving promises based // on RTCError, as to surface both exception type and error message. // https://crbug.com/790007
diff --git a/third_party/blink/renderer/bindings/core/v8/custom/v8_window_custom.cc b/third_party/blink/renderer/bindings/core/v8/custom/v8_window_custom.cc index 1af93c1..5871aa0 100644 --- a/third_party/blink/renderer/bindings/core/v8/custom/v8_window_custom.cc +++ b/third_party/blink/renderer/bindings/core/v8/custom/v8_window_custom.cc
@@ -198,69 +198,6 @@ } } -void V8Window::postMessageMethodCustom( - const v8::FunctionCallbackInfo<v8::Value>& info) { - ExceptionState exception_state(info.GetIsolate(), - ExceptionState::kExecutionContext, "Window", - "postMessage"); - if (UNLIKELY(info.Length() < 2)) { - exception_state.ThrowTypeError( - ExceptionMessages::NotEnoughArguments(2, info.Length())); - return; - } - - // None of these need to be RefPtr because info and context are guaranteed - // to hold on to them. - DOMWindow* window = V8Window::ToImpl(info.Holder()); - // TODO(yukishiino): The HTML spec specifies that we should use the - // Incumbent Realm instead of the Current Realm, but currently we don't have - // a way to retrieve the Incumbent Realm. See also: - // https://html.spec.whatwg.org/multipage/comms.html#dom-window-postmessage - LocalDOMWindow* source = CurrentDOMWindow(info.GetIsolate()); - - DCHECK(window); - UseCounter::Count(source->GetFrame(), WebFeature::kWindowPostMessage); - - // If called directly by WebCore we don't have a calling context. - if (!source) { - exception_state.ThrowTypeError("No active calling context exists."); - return; - } - - // This function has variable arguments and can be: - // postMessage(message, targetOrigin) - // postMessage(message, targetOrigin, {sequence of transferrables}) - // TODO(foolip): Type checking of the arguments should happen in order, so - // that e.g. postMessage({}, { toString: () => { throw Error(); } }, 0) - // throws the Error from toString, not the TypeError for argument 3. - Transferables transferables; - const int kTargetOriginArgIndex = 1; - if (info.Length() > 2) { - const int kTransferablesArgIndex = 2; - if (!SerializedScriptValue::ExtractTransferables( - info.GetIsolate(), info[kTransferablesArgIndex], - kTransferablesArgIndex, transferables, exception_state)) { - return; - } - } - // TODO(foolip): targetOrigin should be a USVString in IDL and treated as - // such here, without TreatNullAndUndefinedAsNullString. - TOSTRING_VOID(V8StringResource<kTreatNullAndUndefinedAsNullString>, - target_origin, info[kTargetOriginArgIndex]); - - SerializedScriptValue::SerializeOptions options; - options.transferables = &transferables; - scoped_refptr<SerializedScriptValue> message = - SerializedScriptValue::Serialize(info.GetIsolate(), info[0], options, - exception_state); - if (exception_state.HadException()) - return; - - message->UnregisterMemoryAllocatedWithCurrentScriptContext(); - window->postMessage(std::move(message), transferables.message_ports, - target_origin, source, exception_state); -} - void V8Window::namedPropertyGetterCustom( const AtomicString& name, const v8::PropertyCallbackInfo<v8::Value>& info) {
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.cc b/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.cc index f9ba4bbc..0c96584 100644 --- a/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.cc +++ b/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.cc
@@ -32,6 +32,7 @@ #include <algorithm> #include <memory> + #include "base/numerics/checked_math.h" #include "base/sys_byteorder.h" #include "third_party/blink/public/web/web_serialized_script_value_version.h" @@ -429,15 +430,24 @@ if (value.IsEmpty() || value->IsUndefined()) return true; - Vector<ScriptValue> transferable_array = + const Vector<ScriptValue>& transferable_array = NativeValueTraits<IDLSequence<ScriptValue>>::NativeValue(isolate, value, exception_state); if (exception_state.HadException()) return false; + return ExtractTransferables(isolate, transferable_array, transferables, + exception_state); +} + +bool SerializedScriptValue::ExtractTransferables( + v8::Isolate* isolate, + const Vector<ScriptValue>& object_sequence, + Transferables& transferables, + ExceptionState& exception_state) { // Validate the passed array of transferables. uint32_t i = 0; - for (const auto& script_value : transferable_array) { + for (const auto& script_value : object_sequence) { v8::Local<v8::Value> transferable_object = script_value.V8Value(); // Validation of non-null objects, per HTML5 spec 10.3.3. if (IsUndefinedOrNull(transferable_object)) {
diff --git a/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h b/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h index de1f552..e8218fb 100644 --- a/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h +++ b/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h
@@ -49,13 +49,14 @@ namespace blink { class BlobDataHandle; -class Transferables; +class DOMSharedArrayBuffer; class ExceptionState; +class ScriptValue; class SharedBuffer; class StaticBitmapImage; +class Transferables; class UnpackedSerializedScriptValue; class WebBlobInfo; -class DOMSharedArrayBuffer; typedef HashMap<String, scoped_refptr<BlobDataHandle>> BlobDataHandleMap; typedef Vector<WebBlobInfo> WebBlobInfoArray; @@ -191,6 +192,10 @@ int, Transferables&, ExceptionState&); + static bool ExtractTransferables(v8::Isolate*, + const Vector<ScriptValue>&, + Transferables&, + ExceptionState&); static ArrayBufferArray ExtractNonSharedArrayBuffers(Transferables&);
diff --git a/third_party/blink/renderer/bindings/core/v8/use_counter_callback.cc b/third_party/blink/renderer/bindings/core/v8/use_counter_callback.cc index e5f7ab56..3daee53 100644 --- a/third_party/blink/renderer/bindings/core/v8/use_counter_callback.cc +++ b/third_party/blink/renderer/bindings/core/v8/use_counter_callback.cc
@@ -148,6 +148,9 @@ case v8::Isolate::kArrayPrototypeSortJSArrayModifiedPrototype: blink_feature = WebFeature::kV8ArrayPrototypeSortJSArrayModifiedPrototype; break; + case v8::Isolate::kFunctionTokenOffsetTooLongForToString: + blink_feature = WebFeature::kV8FunctionTokenOffsetTooLongForToString; + break; default: // This can happen if V8 has added counters that this version of Blink // does not know about. It's harmless.
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc b/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc index c7e703a..dd8bd57 100644 --- a/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc +++ b/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc
@@ -350,10 +350,11 @@ if (data.GetEvent() == v8::kPromiseHandlerAddedAfterReject) { rejected_promises.HandlerAdded(data); return; + } else if (data.GetEvent() != v8::kPromiseRejectWithNoHandler) { + // Ignore reject/resolve after resolved. + return; } - DCHECK_EQ(data.GetEvent(), v8::kPromiseRejectWithNoHandler); - v8::Isolate* isolate = script_state->GetIsolate(); ExecutionContext* context = ExecutionContext::From(script_state);
diff --git a/third_party/blink/renderer/core/animation/animation_sim_test.cc b/third_party/blink/renderer/core/animation/animation_sim_test.cc index fd01d82..345f1d4 100644 --- a/third_party/blink/renderer/core/animation/animation_sim_test.cc +++ b/third_party/blink/renderer/core/animation/animation_sim_test.cc
@@ -48,12 +48,14 @@ // name: '--x', // syntax: '<percentage>', // initialValue: '0%', + // inherits: false // }) DummyExceptionStateForTesting exception_state; PropertyDescriptor property_descriptor; property_descriptor.setName("--x"); property_descriptor.setSyntax("<percentage>"); property_descriptor.setInitialValue("0%"); + property_descriptor.setInherits(false); PropertyRegistration::registerProperty(&GetDocument(), property_descriptor, exception_state); EXPECT_FALSE(exception_state.HadException());
diff --git a/third_party/blink/renderer/core/css/property_descriptor.idl b/third_party/blink/renderer/core/css/property_descriptor.idl index 18b455b..a64010d 100644 --- a/third_party/blink/renderer/core/css/property_descriptor.idl +++ b/third_party/blink/renderer/core/css/property_descriptor.idl
@@ -5,6 +5,6 @@ dictionary PropertyDescriptor { required DOMString name; DOMString syntax = "*"; - boolean inherits = false; + required boolean inherits; DOMString initialValue; };
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index 0ee6e97..667d6df 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc
@@ -605,6 +605,8 @@ compatibility_mode_(kNoQuirksMode), compatibility_mode_locked_(false), has_autofocused_(false), + last_focus_type_(kWebFocusTypeNone), + had_keyboard_event_(false), clear_focused_element_timer_( GetTaskRunner(TaskType::kInternalUserInteraction), this, @@ -4652,7 +4654,10 @@ focused_element_ = new_focused_element; SetSequentialFocusNavigationStartingPoint(focused_element_.Get()); - last_focus_type_ = params.type; + // Keep track of last focus from user interaction, ignoring focus from code. + if (params.type != kWebFocusTypeNone) + last_focus_type_ = params.type; + focused_element_->SetFocused(true, params.type); focused_element_->SetHasFocusWithinUpToAncestor(true, ancestor);
diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h index 9e190d7..1fded5aa 100644 --- a/third_party/blink/renderer/core/dom/document.h +++ b/third_party/blink/renderer/core/dom/document.h
@@ -65,7 +65,6 @@ #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/trace_wrapper_member.h" #include "third_party/blink/renderer/platform/length.h" -#include "third_party/blink/renderer/platform/loader/fetch/client_hints_preferences.h" #include "third_party/blink/renderer/platform/scroll/scroll_types.h" #include "third_party/blink/renderer/platform/timer.h" #include "third_party/blink/renderer/platform/web_task_runner.h" @@ -1303,10 +1302,6 @@ secure_context_state_ = state; } - ClientHintsPreferences& GetClientHintsPreferences() { - return client_hints_preferences_; - } - CanvasFontCache* GetCanvasFontCache(); // Used by unit tests so that all parsing will be main thread for @@ -1793,8 +1788,6 @@ HostsUsingFeatures::Value hosts_using_features_value_; - ClientHintsPreferences client_hints_preferences_; - Member<CanvasFontCache> canvas_font_cache_; TraceWrapperMember<IntersectionObserverController>
diff --git a/third_party/blink/renderer/core/editing/layout_selection_test.cc b/third_party/blink/renderer/core/editing/layout_selection_test.cc index 92e94da..81b9121 100644 --- a/third_party/blink/renderer/core/editing/layout_selection_test.cc +++ b/third_party/blink/renderer/core/editing/layout_selection_test.cc
@@ -91,6 +91,7 @@ LayoutObject* Current() const { return current_; } void Reset() { results.clear(); + stream = std::stringstream(); current_ = GetDocument().body()->GetLayoutObject(); } @@ -98,33 +99,33 @@ DCHECK(current_); current_ = NextLayoutObjectOnDOMTreeIncludeShadow(*current_); } + void TestNext(bool result) { + results.push_back(result); + if (!result) { + stream << "case " << results.size() - 1 << " failed.\n"; + } + if (!current_) { + stream << "cases are more than layout objects.\n"; + return; + } + Next(); + } bool CheckResult() { - std::stringstream stream; - bool has_fails = false; - if (current_) { - has_fails = true; + if (current_) stream << "cases are fewer than layout objects."; + + std::string errors = stream.str(); + if (errors.size()) { + std::stringstream layout_tree; + PrintLayoutTree(layout_tree); + LOG(ERROR) << "\n" << errors << layout_tree.str(); } - std::stringstream fails; - int test_fails = 0; - for (size_t i = 0; i < results.size(); i++) { - if (!results[i]) { - has_fails = true; - test_fails++; - fails << ", " << i; - } - } - if (has_fails) { - if (test_fails) - stream << "\ncases failed at" << fails.str(); - PrintLayoutTree(stream); - LOG(ERROR) << "\n" << stream.str(); - } - return !has_fails; + return !errors.size(); } WTF::Vector<bool> results; + std::stringstream stream; void PrintLayoutTree(std::stringstream& stream) { for (LayoutObject* runner = GetDocument().body()->GetLayoutObject(); runner; @@ -172,6 +173,14 @@ LayoutObject* current_ = nullptr; }; +// You can test SeletionStatus of all LayoutObjects in the body with following +// macros. See TraverseLayoutObject example below. +#define TEST_RESET() Reset(); +#define TEST_NEXT(predicate, state, invalidate) \ + TestNext(TestLayoutObject(Current(), predicate, SelectionState::state, \ + InvalidateOption::invalidate)); +#define TEST_CHECK() EXPECT_TRUE(CheckResult()) + std::ostream& operator<<(std::ostream& ostream, LayoutObject* layout_object) { PrintLayoutObjectForSelection(ostream, layout_object); return ostream; @@ -282,18 +291,6 @@ state, invalidate); } -// You can test SeletionStatus of all LayoutObjects in the body with following -// macros. See TraverseLayoutObject example just below. -#define TEST_RESET() Reset(); - -#define TEST_NEXT(predicate, state, invalidate) \ - results.push_back(TestLayoutObject(Current(), predicate, \ - SelectionState::state, \ - InvalidateOption::invalidate)); \ - Next() - -#define TEST_CHECK() EXPECT_TRUE(CheckResult()) - TEST_F(LayoutSelectionTest, TraverseLayoutObject) { SetBodyContent("foo<br>bar"); Selection().SetSelectionAndEndTyping(
diff --git a/third_party/blink/renderer/core/exported/web_frame_test.cc b/third_party/blink/renderer/core/exported/web_frame_test.cc index ac41703b..d64e287 100644 --- a/third_party/blink/renderer/core/exported/web_frame_test.cc +++ b/third_party/blink/renderer/core/exported/web_frame_test.cc
@@ -1227,8 +1227,8 @@ scoped_refptr<SerializedScriptValue> message = SerializeString("message", ToScriptStateForMainWorld(frame)); MessagePortArray message_ports; - frame->DomWindow()->postMessage(message, message_ports, "*", - frame->DomWindow(), exception_state); + frame->DomWindow()->PostMessageForTesting( + message, message_ports, "*", frame->DomWindow(), exception_state); web_view_helper.Reset(); EXPECT_FALSE(exception_state.HadException());
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc index d873b10..789ba3b 100644 --- a/third_party/blink/renderer/core/exported/web_view_impl.cc +++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -39,7 +39,6 @@ #include "build/build_config.h" #include "cc/layers/picture_layer.h" #include "third_party/blink/public/mojom/page/page_visibility_state.mojom-blink.h" -#include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/web_float_point.h" #include "third_party/blink/public/platform/web_gesture_curve.h" #include "third_party/blink/public/platform/web_image.h" @@ -96,6 +95,7 @@ #include "third_party/blink/renderer/core/frame/browser_controls.h" #include "third_party/blink/renderer/core/frame/event_handler_registry.h" #include "third_party/blink/renderer/core/frame/fullscreen_controller.h" +#include "third_party/blink/renderer/core/frame/link_highlights.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/local_frame_client.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" @@ -140,7 +140,6 @@ #include "third_party/blink/renderer/core/page/validation_message_client_impl.h" #include "third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h" #include "third_party/blink/renderer/core/paint/first_meaningful_paint_detector.h" -#include "third_party/blink/renderer/core/paint/link_highlight_impl.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" #include "third_party/blink/renderer/core/timing/dom_window_performance.h" @@ -150,7 +149,6 @@ #include "third_party/blink/renderer/platform/exported/web_active_gesture_animation.h" #include "third_party/blink/renderer/platform/fonts/font_cache.h" #include "third_party/blink/renderer/platform/geometry/float_rect.h" -#include "third_party/blink/renderer/platform/graphics/color.h" #include "third_party/blink/renderer/platform/graphics/compositor_mutator_client.h" #include "third_party/blink/renderer/platform/graphics/compositor_mutator_impl.h" #include "third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h" @@ -381,11 +379,6 @@ WebViewImpl::~WebViewImpl() { DCHECK(!page_); - - // Each highlight uses m_owningWebViewImpl->m_linkHighlightsTimeline - // in destructor. m_linkHighlightsTimeline might be destroyed earlier - // than m_linkHighlights. - DCHECK(link_highlights_.IsEmpty()); } ValidationMessageClient* WebViewImpl::GetValidationMessageClient() const { @@ -620,8 +613,7 @@ case WebInputEvent::kGestureTapCancel: case WebInputEvent::kGestureTap: case WebInputEvent::kGestureLongPress: - for (size_t i = 0; i < link_highlights_.size(); ++i) - link_highlights_[i]->StartHighlightAnimationIfNeeded(); + GetPage()->GetLinkHighlights().StartHighlightAnimationIfNeeded(); break; default: break; @@ -669,8 +661,7 @@ RoundedIntSize(targeted_event.GetHitTestResult().LocalPoint()); EnableTapHighlights(highlight_nodes); - for (size_t i = 0; i < link_highlights_.size(); ++i) - link_highlights_[i]->StartHighlightAnimationIfNeeded(); + GetPage()->GetLinkHighlights().StartHighlightAnimationIfNeeded(); event_result = WebInputEventResult::kHandledSystem; event_cancelled = true; break; @@ -1266,30 +1257,7 @@ void WebViewImpl::EnableTapHighlights( HeapVector<Member<Node>>& highlight_nodes) { - if (highlight_nodes.IsEmpty()) - return; - - // Always clear any existing highlight when this is invoked, even if we - // don't get a new target to highlight. - link_highlights_.clear(); - - for (size_t i = 0; i < highlight_nodes.size(); ++i) { - Node* node = highlight_nodes[i]; - - if (!node || !node->GetLayoutObject()) - continue; - - Color highlight_color = - node->GetLayoutObject()->Style()->TapHighlightColor(); - // Safari documentation for -webkit-tap-highlight-color says if the - // specified color has 0 alpha, then tap highlighting is disabled. - // http://developer.apple.com/library/safari/#documentation/appleapplications/reference/safaricssref/articles/standardcssproperties.html - if (!highlight_color.Alpha()) - continue; - - link_highlights_.push_back(LinkHighlightImpl::Create(node, this)); - } - + GetPage()->GetLinkHighlights().SetTapHighlights(highlight_nodes); UpdateAllLifecyclePhases(); } @@ -1785,8 +1753,8 @@ // TODO(chrishtr): link highlights don't currently paint themselves, it's // still driven by cc. Fix this. - for (size_t i = 0; i < link_highlights_.size(); ++i) - link_highlights_[i]->UpdateGeometry(); + // TODO(pdr): Move this to LocalFrameView::UpdateLifecyclePhasesInternal. + GetPage()->GetLinkHighlights().UpdateGeometry(); if (LocalFrameView* view = MainFrameImpl()->GetFrameView()) { LocalFrame* frame = MainFrameImpl()->GetFrame(); @@ -2137,12 +2105,6 @@ } void WebViewImpl::WillCloseLayerTreeView() { - if (link_highlights_timeline_) { - link_highlights_.clear(); - DetachCompositorAnimationTimeline(link_highlights_timeline_.get()); - link_highlights_timeline_.reset(); - } - if (layer_tree_view_) GetPage()->WillCloseLayerTreeView(*layer_tree_view_, nullptr); @@ -3172,7 +3134,8 @@ GetPage()->GetVisualViewport().MainFrameDidChangeSize(); // Make sure link highlight from previous page is cleared. - link_highlights_.clear(); + // TODO(pdr): Move this to Page::DidCommitLoad. + GetPage()->GetLinkHighlights().ResetForPageNavigation(); if (!MainFrameImpl()) return; @@ -3503,11 +3466,6 @@ // hit this code and then delete allowsBrokenNullLayerTreeView. DCHECK(layer_tree_view_ || !client_ || client_->WidgetClient()->AllowsBrokenNullLayerTreeView()); - - if (Platform::Current()->IsThreadedAnimationEnabled() && layer_tree_view_) { - link_highlights_timeline_ = CompositorAnimationTimeline::Create(); - AttachCompositorAnimationTimeline(link_highlights_timeline_.get()); - } } void WebViewImpl::ApplyViewportDeltas(
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.h b/third_party/blink/renderer/core/exported/web_view_impl.h index 0b5d35b7b..a47150a8 100644 --- a/third_party/blink/renderer/core/exported/web_view_impl.h +++ b/third_party/blink/renderer/core/exported/web_view_impl.h
@@ -57,7 +57,6 @@ #include "third_party/blink/renderer/core/page/event_with_hit_test_results.h" #include "third_party/blink/renderer/core/page/page_widget_delegate.h" #include "third_party/blink/renderer/core/page/scoped_page_pauser.h" -#include "third_party/blink/renderer/platform/animation/compositor_animation_timeline.h" #include "third_party/blink/renderer/platform/geometry/int_point.h" #include "third_party/blink/renderer/platform/geometry/int_rect.h" #include "third_party/blink/renderer/platform/graphics/graphics_layer.h" @@ -79,7 +78,6 @@ class DevToolsEmulator; class Frame; class FullscreenController; -class LinkHighlightImpl; class PageOverlay; class PageScaleConstraintsSet; class PaintLayerCompositor; @@ -341,9 +339,6 @@ GraphicsLayer* RootGraphicsLayer(); void RegisterViewportLayersWithCompositor(); PaintLayerCompositor* Compositor() const; - CompositorAnimationTimeline* LinkHighlightsTimeline() const { - return link_highlights_timeline_.get(); - } PageScheduler* Scheduler() const override; void SetVisibilityState(mojom::PageVisibilityState, bool) override; @@ -398,12 +393,6 @@ bool HasHorizontalScrollbar(); bool HasVerticalScrollbar(); - // Exposed for tests. - unsigned NumLinkHighlights() { return link_highlights_.size(); } - LinkHighlightImpl* GetLinkHighlight(int i) { - return link_highlights_[i].get(); - } - WebSettingsImpl* SettingsImpl(); // Returns the bounding box of the block type node touched by the WebPoint. @@ -653,8 +642,6 @@ GraphicsLayer* visual_viewport_container_layer_; bool matches_heuristics_for_gpu_rasterization_; - Vector<std::unique_ptr<LinkHighlightImpl>> link_highlights_; - std::unique_ptr<CompositorAnimationTimeline> link_highlights_timeline_; std::unique_ptr<FullscreenController> fullscreen_controller_; WebPoint last_tap_disambiguation_best_candidate_position_;
diff --git a/third_party/blink/renderer/core/frame/BUILD.gn b/third_party/blink/renderer/core/frame/BUILD.gn index fe7ea6b..9244228d 100644 --- a/third_party/blink/renderer/core/frame/BUILD.gn +++ b/third_party/blink/renderer/core/frame/BUILD.gn
@@ -78,6 +78,8 @@ "intervention_report_body.h", "layout_subtree_root_list.cc", "layout_subtree_root_list.h", + "link_highlights.cc", + "link_highlights.h", "local_dom_window.cc", "local_dom_window.h", "local_frame.cc",
diff --git a/third_party/blink/renderer/core/frame/dom_window.cc b/third_party/blink/renderer/core/frame/dom_window.cc index 955e1993..0c0892c 100644 --- a/third_party/blink/renderer/core/frame/dom_window.cc +++ b/third_party/blink/renderer/core/frame/dom_window.cc
@@ -108,6 +108,40 @@ return GetFrame()->Tree().Top().DomWindow(); } +void DOMWindow::postMessage(LocalDOMWindow* incumbent_window, + const ScriptValue& message, + const String& target_origin, + Vector<ScriptValue>& transfer, + ExceptionState& exception_state) { + UseCounter::Count(incumbent_window->GetFrame(), + WebFeature::kWindowPostMessage); + + // Since remote windows do not have a v8::Context, we cannot use + // [CallWith=ScriptState], and there is no good way to get the v8::Isolate. + // As a compromise, ask the isolate to the WindowProxyManager. + v8::Isolate* isolate = window_proxy_manager_->GetIsolate(); + + Transferables transferables; + if (!transfer.IsEmpty()) { + if (!SerializedScriptValue::ExtractTransferables( + isolate, transfer, transferables, exception_state)) { + return; + } + } + + SerializedScriptValue::SerializeOptions options; + options.transferables = &transferables; + scoped_refptr<SerializedScriptValue> serialized_message = + SerializedScriptValue::Serialize(isolate, message.V8Value(), options, + exception_state); + if (exception_state.HadException()) + return; + + serialized_message->UnregisterMemoryAllocatedWithCurrentScriptContext(); + DoPostMessage(std::move(serialized_message), transferables.message_ports, + target_origin, incumbent_window, exception_state); +} + DOMWindow* DOMWindow::AnonymousIndexedGetter(uint32_t index) const { if (!GetFrame()) return nullptr; @@ -149,87 +183,6 @@ return true; } -void DOMWindow::postMessage(scoped_refptr<SerializedScriptValue> message, - const MessagePortArray& ports, - const String& target_origin, - LocalDOMWindow* source, - ExceptionState& exception_state) { - if (!IsCurrentlyDisplayedInFrame()) - return; - - Document* source_document = source->document(); - - // Compute the target origin. We need to do this synchronously in order - // to generate the SyntaxError exception correctly. - scoped_refptr<const SecurityOrigin> target; - if (target_origin == "/") { - if (!source_document) - return; - target = source_document->GetSecurityOrigin(); - } else if (target_origin != "*") { - target = SecurityOrigin::CreateFromString(target_origin); - // It doesn't make sense target a postMessage at a unique origin - // because there's no way to represent a unique origin in a string. - if (target->IsOpaque()) { - exception_state.ThrowDOMException(DOMExceptionCode::kSyntaxError, - "Invalid target origin '" + - target_origin + - "' in a call to 'postMessage'."); - return; - } - } - - auto channels = MessagePort::DisentanglePorts(GetExecutionContext(), ports, - exception_state); - if (exception_state.HadException()) - return; - - // Capture the source of the message. We need to do this synchronously - // in order to capture the source of the message correctly. - if (!source_document) - return; - - const SecurityOrigin* security_origin = source_document->GetSecurityOrigin(); - - String source_origin = security_origin->ToString(); - - KURL target_url = IsLocalDOMWindow() - ? blink::ToLocalDOMWindow(this)->document()->Url() - : KURL(NullURL(), GetFrame() - ->GetSecurityContext() - ->GetSecurityOrigin() - ->ToString()); - if (MixedContentChecker::IsMixedContent(source_document->GetSecurityOrigin(), - target_url)) { - UseCounter::Count(source->GetFrame(), - WebFeature::kPostMessageFromSecureToInsecure); - } else if (MixedContentChecker::IsMixedContent( - GetFrame()->GetSecurityContext()->GetSecurityOrigin(), - source_document->Url())) { - UseCounter::Count(source->GetFrame(), - WebFeature::kPostMessageFromInsecureToSecure); - if (MixedContentChecker::IsMixedContent( - GetFrame()->Tree().Top().GetSecurityContext()->GetSecurityOrigin(), - source_document->Url())) { - UseCounter::Count(source->GetFrame(), - WebFeature::kPostMessageFromInsecureToSecureToplevel); - } - } - - if (!source_document->GetContentSecurityPolicy()->AllowConnectToSource( - target_url, RedirectStatus::kNoRedirect, - SecurityViolationReportingPolicy::kSuppressReporting)) { - UseCounter::Count( - source->GetFrame(), - WebFeature::kPostMessageOutgoingWouldBeBlockedByConnectSrc); - } - - MessageEvent* event = MessageEvent::Create( - std::move(channels), std::move(message), source_origin, String(), source); - - SchedulePostMessage(event, std::move(target), source_document); -} - // FIXME: Once we're throwing exceptions for cross-origin access violations, we // will always sanitize the target frame details, so we can safely combine // 'crossDomainAccessErrorMessage' with this method after considering exactly @@ -435,6 +388,97 @@ return input_capabilities_; } +void DOMWindow::PostMessageForTesting( + scoped_refptr<SerializedScriptValue> message, + const MessagePortArray& ports, + const String& target_origin, + LocalDOMWindow* source, + ExceptionState& exception_state) { + DoPostMessage(std::move(message), ports, target_origin, source, + exception_state); +} + +void DOMWindow::DoPostMessage(scoped_refptr<SerializedScriptValue> message, + const MessagePortArray& ports, + const String& target_origin, + LocalDOMWindow* source, + ExceptionState& exception_state) { + if (!IsCurrentlyDisplayedInFrame()) + return; + + Document* source_document = source->document(); + + // Compute the target origin. We need to do this synchronously in order + // to generate the SyntaxError exception correctly. + scoped_refptr<const SecurityOrigin> target; + if (target_origin == "/") { + if (!source_document) + return; + target = source_document->GetSecurityOrigin(); + } else if (target_origin != "*") { + target = SecurityOrigin::CreateFromString(target_origin); + // It doesn't make sense target a postMessage at a unique origin + // because there's no way to represent a unique origin in a string. + if (target->IsOpaque()) { + exception_state.ThrowDOMException(DOMExceptionCode::kSyntaxError, + "Invalid target origin '" + + target_origin + + "' in a call to 'postMessage'."); + return; + } + } + + auto channels = MessagePort::DisentanglePorts(GetExecutionContext(), ports, + exception_state); + if (exception_state.HadException()) + return; + + // Capture the source of the message. We need to do this synchronously + // in order to capture the source of the message correctly. + if (!source_document) + return; + + const SecurityOrigin* security_origin = source_document->GetSecurityOrigin(); + + String source_origin = security_origin->ToString(); + + KURL target_url = IsLocalDOMWindow() + ? blink::ToLocalDOMWindow(this)->document()->Url() + : KURL(NullURL(), GetFrame() + ->GetSecurityContext() + ->GetSecurityOrigin() + ->ToString()); + if (MixedContentChecker::IsMixedContent(source_document->GetSecurityOrigin(), + target_url)) { + UseCounter::Count(source->GetFrame(), + WebFeature::kPostMessageFromSecureToInsecure); + } else if (MixedContentChecker::IsMixedContent( + GetFrame()->GetSecurityContext()->GetSecurityOrigin(), + source_document->Url())) { + UseCounter::Count(source->GetFrame(), + WebFeature::kPostMessageFromInsecureToSecure); + if (MixedContentChecker::IsMixedContent( + GetFrame()->Tree().Top().GetSecurityContext()->GetSecurityOrigin(), + source_document->Url())) { + UseCounter::Count(source->GetFrame(), + WebFeature::kPostMessageFromInsecureToSecureToplevel); + } + } + + if (!source_document->GetContentSecurityPolicy()->AllowConnectToSource( + target_url, RedirectStatus::kNoRedirect, + SecurityViolationReportingPolicy::kSuppressReporting)) { + UseCounter::Count( + source->GetFrame(), + WebFeature::kPostMessageOutgoingWouldBeBlockedByConnectSrc); + } + + MessageEvent* event = MessageEvent::Create( + std::move(channels), std::move(message), source_origin, String(), source); + + SchedulePostMessage(event, std::move(target), source_document); +} + void DOMWindow::Trace(blink::Visitor* visitor) { visitor->Trace(frame_); visitor->Trace(window_proxy_manager_);
diff --git a/third_party/blink/renderer/core/frame/dom_window.h b/third_party/blink/renderer/core/frame/dom_window.h index 8bbaa0e..50b2802 100644 --- a/third_party/blink/renderer/core/frame/dom_window.h +++ b/third_party/blink/renderer/core/frame/dom_window.h
@@ -22,6 +22,7 @@ class LocalDOMWindow; class Location; class MessageEvent; +class ScriptValue; class SecurityOrigin; class SerializedScriptValue; class WindowProxyManager; @@ -85,15 +86,15 @@ virtual void blur() = 0; void close(LocalDOMWindow* incumbent_window); + void postMessage(LocalDOMWindow* incumbent_window, + const ScriptValue& message, + const String& target_origin, + Vector<ScriptValue>& transfer, + ExceptionState&); + // Indexed properties DOMWindow* AnonymousIndexedGetter(uint32_t index) const; - void postMessage(scoped_refptr<SerializedScriptValue> message, - const MessagePortArray&, - const String& target_origin, - LocalDOMWindow* source, - ExceptionState&); - String SanitizedCrossDomainAccessErrorMessage( const LocalDOMWindow* calling_window) const; String CrossDomainAccessErrorMessage( @@ -111,6 +112,12 @@ InputDeviceCapabilitiesConstants* GetInputDeviceCapabilities(); + void PostMessageForTesting(scoped_refptr<SerializedScriptValue> message, + const MessagePortArray&, + const String& target_origin, + LocalDOMWindow* source, + ExceptionState&); + protected: explicit DOMWindow(Frame&); @@ -121,6 +128,12 @@ void DisconnectFromFrame() { frame_ = nullptr; } private: + void DoPostMessage(scoped_refptr<SerializedScriptValue> message, + const MessagePortArray&, + const String& target_origin, + LocalDOMWindow* source, + ExceptionState&); + Member<Frame> frame_; // Unlike |frame_|, |window_proxy_manager_| is available even after the // window's frame gets detached from the DOM, until the end of the lifetime
diff --git a/third_party/blink/renderer/core/frame/frame_test_helpers.cc b/third_party/blink/renderer/core/frame/frame_test_helpers.cc index 7a99530..abfe0bda 100644 --- a/third_party/blink/renderer/core/frame/frame_test_helpers.cc +++ b/third_party/blink/renderer/core/frame/frame_test_helpers.cc
@@ -32,6 +32,8 @@ #include <utility> +#include "cc/test/test_ukm_recorder_factory.h" +#include "cc/trees/layer_tree_host.h" #include "cc/trees/layer_tree_settings.h" #include "third_party/blink/public/mojom/page/page_visibility_state.mojom-blink.h" #include "third_party/blink/public/platform/platform.h" @@ -490,8 +492,12 @@ settings.use_layer_lists = true; compositor_ = std::make_unique<content::RenderWidgetCompositor>( - specified_delegate ? specified_delegate : &delegate_, &compositor_deps_); - compositor_->Initialize(settings); + specified_delegate ? specified_delegate : &delegate_, + Platform::Current()->CurrentThread()->GetTaskRunner(), + /*compositor_thread=*/nullptr, &test_task_graph_runner_, + &fake_renderer_scheduler_); + compositor_->Initialize(settings, + std::make_unique<cc::TestUkmRecorderFactory>()); return compositor_.get(); }
diff --git a/third_party/blink/renderer/core/frame/frame_test_helpers.h b/third_party/blink/renderer/core/frame/frame_test_helpers.h index d4cd0fa5..a9ff5d0 100644 --- a/third_party/blink/renderer/core/frame/frame_test_helpers.h +++ b/third_party/blink/renderer/core/frame/frame_test_helpers.h
@@ -37,12 +37,13 @@ #include <string> #include "base/macros.h" +#include "cc/test/test_task_graph_runner.h" #include "content/renderer/gpu/render_widget_compositor.h" -#include "content/test/fake_compositor_dependencies.h" #include "content/test/stub_render_widget_compositor_delegate.h" #include "services/service_manager/public/cpp/interface_provider.h" #include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom-shared.h" #include "third_party/blink/public/platform/platform.h" +#include "third_party/blink/public/platform/scheduler/test/fake_renderer_scheduler.h" #include "third_party/blink/public/platform/web_mouse_event.h" #include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/public/platform/web_url_request.h" @@ -173,7 +174,8 @@ private: content::StubRenderWidgetCompositorDelegate delegate_; - content::FakeCompositorDependencies compositor_deps_; + cc::TestTaskGraphRunner test_task_graph_runner_; + blink::scheduler::FakeRendererScheduler fake_renderer_scheduler_; std::unique_ptr<content::RenderWidgetCompositor> compositor_; };
diff --git a/third_party/blink/renderer/core/frame/link_highlights.cc b/third_party/blink/renderer/core/frame/link_highlights.cc new file mode 100644 index 0000000..90aba39 --- /dev/null +++ b/third_party/blink/renderer/core/frame/link_highlights.cc
@@ -0,0 +1,110 @@ +// 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 "third_party/blink/renderer/core/frame/link_highlights.h" + +#include <memory> + +#include "cc/layers/picture_layer.h" +#include "third_party/blink/public/platform/platform.h" +#include "third_party/blink/public/platform/web_layer_tree_view.h" +#include "third_party/blink/renderer/core/dom/node.h" +#include "third_party/blink/renderer/core/layout/layout_object.h" +#include "third_party/blink/renderer/core/page/chrome_client.h" +#include "third_party/blink/renderer/core/page/page.h" +#include "third_party/blink/renderer/core/paint/link_highlight_impl.h" +#include "third_party/blink/renderer/platform/animation/compositor_animation_timeline.h" + +namespace blink { + +LinkHighlights::LinkHighlights(Page& owner) : page_(&owner) {} + +LinkHighlights::~LinkHighlights() { + RemoveAllHighlights(); +} + +void LinkHighlights::Trace(blink::Visitor* visitor) { + visitor->Trace(page_); +} + +void LinkHighlights::RemoveAllHighlights() { + if (timeline_) { + for (auto& highlight : link_highlights_) + timeline_->AnimationDestroyed(*highlight); + } + link_highlights_.clear(); +} + +void LinkHighlights::ResetForPageNavigation() { + RemoveAllHighlights(); +} + +void LinkHighlights::SetTapHighlights( + HeapVector<Member<Node>>& highlight_nodes) { + // Always clear any existing highlight when this is invoked, even if we + // don't get a new target to highlight. + RemoveAllHighlights(); + + for (size_t i = 0; i < highlight_nodes.size(); ++i) { + Node* node = highlight_nodes[i]; + + if (!node || !node->GetLayoutObject()) + continue; + + Color highlight_color = + node->GetLayoutObject()->Style()->TapHighlightColor(); + // Safari documentation for -webkit-tap-highlight-color says if the + // specified color has 0 alpha, then tap highlighting is disabled. + // http://developer.apple.com/library/safari/#documentation/appleapplications/reference/safaricssref/articles/standardcssproperties.html + if (!highlight_color.Alpha()) + continue; + + link_highlights_.push_back(LinkHighlightImpl::Create(node)); + if (timeline_) + timeline_->AnimationAttached(*link_highlights_.back()); + } +} + +void LinkHighlights::UpdateGeometry() { + for (auto& highlight : link_highlights_) + highlight->UpdateGeometry(); +} + +LocalFrame* LinkHighlights::MainFrame() const { + return GetPage().MainFrame() && GetPage().MainFrame()->IsLocalFrame() + ? GetPage().DeprecatedLocalMainFrame() + : nullptr; +} + +void LinkHighlights::StartHighlightAnimationIfNeeded() { + for (auto& highlight : link_highlights_) + highlight->StartHighlightAnimationIfNeeded(); + + if (auto* local_frame = MainFrame()) + GetPage().GetChromeClient().ScheduleAnimation(local_frame->View()); +} + +void LinkHighlights::LayerTreeViewInitialized( + WebLayerTreeView& layer_tree_view) { + if (Platform::Current()->IsThreadedAnimationEnabled()) { + timeline_ = CompositorAnimationTimeline::Create(); + if (auto* local_frame = MainFrame()) { + GetPage().GetChromeClient().AttachCompositorAnimationTimeline( + timeline_.get(), local_frame); + } + } +} + +void LinkHighlights::WillCloseLayerTreeView(WebLayerTreeView& layer_tree_view) { + RemoveAllHighlights(); + if (timeline_) { + if (auto* local_frame = MainFrame()) { + GetPage().GetChromeClient().DetachCompositorAnimationTimeline( + timeline_.get(), local_frame); + } + timeline_.reset(); + } +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/frame/link_highlights.h b/third_party/blink/renderer/core/frame/link_highlights.h new file mode 100644 index 0000000..8b79375 --- /dev/null +++ b/third_party/blink/renderer/core/frame/link_highlights.h
@@ -0,0 +1,64 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_LINK_HIGHLIGHTS_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_LINK_HIGHLIGHTS_H_ + +#include <memory> + +#include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/platform/heap/handle.h" + +namespace blink { + +class Page; +class LinkHighlightImpl; +class CompositorAnimationTimeline; +class WebLayerTreeView; +class LocalFrame; + +class CORE_EXPORT LinkHighlights final + : public GarbageCollectedFinalized<LinkHighlights> { + public: + static LinkHighlights* Create(Page& page) { return new LinkHighlights(page); } + virtual ~LinkHighlights(); + + virtual void Trace(blink::Visitor*); + + void ResetForPageNavigation(); + + void SetTapHighlights(HeapVector<Member<Node>>&); + + void UpdateGeometry(); + + void StartHighlightAnimationIfNeeded(); + + void LayerTreeViewInitialized(WebLayerTreeView&); + void WillCloseLayerTreeView(WebLayerTreeView&); + + private: + FRIEND_TEST_ALL_PREFIXES(LinkHighlightImplTest, verifyWebViewImplIntegration); + FRIEND_TEST_ALL_PREFIXES(LinkHighlightImplTest, resetDuringNodeRemoval); + FRIEND_TEST_ALL_PREFIXES(LinkHighlightImplTest, resetLayerTreeView); + FRIEND_TEST_ALL_PREFIXES(LinkHighlightImplTest, multipleHighlights); + + explicit LinkHighlights(Page&); + + void RemoveAllHighlights(); + + LocalFrame* MainFrame() const; + + Page& GetPage() const { + DCHECK(page_); + return *page_; + } + + Member<Page> page_; + Vector<std::unique_ptr<LinkHighlightImpl>> link_highlights_; + std::unique_ptr<CompositorAnimationTimeline> timeline_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_LINK_HIGHLIGHTS_H_
diff --git a/third_party/blink/renderer/core/frame/local_frame.h b/third_party/blink/renderer/core/frame/local_frame.h index 178e41fe..aa9f1e9 100644 --- a/third_party/blink/renderer/core/frame/local_frame.h +++ b/third_party/blink/renderer/core/frame/local_frame.h
@@ -46,6 +46,7 @@ #include "third_party/blink/renderer/platform/graphics/touch_action.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/instance_counters.h" +#include "third_party/blink/renderer/platform/loader/fetch/client_hints_preferences.h" #include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h" #include "third_party/blink/renderer/platform/supplementable.h" @@ -361,6 +362,10 @@ void AnimateSnapFling(base::TimeTicks monotonic_time); + ClientHintsPreferences& GetClientHintsPreferences() { + return client_hints_preferences_; + } + private: friend class FrameNavigationDisabler; @@ -454,6 +459,7 @@ std::unique_ptr<WebURLLoaderFactory> url_loader_factory_; blink::mojom::blink::PrefetchURLLoaderServicePtr prefetch_loader_service_; + ClientHintsPreferences client_hints_preferences_; }; inline FrameLoader& LocalFrame::Loader() const {
diff --git a/third_party/blink/renderer/core/frame/window.idl b/third_party/blink/renderer/core/frame/window.idl index a09665a..06c89d8 100644 --- a/third_party/blink/renderer/core/frame/window.idl +++ b/third_party/blink/renderer/core/frame/window.idl
@@ -100,7 +100,7 @@ [Measure] long requestIdleCallback(IdleRequestCallback callback, optional IdleRequestOptions options); void cancelIdleCallback(long handle); - [CrossOrigin, Custom, RaisesException] void postMessage(any message, DOMString targetOrigin, optional sequence<object> transfer = []); + [CrossOrigin, CallWith=CurrentWindow, RaisesException] void postMessage(any message, USVString targetOrigin, optional sequence<object> transfer = []); // Custom elements // https://w3c.github.io/webcomponents/spec/custom/#custom-elements-api
diff --git a/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc b/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc index cf42e01..5599616 100644 --- a/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc +++ b/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
@@ -637,13 +637,26 @@ } } +// Returns an image and the image's resolution scale factor. +static std::pair<blink::Image*, float> BrokenCanvas(float device_scale_factor) { + if (device_scale_factor >= 2) { + DEFINE_STATIC_REF(blink::Image, broken_canvas_hi_res, + (blink::Image::LoadPlatformResource("brokenCanvas@2x"))); + return std::make_pair(broken_canvas_hi_res, 2); + } + + DEFINE_STATIC_REF(blink::Image, broken_canvas_lo_res, + (blink::Image::LoadPlatformResource("brokenCanvas"))); + return std::make_pair(broken_canvas_lo_res, 1); +} + void HTMLCanvasElement::Paint(GraphicsContext& context, const LayoutRect& r) { if (context_creation_was_blocked_ || (context_ && context_->isContextLost())) { float device_scale_factor = blink::DeviceScaleFactorDeprecated(GetDocument().GetFrame()); std::pair<Image*, float> broken_canvas_and_image_scale_factor = - ImageResourceContent::BrokenCanvas(device_scale_factor); + BrokenCanvas(device_scale_factor); Image* broken_canvas = broken_canvas_and_image_scale_factor.first; context.Save(); context.FillRect(FloatRect(r), Color(), SkBlendMode::kClear);
diff --git a/third_party/blink/renderer/core/input/event_handler.cc b/third_party/blink/renderer/core/input/event_handler.cc index e380f58..8ef57ffc 100644 --- a/third_party/blink/renderer/core/input/event_handler.cc +++ b/third_party/blink/renderer/core/input/event_handler.cc
@@ -1005,9 +1005,7 @@ EventTypeNames::mouseup, mouse_event); } - // Only release scrollbar when left button up. - if (mouse_event.button == WebPointerProperties::Button::kLeft && - last_scrollbar_under_mouse_) { + if (last_scrollbar_under_mouse_) { mouse_event_manager_->InvalidateClick(); last_scrollbar_under_mouse_->MouseUp(mouse_event); frame_->LocalFrameRoot().Client()->SetMouseCapture(false); @@ -2125,9 +2123,14 @@ bool EventHandler::PassMousePressEventToScrollbar( MouseEventWithHitTestResults& mev) { - // Only handle mouse left button as press. - if (mev.Event().button != WebPointerProperties::Button::kLeft) + // Do not pass the mouse press to scrollbar if scrollbar pressed. If the + // user's left button is down, then the cursor moves outside the scrollbar + // and presses the middle button , we should not clear + // last_scrollbar_under_mouse_. + if (last_scrollbar_under_mouse_ && + last_scrollbar_under_mouse_->PressedPart() != ScrollbarPart::kNoPart) { return false; + } Scrollbar* scrollbar = mev.GetScrollbar(); UpdateLastScrollbarUnderMouse(scrollbar, true);
diff --git a/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope_proxy.cc b/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope_proxy.cc index ce96e62..078e624 100644 --- a/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope_proxy.cc +++ b/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope_proxy.cc
@@ -57,7 +57,7 @@ void LayoutWorkletGlobalScopeProxy::FetchAndInvokeScript( const KURL& module_url_record, network::mojom::FetchCredentialsMode credentials_mode, - const FetchClientSettingsObjectSnapshot& outside_settings_object, + FetchClientSettingsObjectSnapshot* outside_settings_object, scoped_refptr<base::SingleThreadTaskRunner> outside_settings_task_runner, WorkletPendingTasks* pending_tasks) { DCHECK(IsMainThread());
diff --git a/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope_proxy.h b/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope_proxy.h index d933e5e9..f6bcd14 100644 --- a/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope_proxy.h +++ b/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope_proxy.h
@@ -35,7 +35,7 @@ void FetchAndInvokeScript( const KURL& module_url_record, network::mojom::FetchCredentialsMode, - const FetchClientSettingsObjectSnapshot& outside_settings_object, + FetchClientSettingsObjectSnapshot* outside_settings_object, scoped_refptr<base::SingleThreadTaskRunner> outside_settings_task_runner, WorkletPendingTasks*) override; void WorkletObjectDestroyed() override;
diff --git a/third_party/blink/renderer/core/layout/layout_image.cc b/third_party/blink/renderer/core/layout/layout_image.cc index 9f449a30..dac6399 100644 --- a/third_party/blink/renderer/core/layout/layout_image.cc +++ b/third_party/blink/renderer/core/layout/layout_image.cc
@@ -385,7 +385,7 @@ // Our intrinsicSize is empty if we're laying out generated images with // relative width/height. Figure out the right intrinsic size to use. if (intrinsic_sizing_info.size.IsEmpty() && - image_resource_->ImageHasRelativeSize()) { + image_resource_->ImageHasRelativeSize() && !IsLayoutNGListMarkerImage()) { LayoutObject* containing_block = IsOutOfFlowPositioned() ? Container() : ContainingBlock(); if (containing_block->IsBox()) {
diff --git a/third_party/blink/renderer/core/layout/layout_image_resource.cc b/third_party/blink/renderer/core/layout/layout_image_resource.cc index d84e930..62ebf5c 100644 --- a/third_party/blink/renderer/core/layout/layout_image_resource.cc +++ b/third_party/blink/renderer/core/layout/layout_image_resource.cc
@@ -113,6 +113,12 @@ return size; } +FloatSize LayoutImageResource::ImageSizeWithDefaultSize( + float multiplier, + const LayoutSize&) const { + return ImageSize(multiplier); +} + float LayoutImageResource::DeviceScaleFactor() const { return DeviceScaleFactorDeprecated(layout_object_->GetFrame()); }
diff --git a/third_party/blink/renderer/core/layout/layout_image_resource.h b/third_party/blink/renderer/core/layout/layout_image_resource.h index 2005a64..4d2776a 100644 --- a/third_party/blink/renderer/core/layout/layout_image_resource.h +++ b/third_party/blink/renderer/core/layout/layout_image_resource.h
@@ -65,7 +65,9 @@ virtual bool ImageHasRelativeSize() const; virtual FloatSize ImageSize(float multiplier) const; - + // Default size is effective when this is LayoutImageResourceStyleImage. + virtual FloatSize ImageSizeWithDefaultSize(float multiplier, + const LayoutSize&) const; virtual WrappedImagePtr ImagePtr() const { return cached_image_.Get(); } virtual void Trace(blink::Visitor* visitor) { visitor->Trace(cached_image_); }
diff --git a/third_party/blink/renderer/core/layout/layout_image_resource_style_image.cc b/third_party/blink/renderer/core/layout/layout_image_resource_style_image.cc index af0dbd1e..d713f05 100644 --- a/third_party/blink/renderer/core/layout/layout_image_resource_style_image.cc +++ b/third_party/blink/renderer/core/layout/layout_image_resource_style_image.cc
@@ -70,11 +70,17 @@ FloatSize LayoutImageResourceStyleImage::ImageSize(float multiplier) const { // TODO(davve): Find out the correct default object size in this context. - return style_image_->ImageSize(layout_object_->GetDocument(), multiplier, - LayoutSize(LayoutReplaced::kDefaultWidth, - LayoutReplaced::kDefaultHeight)); + return ImageSizeWithDefaultSize(multiplier, + LayoutSize(LayoutReplaced::kDefaultWidth, + LayoutReplaced::kDefaultHeight)); } +FloatSize LayoutImageResourceStyleImage::ImageSizeWithDefaultSize( + float multiplier, + const LayoutSize& default_size) const { + return style_image_->ImageSize(layout_object_->GetDocument(), multiplier, + default_size); +} void LayoutImageResourceStyleImage::Trace(blink::Visitor* visitor) { visitor->Trace(style_image_); LayoutImageResource::Trace(visitor);
diff --git a/third_party/blink/renderer/core/layout/layout_image_resource_style_image.h b/third_party/blink/renderer/core/layout/layout_image_resource_style_image.h index 92067a2..644d3e77a 100644 --- a/third_party/blink/renderer/core/layout/layout_image_resource_style_image.h +++ b/third_party/blink/renderer/core/layout/layout_image_resource_style_image.h
@@ -53,6 +53,8 @@ return style_image_->ImageHasRelativeSize(); } FloatSize ImageSize(float multiplier) const override; + FloatSize ImageSizeWithDefaultSize(float multiplier, + const LayoutSize&) const override; WrappedImagePtr ImagePtr() const override { return style_image_->Data(); } void Trace(blink::Visitor*) override;
diff --git a/third_party/blink/renderer/core/layout/layout_table_cell.cc b/third_party/blink/renderer/core/layout/layout_table_cell.cc index cdcd668..e08a856c 100644 --- a/third_party/blink/renderer/core/layout/layout_table_cell.cc +++ b/third_party/blink/renderer/core/layout/layout_table_cell.cc
@@ -31,6 +31,7 @@ #include "third_party/blink/renderer/core/html_names.h" #include "third_party/blink/renderer/core/layout/collapsed_border_value.h" #include "third_party/blink/renderer/core/layout/layout_analyzer.h" +#include "third_party/blink/renderer/core/layout/layout_object_factory.h" #include "third_party/blink/renderer/core/layout/layout_table_col.h" #include "third_party/blink/renderer/core/layout/subtree_layout_scope.h" #include "third_party/blink/renderer/core/paint/object_paint_invalidator.h" @@ -1157,20 +1158,23 @@ } } -LayoutTableCell* LayoutTableCell::CreateAnonymous(Document* document) { - LayoutTableCell* layout_object = new LayoutTableCell(nullptr); +LayoutTableCell* LayoutTableCell::CreateAnonymous( + Document* document, + scoped_refptr<ComputedStyle> style) { + LayoutTableCell* layout_object = + LayoutObjectFactory::CreateTableCell(*document, *style); layout_object->SetDocumentForAnonymous(document); + layout_object->SetStyle(std::move(style)); return layout_object; } LayoutTableCell* LayoutTableCell::CreateAnonymousWithParent( const LayoutObject* parent) { - LayoutTableCell* new_cell = - LayoutTableCell::CreateAnonymous(&parent->GetDocument()); scoped_refptr<ComputedStyle> new_style = ComputedStyle::CreateAnonymousStyleWithDisplay(parent->StyleRef(), EDisplay::kTableCell); - new_cell->SetStyle(std::move(new_style)); + LayoutTableCell* new_cell = LayoutTableCell::CreateAnonymous( + &parent->GetDocument(), std::move(new_style)); return new_cell; }
diff --git a/third_party/blink/renderer/core/layout/layout_table_cell.h b/third_party/blink/renderer/core/layout/layout_table_cell.h index 48884ca..859bb4f 100644 --- a/third_party/blink/renderer/core/layout/layout_table_cell.h +++ b/third_party/blink/renderer/core/layout/layout_table_cell.h
@@ -235,7 +235,8 @@ cell_children_need_layout_ = b; } - static LayoutTableCell* CreateAnonymous(Document*); + static LayoutTableCell* CreateAnonymous(Document*, + scoped_refptr<ComputedStyle>); static LayoutTableCell* CreateAnonymousWithParent(const LayoutObject*); LayoutBox* CreateAnonymousBoxWithSameTypeAs( const LayoutObject* parent) const override {
diff --git a/third_party/blink/renderer/core/layout/layout_table_cell_test.cc b/third_party/blink/renderer/core/layout/layout_table_cell_test.cc index 74cc3ee4..3647756 100644 --- a/third_party/blink/renderer/core/layout/layout_table_cell_test.cc +++ b/third_party/blink/renderer/core/layout/layout_table_cell_test.cc
@@ -34,7 +34,9 @@ protected: void SetUp() override { RenderingTest::SetUp(); - cell_ = LayoutTableCell::CreateAnonymous(&GetDocument()); + auto style = ComputedStyle::Create(); + style->SetDisplay(EDisplay::kTableCell); + cell_ = LayoutTableCell::CreateAnonymous(&GetDocument(), std::move(style)); } void TearDown() override {
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc index 2247475..bbefd250 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc
@@ -789,11 +789,9 @@ // This positions any "leading" floats within the given exclusion space. // If we are also an empty inline, it will add any out-of-flow descendants. -// TODO(ikilpatrick): Do we need to always add the OOFs here? unsigned NGInlineLayoutAlgorithm::PositionLeadingItems( NGExclusionSpace* exclusion_space) { const Vector<NGInlineItem>& items = Node().ItemsData(false).items; - bool is_empty_inline = Node().IsEmptyInline(); LayoutUnit bfc_line_offset = ConstraintSpace().BfcOffset().line_offset; unsigned index = BreakToken() ? BreakToken()->ItemIndex() : 0; @@ -812,16 +810,11 @@ bfc_line_offset, margins, node, /* break_token */ nullptr); AddUnpositionedFloat(&unpositioned_floats_, &container_builder_, std::move(unpositioned_float)); - } else if (is_empty_inline && - item.Type() == NGInlineItem::kOutOfFlowPositioned) { - NGBlockNode node(ToLayoutBox(item.GetLayoutObject())); - container_builder_.AddInlineOutOfFlowChildCandidate( - node, NGLogicalOffset(), Style().Direction(), nullptr); } // Abort if we've found something that makes this a non-empty inline. if (!item.IsEmptyItem()) { - DCHECK(!is_empty_inline); + DCHECK(!Node().IsEmptyInline()); break; } }
diff --git a/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_marker_image.cc b/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_marker_image.cc index e54310c..653ab1b4 100644 --- a/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_marker_image.cc +++ b/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_marker_image.cc
@@ -22,14 +22,11 @@ return type == kLayoutObjectNGListMarkerImage || LayoutImage::IsOfType(type); } -// Use default_size(ascent/2) to compute ConcreteObjectSize as svg's intrinsic -// size. Otherwise the width of svg marker will be out of control. -void LayoutNGListMarkerImage::ComputeSVGIntrinsicSizingInfoByDefaultSize( +// Because ImageResource() is always LayoutImageResourceStyleImage. So we could +// use StyleImage::ImageSize to determine the concrete object size with +// default object size(ascent/2 x ascent/2). +void LayoutNGListMarkerImage::ComputeIntrinsicSizingInfoByDefaultSize( IntrinsicSizingInfo& intrinsic_sizing_info) const { - DCHECK(CachedImage()); - Image* image = CachedImage()->GetImage(); - DCHECK(image && image->IsSVGImage()); - const SimpleFontData* font_data = Style()->GetFont().PrimaryFont(); DCHECK(font_data); if (!font_data) @@ -37,14 +34,14 @@ LayoutUnit bullet_width = font_data->GetFontMetrics().Ascent() / LayoutUnit(2); - FloatSize default_size(bullet_width, bullet_width); - default_size.Scale(1 / Style()->EffectiveZoom()); - FloatSize concrete_size = ToSVGImage(image)->ConcreteObjectSize(default_size); - concrete_size.Scale(Style()->EffectiveZoom() * ImageDevicePixelRatio()); - LayoutSize svg_image_size(RoundedLayoutSize(concrete_size)); + LayoutSize default_object_size(bullet_width, bullet_width); + FloatSize concrete_size = ImageResource()->ImageSizeWithDefaultSize( + Style()->EffectiveZoom(), default_object_size); + concrete_size.Scale(ImageDevicePixelRatio()); + LayoutSize image_size(RoundedLayoutSize(concrete_size)); - intrinsic_sizing_info.size.SetWidth(svg_image_size.Width()); - intrinsic_sizing_info.size.SetHeight(svg_image_size.Height()); + intrinsic_sizing_info.size.SetWidth(image_size.Width()); + intrinsic_sizing_info.size.SetHeight(image_size.Height()); intrinsic_sizing_info.has_width = true; intrinsic_sizing_info.has_height = true; } @@ -53,17 +50,10 @@ IntrinsicSizingInfo& intrinsic_sizing_info) const { LayoutImage::ComputeIntrinsicSizingInfo(intrinsic_sizing_info); - // If this is an SVG image without intrinsic width and height, - // compute an intrinsic size using the concrete object size resolved - // with a default object size of 1em x 1em. - // TODO(fs): Apply this more generally to all images (CSS <image> values) - // that have no intrinsic width or height. I.e just always compute the - // concrete object size here. - if (intrinsic_sizing_info.size.IsEmpty() && CachedImage()) { - Image* image = CachedImage()->GetImage(); - if (image && image->IsSVGImage()) - ComputeSVGIntrinsicSizingInfoByDefaultSize(intrinsic_sizing_info); - } + // If this is an image without intrinsic width and height, compute the + // concrete object size by using the specified default object size. + if (intrinsic_sizing_info.size.IsEmpty() && ImageResource()) + ComputeIntrinsicSizingInfoByDefaultSize(intrinsic_sizing_info); } } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_marker_image.h b/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_marker_image.h index 050b8ae..8d38ae2 100644 --- a/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_marker_image.h +++ b/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_marker_image.h
@@ -20,7 +20,7 @@ private: bool IsOfType(LayoutObjectType) const override; - void ComputeSVGIntrinsicSizingInfoByDefaultSize(IntrinsicSizingInfo&) const; + void ComputeIntrinsicSizingInfoByDefaultSize(IntrinsicSizingInfo&) const; void ComputeIntrinsicSizingInfo(IntrinsicSizingInfo&) const final; };
diff --git a/third_party/blink/renderer/core/layout/ng/list/ng_unpositioned_list_marker.cc b/third_party/blink/renderer/core/layout/ng/list/ng_unpositioned_list_marker.cc index 34d89be4..c579125 100644 --- a/third_party/blink/renderer/core/layout/ng/list/ng_unpositioned_list_marker.cc +++ b/third_party/blink/renderer/core/layout/ng/list/ng_unpositioned_list_marker.cc
@@ -88,9 +88,9 @@ // Compute the inline offset of the marker. NGBoxFragment marker_fragment(space.GetWritingMode(), marker_physical_fragment); - NGLogicalSize maker_size = marker_fragment.Size(); - NGLogicalOffset marker_offset(InlineOffset(maker_size.inline_size), - content_offset->block_offset); + NGLogicalOffset marker_offset( + InlineOffset(marker_fragment.Size().inline_size), + content_offset->block_offset); // Adjust the block offset to align baselines of the marker and the content. NGLineHeightMetrics marker_metrics = marker_fragment.BaselineMetrics(
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc index be9e163..7360190 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_block_layout_algorithm.cc
@@ -229,7 +229,7 @@ } MinMaxSizeInput child_input; - if (child.IsInline() || child.IsAnonymous()) + if (child.IsInline() || child.IsAnonymousBlock()) child_input = {float_left_inline_size, float_right_inline_size}; MinMaxSize child_sizes; @@ -383,7 +383,7 @@ // Anonymous constraint spaces are auto-sized. Don't let that affect // block-axis percentage resolution. - if (ConstraintSpace().IsAnonymous() || Node().IsAnonymous()) + if (ConstraintSpace().IsAnonymous() || Node().IsAnonymousBlock()) child_percentage_size_ = ConstraintSpace().PercentageResolutionSize(); else child_percentage_size_ = adjusted_size;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.cc b/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.cc index d462627..6c45715 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.cc
@@ -96,8 +96,8 @@ return IsBlock() && box_->IsLayoutNGListMarker(); } -bool NGLayoutInputNode::IsAnonymous() const { - return box_->IsAnonymous(); +bool NGLayoutInputNode::IsAnonymousBlock() const { + return box_->IsAnonymousBlock(); } bool NGLayoutInputNode::IsQuirkyContainer() const {
diff --git a/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h b/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h index d052ddc..896a4bd 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h +++ b/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.h
@@ -60,7 +60,7 @@ bool ShouldBeConsideredAsReplaced() const; bool IsListItem() const; bool IsListMarker() const; - bool IsAnonymous() const; + bool IsAnonymousBlock() const; // If the node is a quirky container for margin collapsing, see: // https://html.spec.whatwg.org/#margin-collapsing-quirks
diff --git a/third_party/blink/renderer/core/layout/scrollbars_test.cc b/third_party/blink/renderer/core/layout/scrollbars_test.cc index be99e3b..ecf9efa 100644 --- a/third_party/blink/renderer/core/layout/scrollbars_test.cc +++ b/third_party/blink/renderer/core/layout/scrollbars_test.cc
@@ -1958,7 +1958,7 @@ EXPECT_FALSE(hit_test_result.GetScrollbar()); } -TEST_F(ScrollbarsTest, NotAllowMiddleButtonPressOnScrollbar) { +TEST_F(ScrollbarsTest, AllowMiddleButtonPressOnScrollbar) { ScopedOverlayScrollbarsForTest overlay_scrollbars(false); WebView().Resize(WebSize(200, 200)); SimRequest request("https://example.com/test.html", "text/html"); @@ -1985,12 +1985,12 @@ // Not allow press scrollbar with middle button. HandleMouseMoveEvent(195, 5); HandleMouseMiddlePressEvent(195, 5); - EXPECT_EQ(scrollbar->PressedPart(), ScrollbarPart::kNoPart); + EXPECT_EQ(scrollbar->PressedPart(), ScrollbarPart::kThumbPart); HandleMouseMiddleReleaseEvent(195, 5); } -// Ensure Scrollbar not release press by middle click. -TEST_F(ScrollbarsTest, MiddleClickShouldNotAffectScrollbarPress) { +// Ensure Scrollbar not release press by middle button down. +TEST_F(ScrollbarsTest, MiddleDownShouldNotAffectScrollbarPress) { ScopedOverlayScrollbarsForTest overlay_scrollbars(false); WebView().Resize(WebSize(200, 200)); SimRequest request("https://example.com/test.html", "text/html"); @@ -2036,11 +2036,8 @@ HandleMouseMiddlePressEvent(5, 5); EXPECT_EQ(scrollbar->PressedPart(), ScrollbarPart::kThumbPart); + // Middle button release should release scrollbar press state. HandleMouseMiddleReleaseEvent(5, 5); - EXPECT_EQ(scrollbar->PressedPart(), ScrollbarPart::kThumbPart); - - // Relase mouse left button should release scrollbar press state. - HandleMouseReleaseEvent(5, 5); EXPECT_EQ(scrollbar->PressedPart(), ScrollbarPart::kNoPart); }
diff --git a/third_party/blink/renderer/core/loader/base_fetch_context.cc b/third_party/blink/renderer/core/loader/base_fetch_context.cc index 861f8b0..81f6ee84 100644 --- a/third_party/blink/renderer/core/loader/base_fetch_context.cc +++ b/third_party/blink/renderer/core/loader/base_fetch_context.cc
@@ -95,8 +95,10 @@ if (!is_main_resource) { if (!request.DidSetHTTPReferrer()) { request.SetHTTPReferrer(SecurityPolicy::GenerateReferrer( - GetReferrerPolicy(), request.Url(), GetOutgoingReferrer())); - request.SetHTTPOriginIfNeeded(GetSecurityOrigin()); + GetFetchClientSettingsObject()->GetReferrerPolicy(), request.Url(), + GetFetchClientSettingsObject()->GetOutgoingReferrer())); + request.SetHTTPOriginIfNeeded( + GetFetchClientSettingsObject()->GetSecurityOrigin()); } else { DCHECK_EQ(SecurityPolicy::GenerateReferrer(request.GetReferrerPolicy(), request.Url(),
diff --git a/third_party/blink/renderer/core/loader/base_fetch_context.h b/third_party/blink/renderer/core/loader/base_fetch_context.h index c77076d..eccbc40 100644 --- a/third_party/blink/renderer/core/loader/base_fetch_context.h +++ b/third_party/blink/renderer/core/loader/base_fetch_context.h
@@ -11,6 +11,7 @@ #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h" #include "third_party/blink/renderer/core/frame/web_feature_forward.h" +#include "third_party/blink/renderer/core/script/fetch_client_settings_object.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/loader/fetch/fetch_context.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_request.h" @@ -50,6 +51,8 @@ void Trace(blink::Visitor*) override; + virtual const FetchClientSettingsObject* GetFetchClientSettingsObject() + const = 0; virtual KURL GetSiteForCookies() const = 0; virtual SubresourceFilter* GetSubresourceFilter() const = 0; virtual void CountUsage(WebFeature) const = 0; @@ -85,8 +88,6 @@ SecurityViolationReportingPolicy) const = 0; virtual bool ShouldBlockFetchAsCredentialedSubresource(const ResourceRequest&, const KURL&) const = 0; - virtual ReferrerPolicy GetReferrerPolicy() const = 0; - virtual String GetOutgoingReferrer() const = 0; virtual const KURL& Url() const = 0; virtual const SecurityOrigin* GetParentSecurityOrigin() const = 0; virtual base::Optional<mojom::IPAddressSpace> GetAddressSpace() const = 0;
diff --git a/third_party/blink/renderer/core/loader/base_fetch_context_test.cc b/third_party/blink/renderer/core/loader/base_fetch_context_test.cc index fda0338..e6937a74 100644 --- a/third_party/blink/renderer/core/loader/base_fetch_context_test.cc +++ b/third_party/blink/renderer/core/loader/base_fetch_context_test.cc
@@ -33,6 +33,7 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/platform/websocket_handshake_throttle.h" +#include "third_party/blink/renderer/core/script/fetch_client_settings_object_impl.h" #include "third_party/blink/renderer/core/testing/null_execution_context.h" #include "third_party/blink/renderer/platform/loader/fetch/fetch_initiator_type_names.h" #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" @@ -42,10 +43,16 @@ class MockBaseFetchContext final : public BaseFetchContext { public: explicit MockBaseFetchContext(ExecutionContext* execution_context) - : execution_context_(execution_context) {} + : execution_context_(execution_context), + fetch_client_settings_object_( + new FetchClientSettingsObjectImpl(*execution_context)) {} ~MockBaseFetchContext() override = default; // BaseFetchContext overrides: + const FetchClientSettingsObject* GetFetchClientSettingsObject() + const override { + return fetch_client_settings_object_.Get(); + } KURL GetSiteForCookies() const override { return KURL(); } bool AllowScriptFromSource(const KURL&) const override { return false; } SubresourceFilter* GetSubresourceFilter() const override { return nullptr; } @@ -79,16 +86,10 @@ const KURL&) const override { return false; } - ReferrerPolicy GetReferrerPolicy() const override { - return execution_context_->GetReferrerPolicy(); - } - String GetOutgoingReferrer() const override { - return execution_context_->OutgoingReferrer(); - } const KURL& Url() const override { return execution_context_->Url(); } const SecurityOrigin* GetSecurityOrigin() const override { - return execution_context_->GetSecurityOrigin(); + return fetch_client_settings_object_->GetSecurityOrigin(); } const SecurityOrigin* GetParentSecurityOrigin() const override { return nullptr; @@ -104,6 +105,7 @@ void Trace(blink::Visitor* visitor) override { visitor->Trace(execution_context_); + visitor->Trace(fetch_client_settings_object_); BaseFetchContext::Trace(visitor); } @@ -112,6 +114,7 @@ private: Member<ExecutionContext> execution_context_; + Member<FetchClientSettingsObjectImpl> fetch_client_settings_object_; bool is_detached_ = false; };
diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc index ed8cb08..c5d64e06 100644 --- a/third_party/blink/renderer/core/loader/document_loader.cc +++ b/third_party/blink/renderer/core/loader/document_loader.cc
@@ -905,7 +905,9 @@ if (history_item_ && IsBackForwardLoadType(load_type_)) document->SetStateForNewFormElements(history_item_->GetDocumentState()); - document->GetClientHintsPreferences().UpdateFrom(client_hints_preferences_); + DCHECK(document->GetFrame()); + document->GetFrame()->GetClientHintsPreferences().UpdateFrom( + client_hints_preferences_); // TODO(japhet): There's no reason to wait until commit to set these bits. Settings* settings = document->GetSettings();
diff --git a/third_party/blink/renderer/core/loader/document_threadable_loader.cc b/third_party/blink/renderer/core/loader/document_threadable_loader.cc index d4f5098c..2fce5f1 100644 --- a/third_party/blink/renderer/core/loader/document_threadable_loader.cc +++ b/third_party/blink/renderer/core/loader/document_threadable_loader.cc
@@ -928,8 +928,9 @@ // Note that CORS-preflight is usually handled in the Network Service side, // but still done in Blink side when it is needed on redirects. // https://crbug.com/736308. - if (out_of_blink_cors_ && actual_request_.IsNull() && - !response.WasFetchedViaServiceWorker()) { + if (out_of_blink_cors_ && !response.WasFetchedViaServiceWorker()) { + DCHECK(actual_request_.IsNull()); + fallback_request_for_service_worker_ = ResourceRequest(); client_->DidReceiveResponse(resource->Identifier(), response, std::move(handle)); return;
diff --git a/third_party/blink/renderer/core/loader/frame_fetch_context.cc b/third_party/blink/renderer/core/loader/frame_fetch_context.cc index 103f20d4..9a90285 100644 --- a/third_party/blink/renderer/core/loader/frame_fetch_context.cc +++ b/third_party/blink/renderer/core/loader/frame_fetch_context.cc
@@ -223,10 +223,7 @@ struct FrameFetchContext::FrozenState final : GarbageCollectedFinalized<FrozenState> { - FrozenState(ReferrerPolicy referrer_policy, - const String& outgoing_referrer, - const KURL& url, - scoped_refptr<const SecurityOrigin> security_origin, + FrozenState(const KURL& url, scoped_refptr<const SecurityOrigin> parent_security_origin, const base::Optional<mojom::IPAddressSpace>& address_space, const ContentSecurityPolicy* content_security_policy, @@ -237,10 +234,7 @@ const String& user_agent, bool is_main_frame, bool is_svg_image_chrome_client) - : referrer_policy(referrer_policy), - outgoing_referrer(outgoing_referrer), - url(url), - security_origin(std::move(security_origin)), + : url(url), parent_security_origin(std::move(parent_security_origin)), address_space(address_space), content_security_policy(content_security_policy), @@ -252,10 +246,7 @@ is_main_frame(is_main_frame), is_svg_image_chrome_client(is_svg_image_chrome_client) {} - const ReferrerPolicy referrer_policy; - const String outgoing_referrer; const KURL url; - const scoped_refptr<const SecurityOrigin> security_origin; const scoped_refptr<const SecurityOrigin> parent_security_origin; const base::Optional<mojom::IPAddressSpace> address_space; const Member<const ContentSecurityPolicy> content_security_policy; @@ -295,6 +286,10 @@ document_(document), save_data_enabled_(GetNetworkStateNotifier().SaveDataEnabled() && !GetSettings()->GetDataSaverHoldbackWebApi()) { + if (document_) { + fetch_client_settings_object_ = + new FetchClientSettingsObjectImpl(*document_); + } DCHECK(GetFrame()); } @@ -303,6 +298,8 @@ DCHECK(document); CHECK(context.IsFrameFetchContext()); static_cast<FrameFetchContext&>(context).document_ = document; + static_cast<FrameFetchContext&>(context).fetch_client_settings_object_ = + new FetchClientSettingsObjectImpl(*document); } FrameFetchContext::~FrameFetchContext() { @@ -349,6 +346,12 @@ return GetFrame()->GetFrameScheduler(); } +const FetchClientSettingsObject* +FrameFetchContext::GetFetchClientSettingsObject() const { + DCHECK(fetch_client_settings_object_); + return fetch_client_settings_object_.Get(); +} + KURL FrameFetchContext::GetSiteForCookies() const { if (IsDetached()) return frozen_state_->site_for_cookies; @@ -873,9 +876,10 @@ } const SecurityOrigin* FrameFetchContext::GetSecurityOrigin() const { - if (IsDetached()) - return frozen_state_->security_origin.get(); - return document_ ? document_->GetSecurityOrigin() : nullptr; + // This can be called before |fetch_client_settings_object_| is set. + if (!fetch_client_settings_object_) + return nullptr; + return fetch_client_settings_object_->GetSecurityOrigin(); } void FrameFetchContext::ModifyRequestForCSP(ResourceRequest& resource_request) { @@ -1192,18 +1196,6 @@ return RuntimeEnabledFeatures::BlockCredentialedSubresourcesEnabled(); } -ReferrerPolicy FrameFetchContext::GetReferrerPolicy() const { - if (IsDetached()) - return frozen_state_->referrer_policy; - return document_->GetReferrerPolicy(); -} - -String FrameFetchContext::GetOutgoingReferrer() const { - if (IsDetached()) - return frozen_state_->outgoing_referrer; - return document_->OutgoingReferrer(); -} - const KURL& FrameFetchContext::Url() const { if (IsDetached()) return frozen_state_->url; @@ -1290,14 +1282,15 @@ return GetSecurityOrigin(); } -ClientHintsPreferences FrameFetchContext::GetClientHintsPreferences() const { +const ClientHintsPreferences FrameFetchContext::GetClientHintsPreferences() + const { if (IsDetached()) return frozen_state_->client_hints_preferences; - if (!document_) + if (!document_ || !document_->GetFrame()) return ClientHintsPreferences(); - return document_->GetClientHintsPreferences(); + return document_->GetFrame()->GetClientHintsPreferences(); } float FrameFetchContext::GetDevicePixelRatio() const { @@ -1409,20 +1402,22 @@ if (document_) { frozen_state_ = new FrozenState( - GetReferrerPolicy(), GetOutgoingReferrer(), Url(), GetSecurityOrigin(), - GetParentSecurityOrigin(), GetAddressSpace(), + Url(), GetParentSecurityOrigin(), GetAddressSpace(), GetContentSecurityPolicy(), GetSiteForCookies(), GetRequestorOrigin(), GetClientHintsPreferences(), GetDevicePixelRatio(), GetUserAgent(), IsMainFrame(), IsSVGImageChromeClient()); + fetch_client_settings_object_ = + new FetchClientSettingsObjectSnapshot(*document_); } else { // Some getters are unavailable in this case. frozen_state_ = new FrozenState( - kReferrerPolicyDefault, String(), NullURL(), GetSecurityOrigin(), - GetParentSecurityOrigin(), GetAddressSpace(), + NullURL(), GetParentSecurityOrigin(), GetAddressSpace(), GetContentSecurityPolicy(), GetSiteForCookies(), SecurityOrigin::CreateUniqueOpaque(), GetClientHintsPreferences(), GetDevicePixelRatio(), GetUserAgent(), IsMainFrame(), IsSVGImageChromeClient()); + fetch_client_settings_object_ = new FetchClientSettingsObjectSnapshot( + NullURL(), nullptr, kReferrerPolicyDefault, String()); } // This is needed to break a reference cycle in which off-heap @@ -1436,6 +1431,7 @@ visitor->Trace(document_loader_); visitor->Trace(document_); visitor->Trace(frozen_state_); + visitor->Trace(fetch_client_settings_object_); BaseFetchContext::Trace(visitor); }
diff --git a/third_party/blink/renderer/core/loader/frame_fetch_context.h b/third_party/blink/renderer/core/loader/frame_fetch_context.h index 754009a..2c3c233 100644 --- a/third_party/blink/renderer/core/loader/frame_fetch_context.h +++ b/third_party/blink/renderer/core/loader/frame_fetch_context.h
@@ -37,6 +37,8 @@ #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h" #include "third_party/blink/renderer/core/loader/base_fetch_context.h" +#include "third_party/blink/renderer/core/script/fetch_client_settings_object_impl.h" +#include "third_party/blink/renderer/core/script/fetch_client_settings_object_snapshot.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/loader/fetch/client_hints_preferences.h" #include "third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h" @@ -206,6 +208,8 @@ scoped_refptr<base::SingleThreadTaskRunner> GetLoadingTaskRunner() override; // BaseFetchContext overrides: + const FetchClientSettingsObject* GetFetchClientSettingsObject() + const override; KURL GetSiteForCookies() const override; SubresourceFilter* GetSubresourceFilter() const override; bool AllowScriptFromSource(const KURL&) const override; @@ -230,8 +234,6 @@ bool ShouldBlockFetchAsCredentialedSubresource(const ResourceRequest&, const KURL&) const override; - ReferrerPolicy GetReferrerPolicy() const override; - String GetOutgoingReferrer() const override; const KURL& Url() const override; const SecurityOrigin* GetParentSecurityOrigin() const override; base::Optional<mojom::IPAddressSpace> GetAddressSpace() const override; @@ -242,7 +244,7 @@ Settings* GetSettings() const; String GetUserAgent() const; scoped_refptr<const SecurityOrigin> GetRequestorOrigin(); - ClientHintsPreferences GetClientHintsPreferences() const; + const ClientHintsPreferences GetClientHintsPreferences() const; float GetDevicePixelRatio() const; bool ShouldSendClientHint(mojom::WebClientHintsType, const ClientHintsPreferences&, @@ -275,6 +277,8 @@ // Non-null only when detached. Member<const FrozenState> frozen_state_; + + Member<FetchClientSettingsObject> fetch_client_settings_object_; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/loader/frame_fetch_context_test.cc b/third_party/blink/renderer/core/loader/frame_fetch_context_test.cc index def8437..ef4702c 100644 --- a/third_party/blink/renderer/core/loader/frame_fetch_context_test.cc +++ b/third_party/blink/renderer/core/loader/frame_fetch_context_test.cc
@@ -632,7 +632,7 @@ ExpectHeader("https://www.example.com/1.gif", "Device-Memory", false, ""); ClientHintsPreferences preferences; preferences.SetShouldSendForTesting(mojom::WebClientHintsType::kDeviceMemory); - document->GetClientHintsPreferences().UpdateFrom(preferences); + document->GetFrame()->GetClientHintsPreferences().UpdateFrom(preferences); ApproximatedDeviceMemory::SetPhysicalMemoryMBForTesting(4096); ExpectHeader("https://www.example.com/1.gif", "Device-Memory", true, "4"); ExpectHeader("https://www.example.com/1.gif", "DPR", false, ""); @@ -657,7 +657,7 @@ ExpectHeader("http://www.example.com/1.gif", "Device-Memory", false, ""); ClientHintsPreferences preferences; preferences.SetShouldSendForTesting(mojom::WebClientHintsType::kDeviceMemory); - document->GetClientHintsPreferences().UpdateFrom(preferences); + document->GetFrame()->GetClientHintsPreferences().UpdateFrom(preferences); ApproximatedDeviceMemory::SetPhysicalMemoryMBForTesting(4096); ExpectHeader("http://www.example.com/1.gif", "Device-Memory", false, ""); ExpectHeader("http://www.example.com/1.gif", "DPR", false, ""); @@ -674,7 +674,7 @@ ExpectHeader("http://localhost/1.gif", "Device-Memory", false, ""); ClientHintsPreferences preferences; preferences.SetShouldSendForTesting(mojom::WebClientHintsType::kDeviceMemory); - document->GetClientHintsPreferences().UpdateFrom(preferences); + document->GetFrame()->GetClientHintsPreferences().UpdateFrom(preferences); ApproximatedDeviceMemory::SetPhysicalMemoryMBForTesting(4096); ExpectHeader("http://localhost/1.gif", "Device-Memory", true, "4"); ExpectHeader("http://localhost/1.gif", "DPR", false, ""); @@ -686,7 +686,7 @@ ExpectHeader("https://www.example.com/1.gif", "Device-Memory", false, ""); ClientHintsPreferences preferences; preferences.SetShouldSendForTesting(mojom::WebClientHintsType::kDeviceMemory); - document->GetClientHintsPreferences().UpdateFrom(preferences); + document->GetFrame()->GetClientHintsPreferences().UpdateFrom(preferences); ApproximatedDeviceMemory::SetPhysicalMemoryMBForTesting(4096); ExpectHeader("https://www.example.com/1.gif", "Device-Memory", true, "4"); ApproximatedDeviceMemory::SetPhysicalMemoryMBForTesting(2048); @@ -704,7 +704,7 @@ ExpectHeader("https://www.example.com/1.gif", "DPR", false, ""); ClientHintsPreferences preferences; preferences.SetShouldSendForTesting(mojom::WebClientHintsType::kDpr); - document->GetClientHintsPreferences().UpdateFrom(preferences); + document->GetFrame()->GetClientHintsPreferences().UpdateFrom(preferences); ExpectHeader("https://www.example.com/1.gif", "DPR", true, "1"); dummy_page_holder->GetPage().SetDeviceScaleFactorDeprecated(2.5); ExpectHeader("https://www.example.com/1.gif", "DPR", true, "2.5"); @@ -725,7 +725,7 @@ ClientHintsPreferences preferences; preferences.SetShouldSendForTesting( mojom::WebClientHintsType::kResourceWidth); - document->GetClientHintsPreferences().UpdateFrom(preferences); + document->GetFrame()->GetClientHintsPreferences().UpdateFrom(preferences); ExpectHeader("https://www.example.com/1.gif", "Width", true, "500", 500); ExpectHeader("https://www.example.com/1.gif", "Width", true, "667", 666.6666); ExpectHeader("https://www.example.com/1.gif", "DPR", false, ""); @@ -740,7 +740,7 @@ ClientHintsPreferences preferences; preferences.SetShouldSendForTesting( mojom::WebClientHintsType::kViewportWidth); - document->GetClientHintsPreferences().UpdateFrom(preferences); + document->GetFrame()->GetClientHintsPreferences().UpdateFrom(preferences); ExpectHeader("https://www.example.com/1.gif", "Viewport-Width", true, "500"); dummy_page_holder->GetFrameView().SetLayoutSizeFixedToFrameSize(false); dummy_page_holder->GetFrameView().SetLayoutSize(IntSize(800, 800)); @@ -770,7 +770,7 @@ preferences.SetShouldSendForTesting(mojom::WebClientHintsType::kDownlink); preferences.SetShouldSendForTesting(mojom::WebClientHintsType::kEct); ApproximatedDeviceMemory::SetPhysicalMemoryMBForTesting(4096); - document->GetClientHintsPreferences().UpdateFrom(preferences); + document->GetFrame()->GetClientHintsPreferences().UpdateFrom(preferences); ExpectHeader("https://www.example.com/1.gif", "Device-Memory", true, "4"); ExpectHeader("https://www.example.com/1.gif", "DPR", true, "1"); ExpectHeader("https://www.example.com/1.gif", "Width", true, "400", 400); @@ -1472,13 +1472,13 @@ FetchParameters::ResourceWidth resource_width; ResourceLoaderOptions options; - document->GetClientHintsPreferences().SetShouldSendForTesting( + document->GetFrame()->GetClientHintsPreferences().SetShouldSendForTesting( mojom::WebClientHintsType::kDeviceMemory); - document->GetClientHintsPreferences().SetShouldSendForTesting( + document->GetFrame()->GetClientHintsPreferences().SetShouldSendForTesting( mojom::WebClientHintsType::kDpr); - document->GetClientHintsPreferences().SetShouldSendForTesting( + document->GetFrame()->GetClientHintsPreferences().SetShouldSendForTesting( mojom::WebClientHintsType::kResourceWidth); - document->GetClientHintsPreferences().SetShouldSendForTesting( + document->GetFrame()->GetClientHintsPreferences().SetShouldSendForTesting( mojom::WebClientHintsType::kViewportWidth); dummy_page_holder = nullptr;
diff --git a/third_party/blink/renderer/core/loader/http_equiv.cc b/third_party/blink/renderer/core/loader/http_equiv.cc index 8931a90..ccc559c 100644 --- a/third_party/blink/renderer/core/loader/http_equiv.cc +++ b/third_party/blink/renderer/core/loader/http_equiv.cc
@@ -86,12 +86,13 @@ void HttpEquiv::ProcessHttpEquivAcceptCH(Document& document, const AtomicString& content) { - if (!document.GetFrame()) + LocalFrame* frame = document.GetFrame(); + if (!frame) return; UseCounter::Count(document, WebFeature::kClientHintsMetaAcceptCH); - FrameClientHintsPreferencesContext hints_context(document.GetFrame()); - document.GetClientHintsPreferences().UpdateFromAcceptClientHintsHeader( + FrameClientHintsPreferencesContext hints_context(frame); + frame->GetClientHintsPreferences().UpdateFromAcceptClientHintsHeader( content, document.Url(), &hints_context); }
diff --git a/third_party/blink/renderer/core/loader/image_loader.cc b/third_party/blink/renderer/core/loader/image_loader.cc index 71ec5b6..b6480650 100644 --- a/third_party/blink/renderer/core/loader/image_loader.cc +++ b/third_party/blink/renderer/core/loader/image_loader.cc
@@ -430,9 +430,10 @@ resource_request.SetSkipServiceWorker(true); } + DCHECK(document.GetFrame()); FetchParameters params(resource_request, resource_loader_options); ConfigureRequest(params, bypass_behavior, *element_, - document.GetClientHintsPreferences()); + document.GetFrame()->GetClientHintsPreferences()); if (update_behavior != kUpdateForcedReload && document.GetFrame()) document.GetFrame()->MaybeAllowImagePlaceholder(params);
diff --git a/third_party/blink/renderer/core/loader/link_loader.cc b/third_party/blink/renderer/core/loader/link_loader.cc index 7cd7ea4..a06f667 100644 --- a/third_party/blink/renderer/core/loader/link_loader.cc +++ b/third_party/blink/renderer/core/loader/link_loader.cc
@@ -502,7 +502,8 @@ // |document| is the node document here, and its context document is the // relevant settings object. Document* context_document = document.ContextDocument(); - FetchClientSettingsObjectSnapshot settings_object(*context_document); + auto* settings_object = + new FetchClientSettingsObjectSnapshot(*context_document); Modulator* modulator = Modulator::From(ToScriptStateForMainWorld(context_document->GetFrame()));
diff --git a/third_party/blink/renderer/core/loader/link_loader_test.cc b/third_party/blink/renderer/core/loader/link_loader_test.cc index 031a66b..3f161f0 100644 --- a/third_party/blink/renderer/core/loader/link_loader_test.cc +++ b/third_party/blink/renderer/core/loader/link_loader_test.cc
@@ -468,7 +468,7 @@ void FetchSingle( const ModuleScriptFetchRequest& request, - const FetchClientSettingsObjectSnapshot& fetch_client_settings_object, + FetchClientSettingsObjectSnapshot* fetch_client_settings_object, ModuleGraphLevel, ModuleScriptCustomFetchType custom_fetch_type, SingleModuleClient*) override {
diff --git a/third_party/blink/renderer/core/loader/modulescript/module_script_loader.cc b/third_party/blink/renderer/core/loader/modulescript/module_script_loader.cc index c0ac28b..5b65489 100644 --- a/third_party/blink/renderer/core/loader/modulescript/module_script_loader.cc +++ b/third_party/blink/renderer/core/loader/modulescript/module_script_loader.cc
@@ -79,7 +79,7 @@ void ModuleScriptLoader::Fetch( const ModuleScriptFetchRequest& module_request, - const FetchClientSettingsObjectSnapshot& fetch_client_settings_object, + FetchClientSettingsObjectSnapshot* fetch_client_settings_object, ModuleGraphLevel level, Modulator* module_map_settings_object, ModuleScriptCustomFetchType custom_fetch_type, @@ -95,7 +95,7 @@ // https://html.spec.whatwg.org/#fetch-a-single-module-script void ModuleScriptLoader::FetchInternal( const ModuleScriptFetchRequest& module_request, - const FetchClientSettingsObjectSnapshot& fetch_client_settings_object, + FetchClientSettingsObjectSnapshot* fetch_client_settings_object, ModuleGraphLevel level, ModuleScriptCustomFetchType custom_fetch_type) { // Step 4. "Set moduleMap[url] to "fetching"." [spec text] @@ -149,7 +149,7 @@ // [SMSR] "... and its credentials mode to options's credentials mode." // [spec text] fetch_params.SetCrossOriginAccessControl( - fetch_client_settings_object.GetSecurityOrigin(), + fetch_client_settings_object->GetSecurityOrigin(), options_.CredentialsMode()); // Step 5. "... referrer is referrer, ..." [spec text]
diff --git a/third_party/blink/renderer/core/loader/modulescript/module_script_loader.h b/third_party/blink/renderer/core/loader/modulescript/module_script_loader.h index e839385..c2e1d33 100644 --- a/third_party/blink/renderer/core/loader/modulescript/module_script_loader.h +++ b/third_party/blink/renderer/core/loader/modulescript/module_script_loader.h
@@ -49,7 +49,7 @@ static void Fetch( const ModuleScriptFetchRequest&, - const FetchClientSettingsObjectSnapshot& fetch_client_settings_object, + FetchClientSettingsObjectSnapshot* fetch_client_settings_object, ModuleGraphLevel, Modulator* module_map_settings_object, ModuleScriptCustomFetchType, @@ -74,7 +74,7 @@ void FetchInternal( const ModuleScriptFetchRequest&, - const FetchClientSettingsObjectSnapshot& fetch_client_settings_object, + FetchClientSettingsObjectSnapshot* fetch_client_settings_object, ModuleGraphLevel, ModuleScriptCustomFetchType);
diff --git a/third_party/blink/renderer/core/loader/modulescript/module_script_loader_test.cc b/third_party/blink/renderer/core/loader/modulescript/module_script_loader_test.cc index 84e147d..9fe4f3400 100644 --- a/third_party/blink/renderer/core/loader/modulescript/module_script_loader_test.cc +++ b/third_party/blink/renderer/core/loader/modulescript/module_script_loader_test.cc
@@ -202,7 +202,8 @@ TestModuleScriptLoaderClient* client) { ModuleScriptLoaderRegistry* registry = ModuleScriptLoaderRegistry::Create(); KURL url("data:text/javascript,export default 'grapes';"); - FetchClientSettingsObjectSnapshot fetch_client_settings_object(GetDocument()); + auto* fetch_client_settings_object = + new FetchClientSettingsObjectSnapshot(GetDocument()); ModuleScriptLoader::Fetch( ModuleScriptFetchRequest::CreateForTest(url), fetch_client_settings_object, ModuleGraphLevel::kTopLevelModuleFetch, @@ -255,7 +256,8 @@ TestModuleScriptLoaderClient* client) { ModuleScriptLoaderRegistry* registry = ModuleScriptLoaderRegistry::Create(); KURL url("data:text/javascript,import 'invalid';export default 'grapes';"); - FetchClientSettingsObjectSnapshot fetch_client_settings_object(GetDocument()); + auto* fetch_client_settings_object = + new FetchClientSettingsObjectSnapshot(GetDocument()); GetModulator()->SetModuleRequests({"invalid"}); ModuleScriptLoader::Fetch( ModuleScriptFetchRequest::CreateForTest(url), @@ -296,7 +298,8 @@ ModuleScriptLoaderRegistry* registry = ModuleScriptLoaderRegistry::Create(); KURL url; EXPECT_FALSE(url.IsValid()); - FetchClientSettingsObjectSnapshot fetch_client_settings_object(GetDocument()); + auto* fetch_client_settings_object = + new FetchClientSettingsObjectSnapshot(GetDocument()); ModuleScriptLoader::Fetch( ModuleScriptFetchRequest::CreateForTest(url), fetch_client_settings_object, ModuleGraphLevel::kTopLevelModuleFetch, @@ -332,7 +335,8 @@ KURL url("https://example.test/module.js"); URLTestHelpers::RegisterMockedURLLoad( url, test::CoreTestDataPath("module.js"), "text/javascript"); - FetchClientSettingsObjectSnapshot fetch_client_settings_object(GetDocument()); + auto* fetch_client_settings_object = + new FetchClientSettingsObjectSnapshot(GetDocument()); ModuleScriptLoaderRegistry* registry = ModuleScriptLoaderRegistry::Create(); ModuleScriptLoader::Fetch(
diff --git a/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.cc b/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.cc index 916e2ad8..67a0ecf 100644 --- a/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.cc +++ b/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.cc
@@ -20,7 +20,7 @@ void ModuleTreeLinker::Fetch( const KURL& url, - const FetchClientSettingsObjectSnapshot& fetch_client_settings_object, + FetchClientSettingsObjectSnapshot* fetch_client_settings_object, WebURLRequest::RequestContext destination, const ScriptFetchOptions& options, Modulator* modulator, @@ -37,7 +37,7 @@ void ModuleTreeLinker::FetchDescendantsForInlineScript( ModuleScript* module_script, - const FetchClientSettingsObjectSnapshot& fetch_client_settings_object, + FetchClientSettingsObjectSnapshot* fetch_client_settings_object, WebURLRequest::RequestContext destination, Modulator* modulator, ModuleScriptCustomFetchType custom_fetch_type, @@ -53,7 +53,7 @@ } ModuleTreeLinker::ModuleTreeLinker( - const FetchClientSettingsObjectSnapshot& fetch_client_settings_object, + FetchClientSettingsObjectSnapshot* fetch_client_settings_object, WebURLRequest::RequestContext destination, Modulator* modulator, ModuleScriptCustomFetchType custom_fetch_type, @@ -71,6 +71,7 @@ } void ModuleTreeLinker::Trace(blink::Visitor* visitor) { + visitor->Trace(fetch_client_settings_object_); visitor->Trace(modulator_); visitor->Trace(registry_); visitor->Trace(client_); @@ -164,7 +165,7 @@ // settings object's API base URL.</spec> if (RuntimeEnabledFeatures::LayeredAPIEnabled()) { url = blink::layered_api::ResolveFetchingURL( - url, fetch_client_settings_object_.BaseURL()); + url, fetch_client_settings_object_->BaseURL()); } #if DCHECK_IS_ON() @@ -192,7 +193,7 @@ url, destination_, options, SecurityPolicy::GenerateReferrer( options.GetReferrerPolicy(), url, - fetch_client_settings_object_.GetOutgoingReferrer()), + fetch_client_settings_object_->GetOutgoingReferrer()), TextPosition::MinimumPosition()); InitiateInternalModuleScriptGraphFetching( @@ -231,7 +232,7 @@ ++num_incomplete_fetches_; // [IMSGF] Step 2. Fetch a single module script given ... - modulator_->FetchSingle(request, fetch_client_settings_object_, level, + modulator_->FetchSingle(request, fetch_client_settings_object_.Get(), level, custom_fetch_type_, this); // [IMSGF] Step 3-- are executed when NotifyModuleLoadFinished() is called.
diff --git a/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.h b/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.h index 9411980b..bd67dd7 100644 --- a/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.h +++ b/third_party/blink/renderer/core/loader/modulescript/module_tree_linker.h
@@ -39,7 +39,7 @@ // https://html.spec.whatwg.org/#fetch-a-module-script-tree static void Fetch( const KURL&, - const FetchClientSettingsObjectSnapshot& fetch_client_settings_object, + FetchClientSettingsObjectSnapshot* fetch_client_settings_object, WebURLRequest::RequestContext destination, const ScriptFetchOptions&, Modulator*, @@ -50,7 +50,7 @@ // [FDaI] for an inline script. static void FetchDescendantsForInlineScript( ModuleScript*, - const FetchClientSettingsObjectSnapshot& fetch_client_settings_object, + FetchClientSettingsObjectSnapshot* fetch_client_settings_object, WebURLRequest::RequestContext destination, Modulator*, ModuleScriptCustomFetchType, @@ -67,7 +67,7 @@ private: ModuleTreeLinker( - const FetchClientSettingsObjectSnapshot& fetch_client_settings_object, + FetchClientSettingsObjectSnapshot* fetch_client_settings_object, WebURLRequest::RequestContext destination, Modulator*, ModuleScriptCustomFetchType, @@ -112,7 +112,7 @@ ScriptValue FindFirstParseError(ModuleScript*, HeapHashSet<Member<ModuleScript>>*) const; - const FetchClientSettingsObjectSnapshot fetch_client_settings_object_; + const Member<FetchClientSettingsObjectSnapshot> fetch_client_settings_object_; const WebURLRequest::RequestContext destination_; const Member<Modulator> modulator_; const ModuleScriptCustomFetchType custom_fetch_type_;
diff --git a/third_party/blink/renderer/core/loader/modulescript/module_tree_linker_test.cc b/third_party/blink/renderer/core/loader/modulescript/module_tree_linker_test.cc index 58d02c11..9f63db9 100644 --- a/third_party/blink/renderer/core/loader/modulescript/module_tree_linker_test.cc +++ b/third_party/blink/renderer/core/loader/modulescript/module_tree_linker_test.cc
@@ -131,7 +131,7 @@ void FetchSingle( const ModuleScriptFetchRequest& request, - const FetchClientSettingsObjectSnapshot& fetch_client_settings_object, + FetchClientSettingsObjectSnapshot* fetch_client_settings_object, ModuleGraphLevel, ModuleScriptCustomFetchType, SingleModuleClient* client) override { @@ -209,10 +209,10 @@ KURL url("http://example.com/root.js"); TestModuleTreeClient* client = new TestModuleTreeClient; - ModuleTreeLinker::Fetch(url, FetchClientSettingsObjectSnapshot(GetDocument()), - WebURLRequest::kRequestContextScript, - ScriptFetchOptions(), GetModulator(), - ModuleScriptCustomFetchType::kNone, registry, client); + ModuleTreeLinker::Fetch( + url, new FetchClientSettingsObjectSnapshot(GetDocument()), + WebURLRequest::kRequestContextScript, ScriptFetchOptions(), + GetModulator(), ModuleScriptCustomFetchType::kNone, registry, client); EXPECT_FALSE(client->WasNotifyFinished()) << "ModuleTreeLinker should always finish asynchronously."; @@ -231,10 +231,10 @@ KURL url("http://example.com/root.js"); TestModuleTreeClient* client = new TestModuleTreeClient; - ModuleTreeLinker::Fetch(url, FetchClientSettingsObjectSnapshot(GetDocument()), - WebURLRequest::kRequestContextScript, - ScriptFetchOptions(), GetModulator(), - ModuleScriptCustomFetchType::kNone, registry, client); + ModuleTreeLinker::Fetch( + url, new FetchClientSettingsObjectSnapshot(GetDocument()), + WebURLRequest::kRequestContextScript, ScriptFetchOptions(), + GetModulator(), ModuleScriptCustomFetchType::kNone, registry, client); EXPECT_FALSE(client->WasNotifyFinished()) << "ModuleTreeLinker should always finish asynchronously."; @@ -257,10 +257,10 @@ KURL url("http://example.com/root.js"); TestModuleTreeClient* client = new TestModuleTreeClient; - ModuleTreeLinker::Fetch(url, FetchClientSettingsObjectSnapshot(GetDocument()), - WebURLRequest::kRequestContextScript, - ScriptFetchOptions(), GetModulator(), - ModuleScriptCustomFetchType::kNone, registry, client); + ModuleTreeLinker::Fetch( + url, new FetchClientSettingsObjectSnapshot(GetDocument()), + WebURLRequest::kRequestContextScript, ScriptFetchOptions(), + GetModulator(), ModuleScriptCustomFetchType::kNone, registry, client); EXPECT_FALSE(client->WasNotifyFinished()) << "ModuleTreeLinker should always finish asynchronously."; @@ -284,10 +284,10 @@ KURL url("http://example.com/root.js"); TestModuleTreeClient* client = new TestModuleTreeClient; - ModuleTreeLinker::Fetch(url, FetchClientSettingsObjectSnapshot(GetDocument()), - WebURLRequest::kRequestContextScript, - ScriptFetchOptions(), GetModulator(), - ModuleScriptCustomFetchType::kNone, registry, client); + ModuleTreeLinker::Fetch( + url, new FetchClientSettingsObjectSnapshot(GetDocument()), + WebURLRequest::kRequestContextScript, ScriptFetchOptions(), + GetModulator(), ModuleScriptCustomFetchType::kNone, registry, client); EXPECT_FALSE(client->WasNotifyFinished()) << "ModuleTreeLinker should always finish asynchronously."; @@ -324,10 +324,10 @@ KURL url("http://example.com/root.js"); TestModuleTreeClient* client = new TestModuleTreeClient; - ModuleTreeLinker::Fetch(url, FetchClientSettingsObjectSnapshot(GetDocument()), - WebURLRequest::kRequestContextScript, - ScriptFetchOptions(), GetModulator(), - ModuleScriptCustomFetchType::kNone, registry, client); + ModuleTreeLinker::Fetch( + url, new FetchClientSettingsObjectSnapshot(GetDocument()), + WebURLRequest::kRequestContextScript, ScriptFetchOptions(), + GetModulator(), ModuleScriptCustomFetchType::kNone, registry, client); EXPECT_FALSE(client->WasNotifyFinished()) << "ModuleTreeLinker should always finish asynchronously."; @@ -383,10 +383,10 @@ KURL url("http://example.com/depth1.js"); TestModuleTreeClient* client = new TestModuleTreeClient; - ModuleTreeLinker::Fetch(url, FetchClientSettingsObjectSnapshot(GetDocument()), - WebURLRequest::kRequestContextScript, - ScriptFetchOptions(), GetModulator(), - ModuleScriptCustomFetchType::kNone, registry, client); + ModuleTreeLinker::Fetch( + url, new FetchClientSettingsObjectSnapshot(GetDocument()), + WebURLRequest::kRequestContextScript, ScriptFetchOptions(), + GetModulator(), ModuleScriptCustomFetchType::kNone, registry, client); EXPECT_FALSE(client->WasNotifyFinished()) << "ModuleTreeLinker should always finish asynchronously."; @@ -409,10 +409,10 @@ KURL url("http://example.com/a.js"); TestModuleTreeClient* client = new TestModuleTreeClient; - ModuleTreeLinker::Fetch(url, FetchClientSettingsObjectSnapshot(GetDocument()), - WebURLRequest::kRequestContextScript, - ScriptFetchOptions(), GetModulator(), - ModuleScriptCustomFetchType::kNone, registry, client); + ModuleTreeLinker::Fetch( + url, new FetchClientSettingsObjectSnapshot(GetDocument()), + WebURLRequest::kRequestContextScript, ScriptFetchOptions(), + GetModulator(), ModuleScriptCustomFetchType::kNone, registry, client); EXPECT_FALSE(client->WasNotifyFinished()) << "ModuleTreeLinker should always finish asynchronously.";
diff --git a/third_party/blink/renderer/core/loader/resource/image_resource_content.cc b/third_party/blink/renderer/core/loader/resource/image_resource_content.cc index 809e48af..7308459 100644 --- a/third_party/blink/renderer/core/loader/resource/image_resource_content.cc +++ b/third_party/blink/renderer/core/loader/resource/image_resource_content.cc
@@ -240,19 +240,6 @@ return image_.get(); } -std::pair<blink::Image*, float> ImageResourceContent::BrokenCanvas( - float device_scale_factor) { - if (device_scale_factor >= 2) { - DEFINE_STATIC_REF(blink::Image, broken_canvas_hi_res, - (blink::Image::LoadPlatformResource("brokenCanvas@2x"))); - return std::make_pair(broken_canvas_hi_res, 2); - } - - DEFINE_STATIC_REF(blink::Image, broken_canvas_lo_res, - (blink::Image::LoadPlatformResource("brokenCanvas"))); - return std::make_pair(broken_canvas_lo_res, 1); -} - IntSize ImageResourceContent::IntrinsicSize( RespectImageOrientationEnum should_respect_image_orientation) { if (!image_)
diff --git a/third_party/blink/renderer/core/loader/resource/image_resource_content.h b/third_party/blink/renderer/core/loader/resource/image_resource_content.h index ab95656..5df45ba 100644 --- a/third_party/blink/renderer/core/loader/resource/image_resource_content.h +++ b/third_party/blink/renderer/core/loader/resource/image_resource_content.h
@@ -61,10 +61,6 @@ blink::Image* GetImage() const; bool HasImage() const { return image_.get(); } - // Returns an image and the image's resolution scale factor. - static std::pair<blink::Image*, float> BrokenCanvas( - float device_scale_factor); - // The device pixel ratio we got from the server for this image, or 1.0. float DevicePixelRatioHeaderValue() const; bool HasDevicePixelRatioHeaderValue() const;
diff --git a/third_party/blink/renderer/core/loader/worker_fetch_context.cc b/third_party/blink/renderer/core/loader/worker_fetch_context.cc index b7e4fff23..3f7a49ca 100644 --- a/third_party/blink/renderer/core/loader/worker_fetch_context.cc +++ b/third_party/blink/renderer/core/loader/worker_fetch_context.cc
@@ -96,6 +96,8 @@ web_context_(std::move(web_context)), loading_task_runner_( global_scope_->GetTaskRunner(TaskType::kInternalLoading)), + fetch_client_settings_object_( + new FetchClientSettingsObjectImpl(*global_scope_)), save_data_enabled_(GetNetworkStateNotifier().SaveDataEnabled()) { web_context_->InitializeOnWorkerThread(); std::unique_ptr<blink::WebDocumentSubresourceFilter> web_filter = @@ -105,6 +107,10 @@ SubresourceFilter::Create(global_scope, std::move(web_filter)); } } +const FetchClientSettingsObject* +WorkerFetchContext::GetFetchClientSettingsObject() const { + return fetch_client_settings_object_.Get(); +} KURL WorkerFetchContext::GetSiteForCookies() const { return web_context_->SiteForCookies(); @@ -199,14 +205,6 @@ return false; } -ReferrerPolicy WorkerFetchContext::GetReferrerPolicy() const { - return global_scope_->GetReferrerPolicy(); -} - -String WorkerFetchContext::GetOutgoingReferrer() const { - return global_scope_->OutgoingReferrer(); -} - const KURL& WorkerFetchContext::Url() const { return global_scope_->Url(); } @@ -235,7 +233,7 @@ } const SecurityOrigin* WorkerFetchContext::GetSecurityOrigin() const { - return global_scope_->GetSecurityOrigin(); + return GetFetchClientSettingsObject()->GetSecurityOrigin(); } std::unique_ptr<WebURLLoader> WorkerFetchContext::CreateURLLoader( @@ -412,6 +410,7 @@ visitor->Trace(global_scope_); visitor->Trace(subresource_filter_); visitor->Trace(resource_fetcher_); + visitor->Trace(fetch_client_settings_object_); BaseFetchContext::Trace(visitor); }
diff --git a/third_party/blink/renderer/core/loader/worker_fetch_context.h b/third_party/blink/renderer/core/loader/worker_fetch_context.h index 74da2bdc..00e973c 100644 --- a/third_party/blink/renderer/core/loader/worker_fetch_context.h +++ b/third_party/blink/renderer/core/loader/worker_fetch_context.h
@@ -11,6 +11,7 @@ #include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom-blink.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/loader/base_fetch_context.h" +#include "third_party/blink/renderer/core/script/fetch_client_settings_object_impl.h" #include "third_party/blink/renderer/platform/wtf/forward.h" namespace blink { @@ -35,6 +36,8 @@ ~WorkerFetchContext() override; // BaseFetchContext implementation: + const FetchClientSettingsObject* GetFetchClientSettingsObject() + const override; KURL GetSiteForCookies() const override; SubresourceFilter* GetSubresourceFilter() const override; bool AllowScriptFromSource(const KURL&) const override; @@ -59,8 +62,6 @@ bool ShouldBlockFetchAsCredentialedSubresource(const ResourceRequest&, const KURL&) const override; bool ShouldLoadNewResource(Resource::Type) const override { return true; } - ReferrerPolicy GetReferrerPolicy() const override; - String GetOutgoingReferrer() const override; const KURL& Url() const override; const SecurityOrigin* GetParentSecurityOrigin() const override; base::Optional<mojom::IPAddressSpace> GetAddressSpace() const override; @@ -137,6 +138,8 @@ Member<ResourceFetcher> resource_fetcher_; scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner_; + const Member<FetchClientSettingsObjectImpl> fetch_client_settings_object_; + // The value of |save_data_enabled_| is read once per frame from // NetworkStateNotifier, which is guarded by a mutex lock, and cached locally // here for performance.
diff --git a/third_party/blink/renderer/core/page/page.cc b/third_party/blink/renderer/core/page/page.cc index 46c75bff..b7fef98 100644 --- a/third_party/blink/renderer/core/page/page.cc +++ b/third_party/blink/renderer/core/page/page.cc
@@ -38,6 +38,7 @@ #include "third_party/blink/renderer/core/frame/dom_timer.h" #include "third_party/blink/renderer/core/frame/event_handler_registry.h" #include "third_party/blink/renderer/core/frame/frame_console.h" +#include "third_party/blink/renderer/core/frame/link_highlights.h" #include "third_party/blink/renderer/core/frame/local_frame_client.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" #include "third_party/blink/renderer/core/frame/page_scale_constraints.h" @@ -160,6 +161,7 @@ visual_viewport_(VisualViewport::Create(*this)), overscroll_controller_( OverscrollController::Create(GetVisualViewport(), GetChromeClient())), + link_highlights_(LinkHighlights::Create(*this)), main_frame_(nullptr), plugin_data_(nullptr), use_counter_(page_clients.chrome_client && @@ -264,6 +266,10 @@ return *overscroll_controller_; } +LinkHighlights& Page::GetLinkHighlights() { + return *link_highlights_; +} + DOMRectList* Page::NonFastScrollableRectsForTesting(const LocalFrame* frame) { // Update lifecycle to kPrePaintClean. This includes the compositing update // and ScrollingCoordinator::UpdateAfterPaint, which computes the non-fast @@ -725,6 +731,7 @@ visitor->Trace(global_root_scroller_controller_); visitor->Trace(visual_viewport_); visitor->Trace(overscroll_controller_); + visitor->Trace(link_highlights_); visitor->Trace(main_frame_); visitor->Trace(plugin_data_); visitor->Trace(validation_message_client_); @@ -740,12 +747,14 @@ LocalFrameView* view) { if (GetScrollingCoordinator()) GetScrollingCoordinator()->LayerTreeViewInitialized(layer_tree_view, view); + GetLinkHighlights().LayerTreeViewInitialized(layer_tree_view); } void Page::WillCloseLayerTreeView(WebLayerTreeView& layer_tree_view, LocalFrameView* view) { if (scrolling_coordinator_) scrolling_coordinator_->WillCloseLayerTreeView(layer_tree_view, view); + GetLinkHighlights().WillCloseLayerTreeView(layer_tree_view); } void Page::WillBeDestroyed() {
diff --git a/third_party/blink/renderer/core/page/page.h b/third_party/blink/renderer/core/page/page.h index 5adaf6d..06804a1 100644 --- a/third_party/blink/renderer/core/page/page.h +++ b/third_party/blink/renderer/core/page/page.h
@@ -60,6 +60,7 @@ class DragController; class FocusController; class Frame; +class LinkHighlights; class OverscrollController; struct PageScaleConstraints; class PageScaleConstraintsSet; @@ -218,6 +219,8 @@ VisualViewport& GetVisualViewport(); const VisualViewport& GetVisualViewport() const; + LinkHighlights& GetLinkHighlights(); + OverscrollController& GetOverscrollController(); const OverscrollController& GetOverscrollController() const; @@ -351,6 +354,7 @@ global_root_scroller_controller_; const Member<VisualViewport> visual_viewport_; const Member<OverscrollController> overscroll_controller_; + const Member<LinkHighlights> link_highlights_; // Typically, the main frame and Page should both be owned by the embedder, // which must call Page::willBeDestroyed() prior to destroying Page. This
diff --git a/third_party/blink/renderer/core/paint/link_highlight_impl.cc b/third_party/blink/renderer/core/paint/link_highlight_impl.cc index 620f511..c091189e 100644 --- a/third_party/blink/renderer/core/paint/link_highlight_impl.cc +++ b/third_party/blink/renderer/core/paint/link_highlight_impl.cc
@@ -38,10 +38,10 @@ #include "third_party/blink/public/web/blink.h" #include "third_party/blink/renderer/core/dom/layout_tree_builder_traversal.h" #include "third_party/blink/renderer/core/dom/node.h" -#include "third_party/blink/renderer/core/exported/web_settings_impl.h" #include "third_party/blink/renderer/core/exported/web_view_impl.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" #include "third_party/blink/renderer/core/frame/web_frame_widget_base.h" #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h" #include "third_party/blink/renderer/core/layout/layout_box_model_object.h" @@ -68,15 +68,12 @@ namespace blink { -std::unique_ptr<LinkHighlightImpl> LinkHighlightImpl::Create( - Node* node, - WebViewImpl* owning_web_view) { - return base::WrapUnique(new LinkHighlightImpl(node, owning_web_view)); +std::unique_ptr<LinkHighlightImpl> LinkHighlightImpl::Create(Node* node) { + return base::WrapUnique(new LinkHighlightImpl(node)); } -LinkHighlightImpl::LinkHighlightImpl(Node* node, WebViewImpl* owning_web_view) +LinkHighlightImpl::LinkHighlightImpl(Node* node) : node_(node), - owning_web_view_(owning_web_view), current_graphics_layer_(nullptr), is_scrolling_graphics_layer_(false), geometry_needs_update_(false), @@ -84,15 +81,12 @@ start_time_(CurrentTimeTicks()), unique_id_(NewUniqueObjectId()) { DCHECK(node_); - DCHECK(owning_web_view); content_layer_ = cc::PictureLayer::Create(this); content_layer_->SetTransformOrigin(FloatPoint3D()); compositor_animation_ = CompositorAnimation::Create(); DCHECK(compositor_animation_); compositor_animation_->SetAnimationDelegate(this); - if (owning_web_view_->LinkHighlightsTimeline()) - owning_web_view_->LinkHighlightsTimeline()->AnimationAttached(*this); CompositorElementId element_id = CompositorElementIdFromUniqueObjectId(unique_id_); @@ -106,8 +100,6 @@ LinkHighlightImpl::~LinkHighlightImpl() { if (compositor_animation_->IsElementAttached()) compositor_animation_->DetachElement(); - if (owning_web_view_->LinkHighlightsTimeline()) - owning_web_view_->LinkHighlightsTimeline()->AnimationDestroyed(*this); compositor_animation_->SetAnimationDelegate(nullptr); compositor_animation_.reset(); @@ -228,7 +220,9 @@ // links: these should ideally be merged into a single rect before creating // the path, but that's another CL. if (quads.size() == 1 && transformed_quad.IsRectilinear() && - !owning_web_view_->SettingsImpl()->MockGestureTapHighlightsEnabled()) { + !node_->GetDocument() + .GetSettings() + ->GetMockGestureTapHighlightsEnabled()) { FloatSize rect_rounding_radii(3, 3); new_path.AddRoundedRect(transformed_quad.BoundingBox(), rect_rounding_radii); @@ -326,7 +320,6 @@ compositor_animation_->AddKeyframeModel(std::move(keyframe_model)); Invalidate(); - owning_web_view_->MainFrameImpl()->FrameWidgetImpl()->ScheduleAnimation(); } void LinkHighlightImpl::ClearGraphicsLayerLinkHighlightPointer() {
diff --git a/third_party/blink/renderer/core/paint/link_highlight_impl.h b/third_party/blink/renderer/core/paint/link_highlight_impl.h index 9c4a76d8f..2158cf7 100644 --- a/third_party/blink/renderer/core/paint/link_highlight_impl.h +++ b/third_party/blink/renderer/core/paint/link_highlight_impl.h
@@ -50,14 +50,13 @@ class GraphicsLayer; class LayoutBoxModelObject; class Node; -class WebViewImpl; class CORE_EXPORT LinkHighlightImpl final : public LinkHighlight, public cc::ContentLayerClient, public CompositorAnimationDelegate, public CompositorAnimationClient { public: - static std::unique_ptr<LinkHighlightImpl> Create(Node*, WebViewImpl*); + static std::unique_ptr<LinkHighlightImpl> Create(Node*); ~LinkHighlightImpl() override; void StartHighlightAnimationIfNeeded(); @@ -88,7 +87,7 @@ } private: - LinkHighlightImpl(Node*, WebViewImpl*); + LinkHighlightImpl(Node*); void ReleaseResources(); void ComputeQuads(const Node&, Vector<FloatQuad>&) const; @@ -104,7 +103,6 @@ Path path_; Persistent<Node> node_; - WebViewImpl* owning_web_view_; GraphicsLayer* current_graphics_layer_; bool is_scrolling_graphics_layer_; std::unique_ptr<CompositorAnimation> compositor_animation_;
diff --git a/third_party/blink/renderer/core/paint/link_highlight_impl_test.cc b/third_party/blink/renderer/core/paint/link_highlight_impl_test.cc index b24337a..f6af6f9 100644 --- a/third_party/blink/renderer/core/paint/link_highlight_impl_test.cc +++ b/third_party/blink/renderer/core/paint/link_highlight_impl_test.cc
@@ -40,6 +40,7 @@ #include "third_party/blink/renderer/core/events/web_input_event_conversion.h" #include "third_party/blink/renderer/core/exported/web_view_impl.h" #include "third_party/blink/renderer/core/frame/frame_test_helpers.h" +#include "third_party/blink/renderer/core/frame/link_highlights.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h" #include "third_party/blink/renderer/core/input/event_handler.h" @@ -104,26 +105,28 @@ web_view_impl->EnableTapHighlightAtPoint( GetTargetedEvent(web_view_impl, touch_event)); - EXPECT_TRUE(web_view_impl->GetLinkHighlight(0)); - EXPECT_TRUE(web_view_impl->GetLinkHighlight(0)->Layer()); + const auto& highlights = + web_view_impl->GetPage()->GetLinkHighlights().link_highlights_; + EXPECT_TRUE(highlights.at(0)); + EXPECT_TRUE(highlights.at(0)->Layer()); // Find a target inside a scrollable div touch_event.SetPositionInWidget(WebFloatPoint(20, 100)); web_view_impl->EnableTapHighlightAtPoint( GetTargetedEvent(web_view_impl, touch_event)); - ASSERT_TRUE(web_view_impl->GetLinkHighlight(0)); + ASSERT_TRUE(highlights.at(0)); // Don't highlight if no "hand cursor" touch_event.SetPositionInWidget( WebFloatPoint(20, 220)); // An A-link with cross-hair cursor. web_view_impl->EnableTapHighlightAtPoint( GetTargetedEvent(web_view_impl, touch_event)); - ASSERT_EQ(0U, web_view_impl->NumLinkHighlights()); + ASSERT_EQ(0U, highlights.size()); touch_event.SetPositionInWidget(WebFloatPoint(20, 260)); // A text input box. web_view_impl->EnableTapHighlightAtPoint( GetTargetedEvent(web_view_impl, touch_event)); - ASSERT_EQ(0U, web_view_impl->NumLinkHighlights()); + ASSERT_EQ(0U, highlights.size()); Platform::Current() ->GetURLLoaderMockFactory() @@ -152,16 +155,17 @@ ASSERT_TRUE(touch_node); web_view_impl->EnableTapHighlightAtPoint(targeted_event); - ASSERT_TRUE(web_view_impl->GetLinkHighlight(0)); + const auto& highlights = web_view_impl->GetPage()->GetLinkHighlights(); + ASSERT_TRUE(highlights.link_highlights_.at(0)); GraphicsLayer* highlight_layer = - web_view_impl->GetLinkHighlight(0)->CurrentGraphicsLayerForTesting(); + highlights.link_highlights_.at(0)->CurrentGraphicsLayerForTesting(); ASSERT_TRUE(highlight_layer); EXPECT_TRUE(highlight_layer->GetLinkHighlight(0)); touch_node->remove(IGNORE_EXCEPTION_FOR_TESTING); web_view_impl->UpdateAllLifecyclePhases(); - ASSERT_EQ(0U, highlight_layer->NumLinkHighlights()); + EXPECT_EQ(0U, highlight_layer->NumLinkHighlights()); Platform::Current() ->GetURLLoaderMockFactory() @@ -191,10 +195,12 @@ ASSERT_TRUE(touch_node); web_view_impl->EnableTapHighlightAtPoint(targeted_event); - ASSERT_TRUE(web_view_impl->GetLinkHighlight(0)); + const auto& highlights = + web_view_impl->GetPage()->GetLinkHighlights().link_highlights_; + ASSERT_TRUE(highlights.at(0)); GraphicsLayer* highlight_layer = - web_view_impl->GetLinkHighlight(0)->CurrentGraphicsLayerForTesting(); + highlights.at(0)->CurrentGraphicsLayerForTesting(); ASSERT_TRUE(highlight_layer); EXPECT_TRUE(highlight_layer->GetLinkHighlight(0)); @@ -228,7 +234,9 @@ good_targets, highlight_nodes); web_view_impl->EnableTapHighlights(highlight_nodes); - EXPECT_EQ(2U, web_view_impl->NumLinkHighlights()); + const auto& highlights = + web_view_impl->GetPage()->GetLinkHighlights().link_highlights_; + EXPECT_EQ(2U, highlights.size()); Platform::Current() ->GetURLLoaderMockFactory()
diff --git a/third_party/blink/renderer/core/paint/paint_invalidator.cc b/third_party/blink/renderer/core/paint/paint_invalidator.cc index 797cbee..5ac372b 100644 --- a/third_party/blink/renderer/core/paint/paint_invalidator.cc +++ b/third_party/blink/renderer/core/paint/paint_invalidator.cc
@@ -360,7 +360,12 @@ LayoutRect selection_visual_rect = MapFragmentLocalRectToVisualRect( local_selection_rect, object, *fragment, context); - if (selection_visual_rect != fragment->SelectionVisualRect()) { + const bool should_invalidate = + object.ShouldInvalidateSelection() || + selection_visual_rect != fragment->SelectionVisualRect(); + const bool rect_exists = !selection_visual_rect.IsEmpty() || + !fragment->SelectionVisualRect().IsEmpty(); + if (should_invalidate && rect_exists) { context.painting_layer->SetNeedsRepaint(); ObjectPaintInvalidator(object).InvalidateDisplayItemClient( *fragment, PaintInvalidationReason::kSelection);
diff --git a/third_party/blink/renderer/core/script/BUILD.gn b/third_party/blink/renderer/core/script/BUILD.gn index 27f09a6..cd40d44 100644 --- a/third_party/blink/renderer/core/script/BUILD.gn +++ b/third_party/blink/renderer/core/script/BUILD.gn
@@ -18,6 +18,9 @@ "document_write_intervention.h", "dynamic_module_resolver.cc", "dynamic_module_resolver.h", + "fetch_client_settings_object.h", + "fetch_client_settings_object_impl.cc", + "fetch_client_settings_object_impl.h", "fetch_client_settings_object_snapshot.cc", "fetch_client_settings_object_snapshot.h", "html_parser_script_runner.cc",
diff --git a/third_party/blink/renderer/core/script/dynamic_module_resolver.cc b/third_party/blink/renderer/core/script/dynamic_module_resolver.cc index 22cf6d7..6a1f828 100644 --- a/third_party/blink/renderer/core/script/dynamic_module_resolver.cc +++ b/third_party/blink/renderer/core/script/dynamic_module_resolver.cc
@@ -219,10 +219,10 @@ // highly discouraged since it breaks layering. Rewrite this. auto* execution_context = ExecutionContext::From(modulator_->GetScriptState()); - FetchClientSettingsObjectSnapshot settings_object(*execution_context); - modulator_->FetchTree(url, settings_object, - WebURLRequest::kRequestContextScript, options, - ModuleScriptCustomFetchType::kNone, tree_client); + modulator_->FetchTree( + url, new FetchClientSettingsObjectSnapshot(*execution_context), + WebURLRequest::kRequestContextScript, options, + ModuleScriptCustomFetchType::kNone, tree_client); // Steps 2.[5-8] are implemented at // DynamicImportTreeClient::NotifyModuleLoadFinished.
diff --git a/third_party/blink/renderer/core/script/dynamic_module_resolver_test.cc b/third_party/blink/renderer/core/script/dynamic_module_resolver_test.cc index 5189ba06..5d19748 100644 --- a/third_party/blink/renderer/core/script/dynamic_module_resolver_test.cc +++ b/third_party/blink/renderer/core/script/dynamic_module_resolver_test.cc
@@ -70,7 +70,7 @@ } void FetchTree(const KURL& url, - const FetchClientSettingsObjectSnapshot&, + FetchClientSettingsObjectSnapshot*, WebURLRequest::RequestContext, const ScriptFetchOptions&, ModuleScriptCustomFetchType custom_fetch_type,
diff --git a/third_party/blink/renderer/core/script/fetch_client_settings_object.h b/third_party/blink/renderer/core/script/fetch_client_settings_object.h new file mode 100644 index 0000000..7bd4406 --- /dev/null +++ b/third_party/blink/renderer/core/script/fetch_client_settings_object.h
@@ -0,0 +1,55 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_FETCH_CLIENT_SETTINGS_OBJECT_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_FETCH_CLIENT_SETTINGS_OBJECT_H_ + +#include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/platform/cross_thread_copier.h" +#include "third_party/blink/renderer/platform/heap/garbage_collected.h" +#include "third_party/blink/renderer/platform/heap/heap.h" +#include "third_party/blink/renderer/platform/weborigin/kurl.h" +#include "third_party/blink/renderer/platform/weborigin/referrer_policy.h" +#include "third_party/blink/renderer/platform/weborigin/security_origin.h" + +namespace blink { + +// This is a partial interface of the "settings object" concept defined in the +// HTML spec: +// https://html.spec.whatwg.org/multipage/webappapis.html#settings-object +// +// This is also a partial interface of the "fetch client settings object" used +// in module script fetch. Other part of the "fetch client settings object" is +// currently implemented by ResourceFetcher and FetchContext, and this class is +// used together with them. +// https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-module-worker-script-tree +class CORE_EXPORT FetchClientSettingsObject + : public GarbageCollectedFinalized<FetchClientSettingsObject> { + public: + virtual ~FetchClientSettingsObject() = default; + + // "A URL used by APIs called by scripts that use this environment settings + // object to parse URLs." + // https://html.spec.whatwg.org/multipage/webappapis.html#api-base-url + virtual const KURL& BaseURL() const = 0; + + // "An origin used in security checks." + // https://html.spec.whatwg.org/multipage/webappapis.html#concept-settings-object-origin + virtual const SecurityOrigin* GetSecurityOrigin() const = 0; + + // "The default referrer policy for fetches performed using this environment + // settings object as a request client." + // https://html.spec.whatwg.org/multipage/webappapis.html#concept-settings-object-referrer-policy + virtual ReferrerPolicy GetReferrerPolicy() const = 0; + + // "referrerURL" used in the "Determine request's Referrer" algorithm: + // https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer + virtual const String GetOutgoingReferrer() const = 0; + + virtual void Trace(Visitor*) {} +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_FETCH_CLIENT_SETTINGS_OBJECT_H_
diff --git a/third_party/blink/renderer/core/script/fetch_client_settings_object_impl.cc b/third_party/blink/renderer/core/script/fetch_client_settings_object_impl.cc new file mode 100644 index 0000000..36257cd0 --- /dev/null +++ b/third_party/blink/renderer/core/script/fetch_client_settings_object_impl.cc
@@ -0,0 +1,42 @@ +// 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 "third_party/blink/renderer/core/script/fetch_client_settings_object_impl.h" + +#include "third_party/blink/renderer/core/execution_context/execution_context.h" + +namespace blink { + +FetchClientSettingsObjectImpl::FetchClientSettingsObjectImpl( + ExecutionContext& execution_context) + : execution_context_(execution_context) { + DCHECK(execution_context_->IsContextThread()); +} + +const KURL& FetchClientSettingsObjectImpl::BaseURL() const { + DCHECK(execution_context_->IsContextThread()); + return execution_context_->BaseURL(); +} + +const SecurityOrigin* FetchClientSettingsObjectImpl::GetSecurityOrigin() const { + DCHECK(execution_context_->IsContextThread()); + return execution_context_->GetSecurityOrigin(); +} + +ReferrerPolicy FetchClientSettingsObjectImpl::GetReferrerPolicy() const { + DCHECK(execution_context_->IsContextThread()); + return execution_context_->GetReferrerPolicy(); +} + +const String FetchClientSettingsObjectImpl::GetOutgoingReferrer() const { + DCHECK(execution_context_->IsContextThread()); + return execution_context_->OutgoingReferrer(); +} + +void FetchClientSettingsObjectImpl::Trace(Visitor* visitor) { + visitor->Trace(execution_context_); + FetchClientSettingsObject::Trace(visitor); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/script/fetch_client_settings_object_impl.h b/third_party/blink/renderer/core/script/fetch_client_settings_object_impl.h new file mode 100644 index 0000000..7f1e29c --- /dev/null +++ b/third_party/blink/renderer/core/script/fetch_client_settings_object_impl.h
@@ -0,0 +1,46 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_FETCH_CLIENT_SETTINGS_OBJECT_IMPL_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_FETCH_CLIENT_SETTINGS_OBJECT_IMPL_H_ + +#include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/core/script/fetch_client_settings_object.h" +#include "third_party/blink/renderer/platform/cross_thread_copier.h" +#include "third_party/blink/renderer/platform/heap/member.h" +#include "third_party/blink/renderer/platform/weborigin/kurl.h" +#include "third_party/blink/renderer/platform/weborigin/referrer_policy.h" +#include "third_party/blink/renderer/platform/weborigin/security_origin.h" + +namespace blink { + +class ExecutionContext; + +// This is an implementation of FetchClientSettingsObject. As opposed to +// FetchClientSettingsObjectSnapshot, this refers to up-to-date values of the +// settings object. +// +// This class should be used for resource loading other than main worker +// (worklet) scripts. For the main scripts, FetchClientSettingsObjectSnapshot +// should be used. See the class level comments on that class. +class CORE_EXPORT FetchClientSettingsObjectImpl final + : public FetchClientSettingsObject { + public: + explicit FetchClientSettingsObjectImpl(ExecutionContext&); + ~FetchClientSettingsObjectImpl() override = default; + + const KURL& BaseURL() const override; + const SecurityOrigin* GetSecurityOrigin() const override; + ReferrerPolicy GetReferrerPolicy() const override; + const String GetOutgoingReferrer() const override; + + void Trace(Visitor* visitor) override; + + private: + Member<ExecutionContext> execution_context_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_FETCH_CLIENT_SETTINGS_OBJECT_IMPL_H_
diff --git a/third_party/blink/renderer/core/script/fetch_client_settings_object_snapshot.cc b/third_party/blink/renderer/core/script/fetch_client_settings_object_snapshot.cc index f5c2dc0..707dde6 100644 --- a/third_party/blink/renderer/core/script/fetch_client_settings_object_snapshot.cc +++ b/third_party/blink/renderer/core/script/fetch_client_settings_object_snapshot.cc
@@ -16,6 +16,13 @@ execution_context.OutgoingReferrer()) {} FetchClientSettingsObjectSnapshot::FetchClientSettingsObjectSnapshot( + std::unique_ptr<CrossThreadFetchClientSettingsObjectData> data) + : FetchClientSettingsObjectSnapshot(data->base_url, + data->security_origin, + data->referrer_policy, + data->outgoing_referrer) {} + +FetchClientSettingsObjectSnapshot::FetchClientSettingsObjectSnapshot( const KURL& base_url, const scoped_refptr<const SecurityOrigin> security_origin, ReferrerPolicy referrer_policy,
diff --git a/third_party/blink/renderer/core/script/fetch_client_settings_object_snapshot.h b/third_party/blink/renderer/core/script/fetch_client_settings_object_snapshot.h index 0bd8bd4..a38cfd7 100644 --- a/third_party/blink/renderer/core/script/fetch_client_settings_object_snapshot.h +++ b/third_party/blink/renderer/core/script/fetch_client_settings_object_snapshot.h
@@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_FETCH_CLIENT_SETTINGS_OBJECT_SNAPSHOT_H_ #include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/core/script/fetch_client_settings_object.h" #include "third_party/blink/renderer/platform/cross_thread_copier.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" #include "third_party/blink/renderer/platform/weborigin/referrer_policy.h" @@ -15,57 +16,71 @@ class ExecutionContext; -// This is a partial implementation of the "settings object" concept defined in -// the HTML spec: -// https://html.spec.whatwg.org/multipage/webappapis.html#settings-object -// -// This is also a partial implementation of the "fetch client settings object" -// used in module script fetch. Actually, it's used with ResourceFetcher and -// FetchContext to compensate "fetch client settings object" that are not -// included in this class. -// https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-module-worker-script-tree -// +// This class is needed to copy a FetchClientSettingsObjectSnapshot across +// threads, because it has some members which cannot be transferred across +// threads (AtomicString for example). +// There are some rules / restrictions: +// - This struct cannot contain an object that cannot be transferred across +// threads (e.g., AtomicString) +// - Non-simple members need explicit copying (e.g., String::IsolatedCopy, +// KURL::Copy) rather than the copy constructor or the assignment operator. +struct CrossThreadFetchClientSettingsObjectData { + WTF_MAKE_NONCOPYABLE(CrossThreadFetchClientSettingsObjectData); + USING_FAST_MALLOC(CrossThreadFetchClientSettingsObjectData); + + public: + CrossThreadFetchClientSettingsObjectData( + KURL base_url, + scoped_refptr<const SecurityOrigin> security_origin, + ReferrerPolicy referrer_policy, + String outgoing_referrer) + : base_url(std::move(base_url)), + security_origin(std::move(security_origin)), + referrer_policy(referrer_policy), + outgoing_referrer(std::move(outgoing_referrer)) {} + + KURL base_url; + scoped_refptr<const SecurityOrigin> security_origin; + ReferrerPolicy referrer_policy; + String outgoing_referrer; +}; + // This takes a partial snapshot of the execution context's states so that an // instance of this class can be passed to another thread without cross-thread // synchronization. Don't keep this object persistently, instead create a new // instance per each "fetch a module script graph" algorithm: // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-module-script-tree // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-module-worker-script-tree -class CORE_EXPORT FetchClientSettingsObjectSnapshot final { +// +// This class should be used only for main worker (worklet) script loading. For +// other resources, FetchClientSettingsObjectImpl should be used. See the class +// level comments on that class. +class CORE_EXPORT FetchClientSettingsObjectSnapshot final + : public FetchClientSettingsObject { public: explicit FetchClientSettingsObjectSnapshot(ExecutionContext&); + explicit FetchClientSettingsObjectSnapshot( + std::unique_ptr<CrossThreadFetchClientSettingsObjectData>); FetchClientSettingsObjectSnapshot( const KURL& base_url, const scoped_refptr<const SecurityOrigin> security_origin, ReferrerPolicy referrer_policy, const String& outgoing_referrer); - virtual ~FetchClientSettingsObjectSnapshot() = default; + ~FetchClientSettingsObjectSnapshot() override = default; - // "A URL used by APIs called by scripts that use this environment settings - // object to parse URLs." - // https://html.spec.whatwg.org/multipage/webappapis.html#api-base-url - const KURL& BaseURL() const { return base_url_; } - - // "An origin used in security checks." - // https://html.spec.whatwg.org/multipage/webappapis.html#concept-settings-object-origin - const SecurityOrigin* GetSecurityOrigin() const { + const KURL& BaseURL() const override { return base_url_; } + const SecurityOrigin* GetSecurityOrigin() const override { return security_origin_.get(); } + ReferrerPolicy GetReferrerPolicy() const override { return referrer_policy_; } + const String GetOutgoingReferrer() const override { + return outgoing_referrer_; + } - // "The default referrer policy for fetches performed using this environment - // settings object as a request client." - // https://html.spec.whatwg.org/multipage/webappapis.html#concept-settings-object-referrer-policy - ReferrerPolicy GetReferrerPolicy() const { return referrer_policy_; } - - // "referrerURL" used in the "Determine request's Referrer" algorithm: - // https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer - const String& GetOutgoingReferrer() const { return outgoing_referrer_; } - - // Makes an copy of this instance. This is typically used for cross-thread - // communication in CrossThreadCopier. - FetchClientSettingsObjectSnapshot IsolatedCopy() const { - return FetchClientSettingsObjectSnapshot( + // Gets a copy of the data suitable for passing to another thread. + std::unique_ptr<CrossThreadFetchClientSettingsObjectData> CopyData() const { + return std::make_unique<CrossThreadFetchClientSettingsObjectData>( base_url_.Copy(), security_origin_->IsolatedCopy(), referrer_policy_, outgoing_referrer_.IsolatedCopy()); } @@ -77,14 +92,6 @@ const String outgoing_referrer_; }; -template <> -struct CrossThreadCopier<FetchClientSettingsObjectSnapshot> { - static FetchClientSettingsObjectSnapshot Copy( - const FetchClientSettingsObjectSnapshot& settings_object) { - return settings_object.IsolatedCopy(); - } -}; - } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_FETCH_CLIENT_SETTINGS_OBJECT_SNAPSHOT_H_
diff --git a/third_party/blink/renderer/core/script/modulator.h b/third_party/blink/renderer/core/script/modulator.h index c372657..49589e5 100644 --- a/third_party/blink/renderer/core/script/modulator.h +++ b/third_party/blink/renderer/core/script/modulator.h
@@ -117,7 +117,7 @@ // module worker script graph" algorithm. virtual void FetchTree( const KURL&, - const FetchClientSettingsObjectSnapshot& fetch_client_settings_object, + FetchClientSettingsObjectSnapshot* fetch_client_settings_object, WebURLRequest::RequestContext destination, const ScriptFetchOptions&, ModuleScriptCustomFetchType, @@ -129,14 +129,14 @@ // Note that |this| is the "module map settings object". virtual void FetchSingle( const ModuleScriptFetchRequest&, - const FetchClientSettingsObjectSnapshot& fetch_client_settings_object, + FetchClientSettingsObjectSnapshot* fetch_client_settings_object, ModuleGraphLevel, ModuleScriptCustomFetchType, SingleModuleClient*) = 0; virtual void FetchDescendantsForInlineScript( ModuleScript*, - const FetchClientSettingsObjectSnapshot& fetch_client_settings_object, + FetchClientSettingsObjectSnapshot* fetch_client_settings_object, WebURLRequest::RequestContext destination, ModuleTreeClient*) = 0;
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 adb71378..233270a 100644 --- a/third_party/blink/renderer/core/script/modulator_impl_base.cc +++ b/third_party/blink/renderer/core/script/modulator_impl_base.cc
@@ -50,7 +50,7 @@ // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-module-worker-script-tree void ModulatorImplBase::FetchTree( const KURL& url, - const FetchClientSettingsObjectSnapshot& fetch_client_settings_object, + FetchClientSettingsObjectSnapshot* fetch_client_settings_object, WebURLRequest::RequestContext destination, const ScriptFetchOptions& options, ModuleScriptCustomFetchType custom_fetch_type, @@ -85,7 +85,7 @@ void ModulatorImplBase::FetchDescendantsForInlineScript( ModuleScript* module_script, - const FetchClientSettingsObjectSnapshot& fetch_client_settings_object, + FetchClientSettingsObjectSnapshot* fetch_client_settings_object, WebURLRequest::RequestContext destination, ModuleTreeClient* client) { ModuleTreeLinker::FetchDescendantsForInlineScript( @@ -95,7 +95,7 @@ void ModulatorImplBase::FetchSingle( const ModuleScriptFetchRequest& request, - const FetchClientSettingsObjectSnapshot& fetch_client_settings_object, + FetchClientSettingsObjectSnapshot* fetch_client_settings_object, ModuleGraphLevel level, ModuleScriptCustomFetchType custom_fetch_type, SingleModuleClient* client) {
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 3fd91666..9e46d9b 100644 --- a/third_party/blink/renderer/core/script/modulator_impl_base.h +++ b/third_party/blink/renderer/core/script/modulator_impl_base.h
@@ -51,19 +51,19 @@ void FetchTree( const KURL&, - const FetchClientSettingsObjectSnapshot& fetch_client_settings_object, + FetchClientSettingsObjectSnapshot* fetch_client_settings_object, WebURLRequest::RequestContext destination, const ScriptFetchOptions&, ModuleScriptCustomFetchType, ModuleTreeClient*) override; void FetchDescendantsForInlineScript( ModuleScript*, - const FetchClientSettingsObjectSnapshot& fetch_client_settings_object, + FetchClientSettingsObjectSnapshot* fetch_client_settings_object, WebURLRequest::RequestContext destination, ModuleTreeClient*) override; void FetchSingle( const ModuleScriptFetchRequest&, - const FetchClientSettingsObjectSnapshot& fetch_client_settings_object, + FetchClientSettingsObjectSnapshot* fetch_client_settings_object, ModuleGraphLevel, ModuleScriptCustomFetchType, SingleModuleClient*) override;
diff --git a/third_party/blink/renderer/core/script/module_map.cc b/third_party/blink/renderer/core/script/module_map.cc index fef4e66..a19f067 100644 --- a/third_party/blink/renderer/core/script/module_map.cc +++ b/third_party/blink/renderer/core/script/module_map.cc
@@ -110,7 +110,7 @@ // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-single-module-script void ModuleMap::FetchSingleModuleScript( const ModuleScriptFetchRequest& request, - const FetchClientSettingsObjectSnapshot& fetch_client_settings_object, + FetchClientSettingsObjectSnapshot* fetch_client_settings_object, ModuleGraphLevel level, ModuleScriptCustomFetchType custom_fetch_type, SingleModuleClient* client) {
diff --git a/third_party/blink/renderer/core/script/module_map.h b/third_party/blink/renderer/core/script/module_map.h index bb7895c..5efb043 100644 --- a/third_party/blink/renderer/core/script/module_map.h +++ b/third_party/blink/renderer/core/script/module_map.h
@@ -41,7 +41,7 @@ // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-single-module-script void FetchSingleModuleScript( const ModuleScriptFetchRequest&, - const FetchClientSettingsObjectSnapshot& fetch_client_settings_object, + FetchClientSettingsObjectSnapshot* fetch_client_settings_object, ModuleGraphLevel, ModuleScriptCustomFetchType, SingleModuleClient*);
diff --git a/third_party/blink/renderer/core/script/module_map_test.cc b/third_party/blink/renderer/core/script/module_map_test.cc index 1a6729df..20bcac6a 100644 --- a/third_party/blink/renderer/core/script/module_map_test.cc +++ b/third_party/blink/renderer/core/script/module_map_test.cc
@@ -208,7 +208,7 @@ platform->AdvanceClockSeconds(1.); // For non-zero DocumentParserTimings KURL url(NullURL(), "https://example.com/foo.js"); - FetchClientSettingsObjectSnapshot settings_object(GetDocument()); + auto* settings_object = new FetchClientSettingsObjectSnapshot(GetDocument()); // First request TestSingleModuleClient* client = new TestSingleModuleClient; @@ -254,7 +254,7 @@ platform->AdvanceClockSeconds(1.); // For non-zero DocumentParserTimings KURL url(NullURL(), "https://example.com/foo.js"); - FetchClientSettingsObjectSnapshot settings_object(GetDocument()); + auto* settings_object = new FetchClientSettingsObjectSnapshot(GetDocument()); // First request TestSingleModuleClient* client = new TestSingleModuleClient;
diff --git a/third_party/blink/renderer/core/script/script_loader.cc b/third_party/blink/renderer/core/script/script_loader.cc index a036112..ecac44f 100644 --- a/third_party/blink/renderer/core/script/script_loader.cc +++ b/third_party/blink/renderer/core/script/script_loader.cc
@@ -374,7 +374,8 @@ // object's environment settings object.</spec> // // Note: We use |element_document| as "settings object" in the steps below. - FetchClientSettingsObjectSnapshot settings_object(element_document); + auto* settings_object = + new FetchClientSettingsObjectSnapshot(element_document); // <spec step="24">If the element has a src content attribute, then:</spec> if (element_->HasSourceAttribute()) { @@ -708,7 +709,7 @@ void ScriptLoader::FetchModuleScriptTree( const KURL& url, - const FetchClientSettingsObjectSnapshot& settings_object, + FetchClientSettingsObjectSnapshot* settings_object, Modulator* modulator, const ScriptFetchOptions& options) { // <spec
diff --git a/third_party/blink/renderer/core/script/script_loader.h b/third_party/blink/renderer/core/script/script_loader.h index ae1a413..8d37f20 100644 --- a/third_party/blink/renderer/core/script/script_loader.h +++ b/third_party/blink/renderer/core/script/script_loader.h
@@ -129,7 +129,7 @@ const WTF::TextEncoding&); // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-module-script-tree void FetchModuleScriptTree(const KURL&, - const FetchClientSettingsObjectSnapshot&, + FetchClientSettingsObjectSnapshot*, Modulator*, const ScriptFetchOptions&);
diff --git a/third_party/blink/renderer/core/testing/dummy_modulator.cc b/third_party/blink/renderer/core/testing/dummy_modulator.cc index 70ac36a..193a998 100644 --- a/third_party/blink/renderer/core/testing/dummy_modulator.cc +++ b/third_party/blink/renderer/core/testing/dummy_modulator.cc
@@ -63,7 +63,7 @@ }; void DummyModulator::FetchTree(const KURL&, - const FetchClientSettingsObjectSnapshot&, + FetchClientSettingsObjectSnapshot*, WebURLRequest::RequestContext, const ScriptFetchOptions&, ModuleScriptCustomFetchType, @@ -72,7 +72,7 @@ } void DummyModulator::FetchSingle(const ModuleScriptFetchRequest&, - const FetchClientSettingsObjectSnapshot&, + FetchClientSettingsObjectSnapshot*, ModuleGraphLevel, ModuleScriptCustomFetchType, SingleModuleClient*) { @@ -81,7 +81,7 @@ void DummyModulator::FetchDescendantsForInlineScript( ModuleScript*, - const FetchClientSettingsObjectSnapshot& fetch_client_settings_object, + FetchClientSettingsObjectSnapshot* fetch_client_settings_object, WebURLRequest::RequestContext, ModuleTreeClient*) { NOTREACHED();
diff --git a/third_party/blink/renderer/core/testing/dummy_modulator.h b/third_party/blink/renderer/core/testing/dummy_modulator.h index df88282c..300f7cb 100644 --- a/third_party/blink/renderer/core/testing/dummy_modulator.h +++ b/third_party/blink/renderer/core/testing/dummy_modulator.h
@@ -36,20 +36,20 @@ void FetchTree( const KURL&, - const FetchClientSettingsObjectSnapshot& fetch_client_settings_object, + FetchClientSettingsObjectSnapshot* fetch_client_settings_object, WebURLRequest::RequestContext destination, const ScriptFetchOptions&, ModuleScriptCustomFetchType, ModuleTreeClient*) override; void FetchSingle( const ModuleScriptFetchRequest&, - const FetchClientSettingsObjectSnapshot& fetch_client_settings_object, + FetchClientSettingsObjectSnapshot* fetch_client_settings_object, ModuleGraphLevel, ModuleScriptCustomFetchType, SingleModuleClient*) override; void FetchDescendantsForInlineScript( ModuleScript*, - const FetchClientSettingsObjectSnapshot& fetch_client_settings_object, + FetchClientSettingsObjectSnapshot* fetch_client_settings_object, WebURLRequest::RequestContext destination, ModuleTreeClient*) override; ModuleScript* GetFetchedModuleScript(const KURL&) override;
diff --git a/third_party/blink/renderer/core/testing/sim/sim_compositor.h b/third_party/blink/renderer/core/testing/sim/sim_compositor.h index c561c7cd..74331ce8 100644 --- a/third_party/blink/renderer/core/testing/sim/sim_compositor.h +++ b/third_party/blink/renderer/core/testing/sim/sim_compositor.h
@@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_TESTING_SIM_SIM_COMPOSITOR_H_ #include "base/time/time.h" +#include "cc/trees/layer_tree_host.h" #include "content/renderer/gpu/render_widget_compositor.h" #include "content/test/stub_render_widget_compositor_delegate.h" #include "third_party/blink/renderer/core/frame/frame_test_helpers.h"
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker.cc b/third_party/blink/renderer/core/workers/dedicated_worker.cc index fd38f77..512ee7f 100644 --- a/third_party/blink/renderer/core/workers/dedicated_worker.cc +++ b/third_party/blink/renderer/core/workers/dedicated_worker.cc
@@ -161,8 +161,8 @@ // Specify empty source code here because module scripts will be fetched on // the worker thread as opposed to classic scripts that are fetched on the // main thread. - FetchClientSettingsObjectSnapshot outside_settings_object( - *GetExecutionContext()); + auto* outside_settings_object = + new FetchClientSettingsObjectSnapshot(*GetExecutionContext()); context_proxy_->StartWorkerGlobalScope( CreateGlobalScopeCreationParams(), options_, script_url_, outside_settings_object, stack_id, String() /* source_code */); @@ -257,8 +257,8 @@ std::unique_ptr<GlobalScopeCreationParams> creation_params = CreateGlobalScopeCreationParams(); creation_params->referrer_policy = referrer_policy; - FetchClientSettingsObjectSnapshot outside_settings_object( - *GetExecutionContext()); + auto* outside_settings_object = + new FetchClientSettingsObjectSnapshot(*GetExecutionContext()); context_proxy_->StartWorkerGlobalScope( std::move(creation_params), options_, script_url_, outside_settings_object, stack_id,
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.cc b/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.cc index dfe7e98..58166d3 100644 --- a/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.cc +++ b/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.cc
@@ -64,7 +64,7 @@ // https://html.spec.whatwg.org/multipage/workers.html#worker-processing-model void DedicatedWorkerGlobalScope::ImportModuleScript( const KURL& module_url_record, - const FetchClientSettingsObjectSnapshot& outside_settings_object, + FetchClientSettingsObjectSnapshot* outside_settings_object, network::mojom::FetchCredentialsMode credentials_mode) { // Step 12: "Let destination be "sharedworker" if is shared is true, and // "worker" otherwise."
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h b/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h index 39aa110..6455651 100644 --- a/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h +++ b/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.h
@@ -61,7 +61,7 @@ // WorkerGlobalScope void ImportModuleScript( const KURL& module_url_record, - const FetchClientSettingsObjectSnapshot& outside_settings_object, + FetchClientSettingsObjectSnapshot* outside_settings_object, network::mojom::FetchCredentialsMode) override; void postMessage(ScriptState*,
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.cc b/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.cc index c416638..4e5a904 100644 --- a/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.cc +++ b/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.cc
@@ -46,7 +46,7 @@ std::unique_ptr<GlobalScopeCreationParams> creation_params, const WorkerOptions& options, const KURL& script_url, - const FetchClientSettingsObjectSnapshot& outside_settings_object, + FetchClientSettingsObjectSnapshot* outside_settings_object, const v8_inspector::V8StackTraceId& stack_id, const String& source_code) { DCHECK(IsParentContextThread());
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.h b/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.h index 3ee4a4d..7fcb3fd 100644 --- a/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.h +++ b/third_party/blink/renderer/core/workers/dedicated_worker_messaging_proxy.h
@@ -43,7 +43,7 @@ std::unique_ptr<GlobalScopeCreationParams>, const WorkerOptions&, const KURL& script_url, - const FetchClientSettingsObjectSnapshot& outside_settings_object, + FetchClientSettingsObjectSnapshot* outside_settings_object, const v8_inspector::V8StackTraceId&, const String& source_code); void PostMessageToWorkerGlobalScope(scoped_refptr<SerializedScriptValue>,
diff --git a/third_party/blink/renderer/core/workers/shared_worker_global_scope.cc b/third_party/blink/renderer/core/workers/shared_worker_global_scope.cc index 5ec997f..553c01a 100644 --- a/third_party/blink/renderer/core/workers/shared_worker_global_scope.cc +++ b/third_party/blink/renderer/core/workers/shared_worker_global_scope.cc
@@ -65,7 +65,7 @@ // https://html.spec.whatwg.org/multipage/workers.html#worker-processing-model void SharedWorkerGlobalScope::ImportModuleScript( const KURL& module_url_record, - const FetchClientSettingsObjectSnapshot& outside_settings_object, + FetchClientSettingsObjectSnapshot* outside_settings_object, network::mojom::FetchCredentialsMode credentials_mode) { // Step 12: "Let destination be "sharedworker" if is shared is true, and // "worker" otherwise."
diff --git a/third_party/blink/renderer/core/workers/shared_worker_global_scope.h b/third_party/blink/renderer/core/workers/shared_worker_global_scope.h index 15a64ef..da59f4c 100644 --- a/third_party/blink/renderer/core/workers/shared_worker_global_scope.h +++ b/third_party/blink/renderer/core/workers/shared_worker_global_scope.h
@@ -60,7 +60,7 @@ // WorkerGlobalScope void ImportModuleScript( const KURL& module_url_record, - const FetchClientSettingsObjectSnapshot& outside_settings_object, + FetchClientSettingsObjectSnapshot* outside_settings_object, network::mojom::FetchCredentialsMode) override; // Setters/Getters for attributes in SharedWorkerGlobalScope.idl
diff --git a/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.cc b/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.cc index d6f5db31..260f497 100644 --- a/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.cc +++ b/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.cc
@@ -78,7 +78,7 @@ void ThreadedWorkletMessagingProxy::FetchAndInvokeScript( const KURL& module_url_record, network::mojom::FetchCredentialsMode credentials_mode, - const FetchClientSettingsObjectSnapshot& outside_settings_object, + FetchClientSettingsObjectSnapshot* outside_settings_object, scoped_refptr<base::SingleThreadTaskRunner> outside_settings_task_runner, WorkletPendingTasks* pending_tasks) { DCHECK(IsMainThread()); @@ -87,7 +87,7 @@ CrossThreadBind(&ThreadedWorkletObjectProxy::FetchAndInvokeScript, CrossThreadUnretained(worklet_object_proxy_.get()), module_url_record, credentials_mode, - outside_settings_object, + WTF::Passed(outside_settings_object->CopyData()), std::move(outside_settings_task_runner), WrapCrossThreadPersistent(pending_tasks), CrossThreadUnretained(GetWorkerThread())));
diff --git a/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.h b/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.h index ee780e7..caad225d 100644 --- a/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.h +++ b/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.h
@@ -26,7 +26,7 @@ void FetchAndInvokeScript( const KURL& module_url_record, network::mojom::FetchCredentialsMode, - const FetchClientSettingsObjectSnapshot& outside_settings_object, + FetchClientSettingsObjectSnapshot* outside_settings_object, scoped_refptr<base::SingleThreadTaskRunner> outside_settings_task_runner, WorkletPendingTasks*) final; void WorkletObjectDestroyed() final;
diff --git a/third_party/blink/renderer/core/workers/threaded_worklet_object_proxy.cc b/third_party/blink/renderer/core/workers/threaded_worklet_object_proxy.cc index 7058a473..cd380d7 100644 --- a/third_party/blink/renderer/core/workers/threaded_worklet_object_proxy.cc +++ b/third_party/blink/renderer/core/workers/threaded_worklet_object_proxy.cc
@@ -8,6 +8,7 @@ #include <utility> #include "base/memory/ptr_util.h" +#include "third_party/blink/renderer/core/script/fetch_client_settings_object_snapshot.h" #include "third_party/blink/renderer/core/workers/threaded_worklet_global_scope.h" #include "third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.h" #include "third_party/blink/renderer/core/workers/worker_thread.h" @@ -27,14 +28,16 @@ void ThreadedWorkletObjectProxy::FetchAndInvokeScript( const KURL& module_url_record, network::mojom::FetchCredentialsMode credentials_mode, - const FetchClientSettingsObjectSnapshot& outside_settings_object, + std::unique_ptr<CrossThreadFetchClientSettingsObjectData> + outside_settings_object, scoped_refptr<base::SingleThreadTaskRunner> outside_settings_task_runner, WorkletPendingTasks* pending_tasks, WorkerThread* worker_thread) { ThreadedWorkletGlobalScope* global_scope = ToThreadedWorkletGlobalScope(worker_thread->GlobalScope()); global_scope->FetchAndInvokeScript( - module_url_record, credentials_mode, outside_settings_object, + module_url_record, credentials_mode, + new FetchClientSettingsObjectSnapshot(std::move(outside_settings_object)), std::move(outside_settings_task_runner), pending_tasks); }
diff --git a/third_party/blink/renderer/core/workers/threaded_worklet_object_proxy.h b/third_party/blink/renderer/core/workers/threaded_worklet_object_proxy.h index 2fdd1bc..0e900e2 100644 --- a/third_party/blink/renderer/core/workers/threaded_worklet_object_proxy.h +++ b/third_party/blink/renderer/core/workers/threaded_worklet_object_proxy.h
@@ -14,10 +14,10 @@ namespace blink { -class FetchClientSettingsObjectSnapshot; class ThreadedWorkletMessagingProxy; class WorkletPendingTasks; class WorkerThread; +struct CrossThreadFetchClientSettingsObjectData; // A proxy to talk to the parent worker object. See class comments on // ThreadedObjectProxyBase.h for lifetime of this class etc. @@ -36,7 +36,8 @@ void FetchAndInvokeScript( const KURL& module_url_record, network::mojom::FetchCredentialsMode, - const FetchClientSettingsObjectSnapshot& outside_settings_object, + std::unique_ptr<CrossThreadFetchClientSettingsObjectData> + outside_settings_object, scoped_refptr<base::SingleThreadTaskRunner> outside_settings_task_runner, WorkletPendingTasks*, WorkerThread*);
diff --git a/third_party/blink/renderer/core/workers/worker_global_scope.h b/third_party/blink/renderer/core/workers/worker_global_scope.h index 65ac243..4143202 100644 --- a/third_party/blink/renderer/core/workers/worker_global_scope.h +++ b/third_party/blink/renderer/core/workers/worker_global_scope.h
@@ -138,7 +138,7 @@ // Imports the top-level module script for |module_url_record|. virtual void ImportModuleScript( const KURL& module_url_record, - const FetchClientSettingsObjectSnapshot& outside_settings_object, + FetchClientSettingsObjectSnapshot* outside_settings_object, network::mojom::FetchCredentialsMode) = 0; base::TimeTicks TimeOrigin() const { return time_origin_; }
diff --git a/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc b/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc index 470a53f9..c006e649 100644 --- a/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc +++ b/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.cc
@@ -203,7 +203,7 @@ // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-module-worker-script-tree void WorkerOrWorkletGlobalScope::FetchModuleScript( const KURL& module_url_record, - const FetchClientSettingsObjectSnapshot& fetch_client_settings_object, + FetchClientSettingsObjectSnapshot* fetch_client_settings_object, WebURLRequest::RequestContext destination, network::mojom::FetchCredentialsMode credentials_mode, ModuleScriptCustomFetchType custom_fetch_type,
diff --git a/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h b/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h index 5109848..bf40a50 100644 --- a/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h +++ b/third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h
@@ -112,7 +112,7 @@ void FetchModuleScript( const KURL& module_url_record, - const FetchClientSettingsObjectSnapshot& fetch_client_settings_object, + FetchClientSettingsObjectSnapshot* fetch_client_settings_object, WebURLRequest::RequestContext destination, network::mojom::FetchCredentialsMode, ModuleScriptCustomFetchType,
diff --git a/third_party/blink/renderer/core/workers/worker_thread.cc b/third_party/blink/renderer/core/workers/worker_thread.cc index db2e105..9704521 100644 --- a/third_party/blink/renderer/core/workers/worker_thread.cc +++ b/third_party/blink/renderer/core/workers/worker_thread.cc
@@ -146,14 +146,15 @@ void WorkerThread::ImportModuleScript( const KURL& script_url, - const FetchClientSettingsObjectSnapshot& outside_settings_object, + FetchClientSettingsObjectSnapshot* outside_settings_object, network::mojom::FetchCredentialsMode credentials_mode) { DCHECK_CALLED_ON_VALID_THREAD(parent_thread_checker_); PostCrossThreadTask( *GetTaskRunner(TaskType::kInternalWorker), FROM_HERE, CrossThreadBind(&WorkerThread::ImportModuleScriptOnWorkerThread, CrossThreadUnretained(this), script_url, - outside_settings_object, credentials_mode)); + WTF::Passed(outside_settings_object->CopyData()), + credentials_mode)); } void WorkerThread::TerminateChildThreadsOnWorkerThread() { @@ -502,13 +503,16 @@ void WorkerThread::ImportModuleScriptOnWorkerThread( const KURL& script_url, - const FetchClientSettingsObjectSnapshot& outside_settings_object, + std::unique_ptr<CrossThreadFetchClientSettingsObjectData> + outside_settings_object, network::mojom::FetchCredentialsMode credentials_mode) { // Worklets have a different code path to import module scripts. // TODO(nhiroki): Consider excluding this code path from WorkerThread like // Worklets. ToWorkerGlobalScope(GlobalScope()) - ->ImportModuleScript(script_url, outside_settings_object, + ->ImportModuleScript(script_url, + new FetchClientSettingsObjectSnapshot( + std::move(outside_settings_object)), credentials_mode); } @@ -523,24 +527,13 @@ SetExitCode(ExitCode::kGracefullyTerminated); } - inspector_task_runner_->Dispose(); GetWorkerReportingProxy().WillDestroyWorkerGlobalScope(); + probe::AllAsyncTasksCanceled(GlobalScope()); - GlobalScope()->NotifyContextDestroyed(); - if (worker_inspector_controller_) { - worker_inspector_controller_->Dispose(); - worker_inspector_controller_.Clear(); - } worker_scheduler_->Dispose(); - GlobalScope()->Dispose(); - global_scope_ = nullptr; - if (WorkerThreadDebugger* debugger = WorkerThreadDebugger::From(GetIsolate())) - debugger->WorkerThreadDestroyed(this); - - console_message_storage_.Clear(); - loading_context_.Clear(); + // No V8 microtasks should get executed after shutdown is requested. GetWorkerBackingThread().BackingThread().RemoveTaskObserver(this); } @@ -554,6 +547,21 @@ } #endif + inspector_task_runner_->Dispose(); + if (worker_inspector_controller_) { + worker_inspector_controller_->Dispose(); + worker_inspector_controller_.Clear(); + } + + GlobalScope()->Dispose(); + global_scope_ = nullptr; + + if (WorkerThreadDebugger* debugger = WorkerThreadDebugger::From(GetIsolate())) + debugger->WorkerThreadDestroyed(this); + + console_message_storage_.Clear(); + loading_context_.Clear(); + if (IsOwningBackingThread()) GetWorkerBackingThread().ShutdownOnBackingThread(); // We must not touch workerBackingThread() from now on.
diff --git a/third_party/blink/renderer/core/workers/worker_thread.h b/third_party/blink/renderer/core/workers/worker_thread.h index e8195f3b7..d2c9434 100644 --- a/third_party/blink/renderer/core/workers/worker_thread.h +++ b/third_party/blink/renderer/core/workers/worker_thread.h
@@ -62,6 +62,7 @@ class WorkerInspectorController; class WorkerOrWorkletGlobalScope; class WorkerReportingProxy; +struct CrossThreadFetchClientSettingsObjectData; struct GlobalScopeCreationParams; // WorkerThread is a kind of WorkerBackingThread client. Each worker mechanism @@ -115,7 +116,7 @@ // Called on the main thread after start(). void ImportModuleScript( const KURL& script_url, - const FetchClientSettingsObjectSnapshot& outside_settings_object, + FetchClientSettingsObjectSnapshot* outside_settings_object, network::mojom::FetchCredentialsMode); // Posts a task to the worker thread to close the global scope and terminate @@ -286,7 +287,8 @@ const v8_inspector::V8StackTraceId& stack_id); void ImportModuleScriptOnWorkerThread( const KURL& script_url, - const FetchClientSettingsObjectSnapshot& outside_settings_object, + std::unique_ptr<CrossThreadFetchClientSettingsObjectData> + outside_settings_object, network::mojom::FetchCredentialsMode); void TerminateChildThreadsOnWorkerThread();
diff --git a/third_party/blink/renderer/core/workers/worker_thread_test_helper.h b/third_party/blink/renderer/core/workers/worker_thread_test_helper.h index 58c9ca86..4e6c5b3b 100644 --- a/third_party/blink/renderer/core/workers/worker_thread_test_helper.h +++ b/third_party/blink/renderer/core/workers/worker_thread_test_helper.h
@@ -75,7 +75,7 @@ // WorkerGlobalScope void ImportModuleScript( const KURL& module_url_record, - const FetchClientSettingsObjectSnapshot& outside_settings_object, + FetchClientSettingsObjectSnapshot* outside_settings_object, network::mojom::FetchCredentialsMode) override { NOTREACHED(); }
diff --git a/third_party/blink/renderer/core/workers/worklet.cc b/third_party/blink/renderer/core/workers/worklet.cc index 34f9f93..4eabae256 100644 --- a/third_party/blink/renderer/core/workers/worklet.cc +++ b/third_party/blink/renderer/core/workers/worklet.cc
@@ -121,8 +121,8 @@ DCHECK(result); // Step 7: "Let outsideSettings be the relevant settings object of this." - FetchClientSettingsObjectSnapshot outside_settings_object( - *GetExecutionContext()); + auto* outside_settings_object = + new FetchClientSettingsObjectSnapshot(*GetExecutionContext()); // Specify TaskType::kInternalLoading because it's commonly used for module // loading. scoped_refptr<base::SingleThreadTaskRunner> outside_settings_task_runner =
diff --git a/third_party/blink/renderer/core/workers/worklet_global_scope.cc b/third_party/blink/renderer/core/workers/worklet_global_scope.cc index 0aa2bcb..5135d01 100644 --- a/third_party/blink/renderer/core/workers/worklet_global_scope.cc +++ b/third_party/blink/renderer/core/workers/worklet_global_scope.cc
@@ -81,7 +81,7 @@ void WorkletGlobalScope::FetchAndInvokeScript( const KURL& module_url_record, network::mojom::FetchCredentialsMode credentials_mode, - const FetchClientSettingsObjectSnapshot& outside_settings_object, + FetchClientSettingsObjectSnapshot* outside_settings_object, scoped_refptr<base::SingleThreadTaskRunner> outside_settings_task_runner, WorkletPendingTasks* pending_tasks) { DCHECK(IsContextThread());
diff --git a/third_party/blink/renderer/core/workers/worklet_global_scope.h b/third_party/blink/renderer/core/workers/worklet_global_scope.h index a6d6f46..c19ef39 100644 --- a/third_party/blink/renderer/core/workers/worklet_global_scope.h +++ b/third_party/blink/renderer/core/workers/worklet_global_scope.h
@@ -65,7 +65,7 @@ void FetchAndInvokeScript( const KURL& module_url_record, network::mojom::FetchCredentialsMode, - const FetchClientSettingsObjectSnapshot& outside_settings_object, + FetchClientSettingsObjectSnapshot* outside_settings_object, scoped_refptr<base::SingleThreadTaskRunner> outside_settings_task_runner, WorkletPendingTasks*);
diff --git a/third_party/blink/renderer/core/workers/worklet_global_scope_proxy.h b/third_party/blink/renderer/core/workers/worklet_global_scope_proxy.h index 1074464..f9a9a35 100644 --- a/third_party/blink/renderer/core/workers/worklet_global_scope_proxy.h +++ b/third_party/blink/renderer/core/workers/worklet_global_scope_proxy.h
@@ -28,7 +28,7 @@ virtual void FetchAndInvokeScript( const KURL& module_url_record, network::mojom::FetchCredentialsMode, - const FetchClientSettingsObjectSnapshot& outside_settings_object, + FetchClientSettingsObjectSnapshot* outside_settings_object, scoped_refptr<base::SingleThreadTaskRunner> outside_settings_task_runner, WorkletPendingTasks*) = 0;
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_type_converters.cc b/third_party/blink/renderer/modules/background_fetch/background_fetch_type_converters.cc index 413559e..719b38b 100644 --- a/third_party/blink/renderer/modules/background_fetch/background_fetch_type_converters.cc +++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_type_converters.cc
@@ -15,34 +15,36 @@ TypeConverter<blink::BackgroundFetchRegistration*, blink::mojom::blink::BackgroundFetchRegistrationPtr>:: Convert(const blink::mojom::blink::BackgroundFetchRegistrationPtr& - mojoRegistration) { - if (!mojoRegistration) + mojo_registration) { + if (!mojo_registration) return nullptr; return new blink::BackgroundFetchRegistration( - mojoRegistration->developer_id, mojoRegistration->unique_id, - mojoRegistration->upload_total, mojoRegistration->uploaded, - mojoRegistration->download_total, mojoRegistration->downloaded); + mojo_registration->developer_id, mojo_registration->unique_id, + mojo_registration->upload_total, mojo_registration->uploaded, + mojo_registration->download_total, mojo_registration->downloaded); } blink::mojom::blink::BackgroundFetchOptionsPtr TypeConverter< blink::mojom::blink::BackgroundFetchOptionsPtr, blink::BackgroundFetchOptions>::Convert(const blink::BackgroundFetchOptions& options) { - blink::mojom::blink::BackgroundFetchOptionsPtr mojoOptions = + blink::mojom::blink::BackgroundFetchOptionsPtr mojo_options = blink::mojom::blink::BackgroundFetchOptions::New(); - WTF::Vector<blink::mojom::blink::ManifestImageResourcePtr> mojoIcons; - mojoIcons.ReserveInitialCapacity(options.icons().size()); + WTF::Vector<blink::mojom::blink::ManifestImageResourcePtr> mojo_icons; + mojo_icons.ReserveInitialCapacity(options.icons().size()); - for (const auto& icon : options.icons()) - mojoIcons.push_back(blink::mojom::blink::ManifestImageResource::From(icon)); + for (const auto& icon : options.icons()) { + mojo_icons.push_back( + blink::mojom::blink::ManifestImageResource::From(icon)); + } - mojoOptions->icons = std::move(mojoIcons); - mojoOptions->download_total = options.downloadTotal(); - mojoOptions->title = options.title(); + mojo_options->icons = std::move(mojo_icons); + mojo_options->download_total = options.downloadTotal(); + mojo_options->title = options.title(); - return mojoOptions; + return mojo_options; } } // namespace mojo
diff --git a/third_party/blink/renderer/modules/background_fetch/background_fetch_type_converters.h b/third_party/blink/renderer/modules/background_fetch/background_fetch_type_converters.h index 7e8d66ee..3ee7d58 100644 --- a/third_party/blink/renderer/modules/background_fetch/background_fetch_type_converters.h +++ b/third_party/blink/renderer/modules/background_fetch/background_fetch_type_converters.h
@@ -18,14 +18,15 @@ struct TypeConverter<blink::BackgroundFetchRegistration*, blink::mojom::blink::BackgroundFetchRegistrationPtr> { static blink::BackgroundFetchRegistration* Convert( - const blink::mojom::blink::BackgroundFetchRegistrationPtr&); + const blink::mojom::blink::BackgroundFetchRegistrationPtr& + mojo_registration); }; template <> struct TypeConverter<blink::mojom::blink::BackgroundFetchOptionsPtr, blink::BackgroundFetchOptions> { static blink::mojom::blink::BackgroundFetchOptionsPtr Convert( - const blink::BackgroundFetchOptions&); + const blink::BackgroundFetchOptions& options); }; } // namespace mojo
diff --git a/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.cc b/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.cc index 60da423e..7ded3e21f 100644 --- a/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.cc +++ b/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.cc
@@ -57,7 +57,7 @@ void PaintWorkletGlobalScopeProxy::FetchAndInvokeScript( const KURL& module_url_record, network::mojom::FetchCredentialsMode credentials_mode, - const FetchClientSettingsObjectSnapshot& outside_settings_object, + FetchClientSettingsObjectSnapshot* outside_settings_object, scoped_refptr<base::SingleThreadTaskRunner> outside_settings_task_runner, WorkletPendingTasks* pending_tasks) { DCHECK(IsMainThread());
diff --git a/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.h b/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.h index 13b5844..cbf5a8dd 100644 --- a/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.h +++ b/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope_proxy.h
@@ -37,7 +37,7 @@ void FetchAndInvokeScript( const KURL& module_url_record, network::mojom::FetchCredentialsMode, - const FetchClientSettingsObjectSnapshot& outside_settings_object, + FetchClientSettingsObjectSnapshot* outside_settings_object, scoped_refptr<base::SingleThreadTaskRunner> outside_settings_task_runner, WorkletPendingTasks*) override; void WorkletObjectDestroyed() override;
diff --git a/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc b/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc index a2409ce..7b5b3286 100644 --- a/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc +++ b/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc
@@ -570,6 +570,8 @@ } if (RuntimeEnabledFeatures::PictureInPictureEnabled() && + GetDocument().GetSettings() && + GetDocument().GetSettings()->GetPictureInPictureEnabled() && MediaElement().IsHTMLVideoElement()) { picture_in_picture_button_ = new MediaControlPictureInPictureButtonElement(*this); @@ -612,8 +614,7 @@ overflow_list_->ParserAppendChild( toggle_closed_captions_button_->CreateOverflowElement( new MediaControlToggleClosedCaptionsButtonElement(*this))); - if (RuntimeEnabledFeatures::PictureInPictureEnabled() && - MediaElement().IsHTMLVideoElement()) { + if (picture_in_picture_button_) { overflow_list_->ParserAppendChild( picture_in_picture_button_->CreateOverflowElement( new MediaControlPictureInPictureButtonElement(*this))); @@ -1716,6 +1717,10 @@ } void MediaControlsImpl::OnPictureInPictureChanged() { + // This will only be called if the media controls are listening to the + // Picture-in-Picture events which only happen when they provide a + // Picture-in-Picture button. + DCHECK(picture_in_picture_button_); picture_in_picture_button_->UpdateDisplayType(); }
diff --git a/third_party/blink/renderer/modules/media_controls/media_controls_media_event_listener.cc b/third_party/blink/renderer/modules/media_controls/media_controls_media_event_listener.cc index aa68bea3..ffe4904e 100644 --- a/third_party/blink/renderer/modules/media_controls/media_controls_media_event_listener.cc +++ b/third_party/blink/renderer/modules/media_controls/media_controls_media_event_listener.cc
@@ -6,6 +6,7 @@ #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/events/event.h" +#include "third_party/blink/renderer/core/frame/settings.h" #include "third_party/blink/renderer/core/html/media/html_media_element.h" #include "third_party/blink/renderer/core/html/track/text_track_list.h" #include "third_party/blink/renderer/modules/media_controls/media_controls_impl.h" @@ -52,6 +53,10 @@ // Picture-in-Picture events. if (RuntimeEnabledFeatures::PictureInPictureEnabled() && + media_controls_->GetDocument().GetSettings() && + media_controls_->GetDocument() + .GetSettings() + ->GetPictureInPictureEnabled() && GetMediaElement().IsHTMLVideoElement()) { GetMediaElement().addEventListener(EventTypeNames::enterpictureinpicture, this, false);
diff --git a/third_party/blink/renderer/modules/mediacapturefromelement/html_media_element_capture.cc b/third_party/blink/renderer/modules/mediacapturefromelement/html_media_element_capture.cc index 61eb72f..fa721b2 100644 --- a/third_party/blink/renderer/modules/mediacapturefromelement/html_media_element_capture.cc +++ b/third_party/blink/renderer/modules/mediacapturefromelement/html_media_element_capture.cc
@@ -62,7 +62,7 @@ const MediaStreamTrackVector tracks = media_stream_->getTracks(); for (const auto& track : tracks) { track->stopTrack(context); - media_stream_->RemoveTrackByComponent(track->Component()); + media_stream_->RemoveTrackByComponentAndFireEvents(track->Component()); } media_stream_->StreamEnded(); @@ -76,7 +76,7 @@ const MediaStreamTrackVector tracks = media_stream_->getTracks(); for (const auto& track : tracks) { track->stopTrack(context); - media_stream_->RemoveTrackByComponent(track->Component()); + media_stream_->RemoveTrackByComponentAndFireEvents(track->Component()); } MediaStreamDescriptor* const descriptor = media_element_->currentSrc().IsEmpty() @@ -84,10 +84,14 @@ : MediaStreamRegistry::Registry().LookupMediaStreamDescriptor( media_element_->currentSrc().GetString()); DCHECK(descriptor); - for (size_t i = 0; i < descriptor->NumberOfAudioComponents(); i++) - media_stream_->AddTrackByComponent(descriptor->AudioComponent(i)); - for (size_t i = 0; i < descriptor->NumberOfVideoComponents(); i++) - media_stream_->AddTrackByComponent(descriptor->VideoComponent(i)); + for (size_t i = 0; i < descriptor->NumberOfAudioComponents(); i++) { + media_stream_->AddTrackByComponentAndFireEvents( + descriptor->AudioComponent(i)); + } + for (size_t i = 0; i < descriptor->NumberOfVideoComponents(); i++) { + media_stream_->AddTrackByComponentAndFireEvents( + descriptor->VideoComponent(i)); + } UpdateSources(context); return; } @@ -109,11 +113,11 @@ WebVector<WebMediaStreamTrack> video_tracks = web_stream.VideoTracks(); for (const auto& track : video_tracks) - media_stream_->AddTrackByComponent(track); + media_stream_->AddTrackByComponentAndFireEvents(track); WebVector<WebMediaStreamTrack> audio_tracks = web_stream.AudioTracks(); for (const auto& track : audio_tracks) - media_stream_->AddTrackByComponent(track); + media_stream_->AddTrackByComponentAndFireEvents(track); DVLOG(2) << "#videotracks: " << video_tracks.size() << " #audiotracks: " << audio_tracks.size();
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream.cc b/third_party/blink/renderer/modules/mediastream/media_stream.cc index 038606d7..99bea50 100644 --- a/third_party/blink/renderer/modules/mediastream/media_stream.cc +++ b/third_party/blink/renderer/modules/mediastream/media_stream.cc
@@ -399,34 +399,18 @@ return EventTargetNames::MediaStream; } -void MediaStream::AddTrackByComponent(MediaStreamComponent* component) { +void MediaStream::AddTrackByComponentAndFireEvents( + MediaStreamComponent* component) { DCHECK(component); if (!GetExecutionContext()) return; - MediaStreamTrack* track = MediaStreamTrack::Create(GetExecutionContext(), component); - switch (component->Source()->GetType()) { - case MediaStreamSource::kTypeAudio: - audio_tracks_.push_back(track); - break; - case MediaStreamSource::kTypeVideo: - video_tracks_.push_back(track); - break; - } - track->RegisterMediaStream(this); - descriptor_->AddComponent(component); - - ScheduleDispatchEvent( - MediaStreamTrackEvent::Create(EventTypeNames::addtrack, track)); - - if (!active() && !track->Ended()) { - descriptor_->SetActive(true); - ScheduleDispatchEvent(Event::Create(EventTypeNames::active)); - } + AddTrackAndFireEvents(track); } -void MediaStream::RemoveTrackByComponent(MediaStreamComponent* component) { +void MediaStream::RemoveTrackByComponentAndFireEvents( + MediaStreamComponent* component) { DCHECK(component); if (!GetExecutionContext()) return; @@ -465,6 +449,33 @@ } } +void MediaStream::AddTrackAndFireEvents(MediaStreamTrack* track) { + DCHECK(track); + switch (track->Component()->Source()->GetType()) { + case MediaStreamSource::kTypeAudio: + audio_tracks_.push_back(track); + break; + case MediaStreamSource::kTypeVideo: + video_tracks_.push_back(track); + break; + } + track->RegisterMediaStream(this); + descriptor_->AddComponent(track->Component()); + + ScheduleDispatchEvent( + MediaStreamTrackEvent::Create(EventTypeNames::addtrack, track)); + + if (!active() && !track->Ended()) { + descriptor_->SetActive(true); + ScheduleDispatchEvent(Event::Create(EventTypeNames::active)); + } +} + +void MediaStream::RemoveTrackAndFireEvents(MediaStreamTrack* track) { + DCHECK(track); + RemoveTrackByComponentAndFireEvents(track->Component()); +} + void MediaStream::ScheduleDispatchEvent(Event* event) { scheduled_events_.push_back(event);
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream.h b/third_party/blink/renderer/modules/mediastream/media_stream.h index 1d045842..8b815ef7 100644 --- a/third_party/blink/renderer/modules/mediastream/media_stream.h +++ b/third_party/blink/renderer/modules/mediastream/media_stream.h
@@ -82,6 +82,9 @@ String id() const { return descriptor_->Id(); } + // Adds the track, this may cause "onactive" to fire but it won't cause + // "onaddtrack" because the track was added explicitly by the JavaScript + // application. void addTrack(MediaStreamTrack*, ExceptionState&); void removeTrack(MediaStreamTrack*, ExceptionState&); MediaStreamTrack* getTrackById(String); @@ -105,8 +108,16 @@ // MediaStreamDescriptorClient implementation void StreamEnded() override; - void AddTrackByComponent(MediaStreamComponent*) override; - void RemoveTrackByComponent(MediaStreamComponent*) override; + void AddTrackByComponentAndFireEvents(MediaStreamComponent*) override; + void RemoveTrackByComponentAndFireEvents(MediaStreamComponent*) override; + + // Adds the track and, unlike JavaScript-invoked addTrack(), fires related + // events like "onaddtrack". + void AddTrackAndFireEvents(MediaStreamTrack*); + void RemoveTrackAndFireEvents(MediaStreamTrack*); + + void AddRemoteTrack(MediaStreamTrack*); + void RemoveRemoteTrack(MediaStreamTrack*); MediaStreamDescriptor* Descriptor() const { return descriptor_; }
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc index 809dee3..0c91a12 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
@@ -1287,28 +1287,26 @@ return remote_streams; } -MediaStream* RTCPeerConnection::getRemoteStream( - MediaStreamDescriptor* descriptor) const { +MediaStream* RTCPeerConnection::getRemoteStreamById(const WebString& id) const { for (const auto& rtp_receiver : rtp_receivers_) { for (const auto& stream : rtp_receiver->streams()) { - if (stream->Descriptor() == descriptor) + if (static_cast<WebString>(stream->id()) == id) { return stream; + } } } return nullptr; } -size_t RTCPeerConnection::getRemoteStreamUsageCount( - MediaStreamDescriptor* descriptor) const { - size_t usage_count = 0; +bool RTCPeerConnection::IsRemoteStream(MediaStream* stream) const { for (const auto& receiver : rtp_receivers_) { - WebVector<WebMediaStream> streams = receiver->web_receiver().Streams(); - for (const WebMediaStream& stream : streams) { - if (stream == descriptor) - ++usage_count; + for (const auto& receiver_stream : receiver->streams()) { + if (receiver_stream == stream) { + return true; + } } } - return usage_count; + return false; } ScriptPromise RTCPeerConnection::getStats( @@ -1725,119 +1723,82 @@ ChangeIceConnectionState(new_state); } -void RTCPeerConnection::DidAddRemoteTrack( - std::unique_ptr<WebRTCRtpReceiver> web_rtp_receiver) { +void RTCPeerConnection::DidAddReceiver( + std::unique_ptr<WebRTCRtpReceiver> web_receiver) { DCHECK(!closed_); DCHECK(GetExecutionContext()->IsContextThread()); if (signaling_state_ == webrtc::PeerConnectionInterface::SignalingState::kClosed) return; + // Create track. + MediaStreamTrack* track = + MediaStreamTrack::Create(GetExecutionContext(), web_receiver->Track()); + tracks_.insert(track->Component(), track); + // Create or update streams. HeapVector<Member<MediaStream>> streams; - WebVector<WebMediaStream> web_streams = web_rtp_receiver->Streams(); - streams.ReserveCapacity(web_streams.size()); - for (const WebMediaStream& web_stream : web_streams) { - MediaStream* stream = getRemoteStream(web_stream); + for (const auto& stream_id : web_receiver->StreamIds()) { + MediaStream* stream = getRemoteStreamById(stream_id); if (!stream) { - // This is a new stream that we need to create. - // Get or create audio tracks. - WebVector<WebMediaStreamTrack> audio_web_tracks = - web_stream.AudioTracks(); + // The stream is new, create it containing this track. + MediaStreamComponentVector audio_track_components; MediaStreamTrackVector audio_tracks; - audio_tracks.ReserveCapacity(audio_web_tracks.size()); - for (const WebMediaStreamTrack& audio_web_track : audio_web_tracks) { - MediaStreamTrack* audio_track = tracks_.at(audio_web_track); - if (!audio_track) { - audio_track = - MediaStreamTrack::Create(GetExecutionContext(), audio_web_track); - tracks_.insert(audio_track->Component(), audio_track); - } - audio_tracks.push_back(audio_track); - } - // Get or create video tracks. - WebVector<WebMediaStreamTrack> video_web_tracks = - web_stream.VideoTracks(); + MediaStreamComponentVector video_track_components; MediaStreamTrackVector video_tracks; - video_tracks.ReserveCapacity(video_web_tracks.size()); - for (const WebMediaStreamTrack& video_web_track : video_web_tracks) { - MediaStreamTrack* video_track = tracks_.at(video_web_track); - if (!video_track) { - video_track = - MediaStreamTrack::Create(GetExecutionContext(), video_web_track); - tracks_.insert(video_track->Component(), video_track); - } - video_tracks.push_back(video_track); + if (track->Component()->Source()->GetType() == + MediaStreamSource::kTypeAudio) { + audio_track_components.push_back(track->Component()); + audio_tracks.push_back(track); + } else { + DCHECK(track->Component()->Source()->GetType() == + MediaStreamSource::kTypeVideo); + video_track_components.push_back(track->Component()); + video_tracks.push_back(track); } - // Create stream with tracks. - stream = MediaStream::Create(GetExecutionContext(), web_stream, - audio_tracks, video_tracks); - stream->RegisterObserver(this); + MediaStreamDescriptor* descriptor = MediaStreamDescriptor::Create( + stream_id, std::move(audio_track_components), + std::move(video_track_components)); + stream = + MediaStream::Create(GetExecutionContext(), descriptor, + std::move(audio_tracks), std::move(video_tracks)); + // Schedule to fire "pc.onaddstream". ScheduleDispatchEvent( MediaStreamEvent::Create(EventTypeNames::addstream, stream)); } else { - // The stream already exists. Because the blink stream is wired up to - // reflect when web tracks are added to the corresponding web stream, the - // receiver's track will already have a blink track created for it and - // added to the blink stream. Find it and add it to |tracks_| so that the - // RTCPeerConnection knows of its existence. - // TODO(hbos): This wiring is problematic since it assumes the blink track - // should always be created. If the track already exists (on some other - // stream or receiver) we will end up with multiple blink tracks for the - // same component. When a web track is added to the web stream, we need to - // check if a blink track already exists for it by querying the - // RTCPeerConnection. https://crbug.com/769743 - MediaStreamTrack* receiver_track = nullptr; - for (const auto& track : stream->getTracks()) { - if (track->Component() == web_rtp_receiver->Track()) { - receiver_track = track; - break; - } - } - DCHECK(receiver_track); - tracks_.insert(receiver_track->Component(), receiver_track); + // The stream already exists, add the track to it. + // This will cause to schedule to fire "stream.onaddtrack". + stream->AddTrackAndFireEvents(track); } streams.push_back(stream); } - DCHECK(FindReceiver(*web_rtp_receiver) == rtp_receivers_.end()); - MediaStreamTrack* track = GetTrack(web_rtp_receiver->Track()); - if (!track) { - // Receiver with track, without a stream. May be created by Unified Plan. - track = MediaStreamTrack::Create(GetExecutionContext(), - web_rtp_receiver->Track()); - } + DCHECK(FindReceiver(*web_receiver) == rtp_receivers_.end()); RTCRtpReceiver* rtp_receiver = - new RTCRtpReceiver(std::move(web_rtp_receiver), track, streams); + new RTCRtpReceiver(std::move(web_receiver), track, streams); rtp_receivers_.push_back(rtp_receiver); ScheduleDispatchEvent( new RTCTrackEvent(rtp_receiver, rtp_receiver->track(), streams)); } -void RTCPeerConnection::DidRemoveRemoteTrack( - std::unique_ptr<WebRTCRtpReceiver> web_rtp_receiver) { +void RTCPeerConnection::DidRemoveReceiver( + std::unique_ptr<WebRTCRtpReceiver> web_receiver) { DCHECK(!closed_); DCHECK(GetExecutionContext()->IsContextThread()); - WebVector<WebMediaStream> web_streams = web_rtp_receiver->Streams(); - auto* it = FindReceiver(*web_rtp_receiver); + auto* it = FindReceiver(*web_receiver); DCHECK(it != rtp_receivers_.end()); RTCRtpReceiver* rtp_receiver = *it; + auto streams = rtp_receiver->streams(); MediaStreamTrack* track = rtp_receiver->track(); rtp_receivers_.erase(it); // End streams no longer in use and fire "removestream" events. This behavior // is no longer in the spec. - for (const WebMediaStream& web_stream : web_streams) { - MediaStreamDescriptor* stream_descriptor = web_stream; - DCHECK(stream_descriptor->Client()); - MediaStream* stream = - static_cast<MediaStream*>(stream_descriptor->Client()); - - // The track should already have been removed from the stream thanks to - // wiring listening to the webrtc layer stream. This should make sure the - // "removetrack" event fires. - DCHECK(!stream->getTracks().Contains(track)); + for (const auto& stream : streams) { + // Remove the track. + // This will cause to schedule to fire "stream.onremovetrack". + stream->RemoveTrackAndFireEvents(track); // Was this the last usage of the stream? Remove from remote streams. - if (!getRemoteStreamUsageCount(web_stream)) { + if (!IsRemoteStream(stream)) { // TODO(hbos): The stream should already have ended by being empty, no // need for |StreamEnded|. stream->StreamEnded();
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h index 1f5c612..63c8fd6 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h +++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h
@@ -143,14 +143,12 @@ String iceConnectionState() const; + // A local stream is any stream associated with a sender. MediaStreamVector getLocalStreams() const; - + // A remote stream is any stream associated with a receiver. MediaStreamVector getRemoteStreams() const; - // Returns the remote stream for the descriptor, if one exists. - MediaStream* getRemoteStream(MediaStreamDescriptor*) const; - // Counts the number of receivers that have a remote stream for the descriptor - // in its set of associated remote streams. - size_t getRemoteStreamUsageCount(MediaStreamDescriptor*) const; + MediaStream* getRemoteStreamById(const WebString&) const; + bool IsRemoteStream(MediaStream* stream) const; void addStream(ScriptState*, MediaStream*, @@ -219,8 +217,8 @@ webrtc::PeerConnectionInterface::SignalingState) override; void DidChangeICEGatheringState(ICEGatheringState) override; void DidChangeICEConnectionState(ICEConnectionState) override; - void DidAddRemoteTrack(std::unique_ptr<WebRTCRtpReceiver>) override; - void DidRemoveRemoteTrack(std::unique_ptr<WebRTCRtpReceiver>) override; + void DidAddReceiver(std::unique_ptr<WebRTCRtpReceiver>) override; + void DidRemoveReceiver(std::unique_ptr<WebRTCRtpReceiver>) override; void DidAddRemoteDataChannel(WebRTCDataChannelHandler*) override; void ReleasePeerConnectionHandler() override; void ClosePeerConnection() override;
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc index c19c692a..dadd9fb 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc
@@ -60,15 +60,12 @@ static_cast<MediaStreamComponent*>(receiver_->Track())) { return false; } - WebVector<WebMediaStream> web_streams = receiver_->Streams(); - if (streams_.size() != web_streams.size()) + WebVector<WebString> stream_ids = receiver_->StreamIds(); + if (streams_.size() != stream_ids.size()) return false; - for (size_t i = 0; i < streams_.size(); ++i) { - if (streams_[i]->Descriptor() != - static_cast<MediaStreamDescriptor*>(web_streams[i])) { + for (size_t i = 0; i < streams_.size(); ++i) + if (static_cast<WebString>(streams_[i]->id()) != stream_ids[i]) return false; - } - } return true; }
diff --git a/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.idl b/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.idl index 66ab145..a7d40cb 100644 --- a/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.idl +++ b/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.idl
@@ -12,8 +12,8 @@ attribute EventHandler onenterpictureinpicture; attribute EventHandler onleavepictureinpicture; - [RuntimeEnabled=PictureInPictureControl] attribute EventHandler onpictureinpicturecontrolclick; + [CEReactions, Measure, Reflect] attribute boolean disablePictureInPicture; };
diff --git a/third_party/blink/renderer/modules/serviceworkers/service_worker_global_scope.cc b/third_party/blink/renderer/modules/serviceworkers/service_worker_global_scope.cc index faf1659..4bb6c38 100644 --- a/third_party/blink/renderer/modules/serviceworkers/service_worker_global_scope.cc +++ b/third_party/blink/renderer/modules/serviceworkers/service_worker_global_scope.cc
@@ -170,7 +170,7 @@ void ServiceWorkerGlobalScope::ImportModuleScript( const KURL& module_url_record, - const FetchClientSettingsObjectSnapshot& outside_settings_object, + FetchClientSettingsObjectSnapshot* outside_settings_object, network::mojom::FetchCredentialsMode credentials_mode) { // TODO(nhiroki): Implement module loading for service workers. // (https://crbug.com/824647)
diff --git a/third_party/blink/renderer/modules/serviceworkers/service_worker_global_scope.h b/third_party/blink/renderer/modules/serviceworkers/service_worker_global_scope.h index cde529f..26f2aee 100644 --- a/third_party/blink/renderer/modules/serviceworkers/service_worker_global_scope.h +++ b/third_party/blink/renderer/modules/serviceworkers/service_worker_global_scope.h
@@ -74,7 +74,7 @@ std::unique_ptr<Vector<char>> cached_meta_data) override; void ImportModuleScript( const KURL& module_url_record, - const FetchClientSettingsObjectSnapshot& outside_settings_object, + FetchClientSettingsObjectSnapshot* outside_settings_object, network::mojom::FetchCredentialsMode) override; // Counts an evaluated script and its size. Called for the main worker script.
diff --git a/third_party/blink/renderer/modules/xr/xr_canvas_input_provider.cc b/third_party/blink/renderer/modules/xr/xr_canvas_input_provider.cc index c85e149..d2e9884f 100644 --- a/third_party/blink/renderer/modules/xr/xr_canvas_input_provider.cc +++ b/third_party/blink/renderer/modules/xr/xr_canvas_input_provider.cc
@@ -86,7 +86,7 @@ if (!input_source_) { input_source_ = new XRInputSource(session_, 0); - input_source_->SetPointerOrigin(XRInputSource::kOriginScreen); + input_source_->SetTargetRayMode(XRInputSource::kTapping); } // Get the event location relative to the canvas element.
diff --git a/third_party/blink/renderer/modules/xr/xr_frame.cc b/third_party/blink/renderer/modules/xr/xr_frame.cc index 259962a..426e7e9 100644 --- a/third_party/blink/renderer/modules/xr/xr_frame.cc +++ b/third_party/blink/renderer/modules/xr/xr_frame.cc
@@ -57,8 +57,8 @@ return nullptr; } - switch (input_source->pointer_origin_) { - case XRInputSource::kOriginScreen: { + switch (input_source->target_ray_mode_) { + case XRInputSource::kTapping: { // If the pointer origin is the screen we need the head's base pose and // the pointer transform matrix to continue. The pointer transform will // represent the point the canvas was clicked as an offset from the view. @@ -73,7 +73,7 @@ return new XRInputPose(std::move(pointer_pose), nullptr); } - case XRInputSource::kOriginHead: { + case XRInputSource::kGazing: { // If the pointer origin is the users head, this is a gaze cursor and the // returned pointer is based on the device pose. If we don't have a valid // base pose (most common when tracking is lost) return null. @@ -88,7 +88,7 @@ return new XRInputPose(std::move(pointer_pose), nullptr, input_source->emulatedPosition()); } - case XRInputSource::kOriginHand: { + case XRInputSource::kPointing: { // If the input source doesn't have a base pose return null; if (!input_source->base_pose_matrix_) { return nullptr;
diff --git a/third_party/blink/renderer/modules/xr/xr_input_source.cc b/third_party/blink/renderer/modules/xr/xr_input_source.cc index 761a46d..35a50188 100644 --- a/third_party/blink/renderer/modules/xr/xr_input_source.cc +++ b/third_party/blink/renderer/modules/xr/xr_input_source.cc
@@ -9,29 +9,29 @@ XRInputSource::XRInputSource(XRSession* session, uint32_t source_id) : session_(session), source_id_(source_id) { - SetPointerOrigin(kOriginHead); + SetTargetRayMode(kGazing); SetHandedness(kHandNone); } -void XRInputSource::SetPointerOrigin(PointerOrigin pointer_origin) { - if (pointer_origin_ == pointer_origin) +void XRInputSource::SetTargetRayMode(TargetRayMode target_ray_mode) { + if (target_ray_mode_ == target_ray_mode) return; - pointer_origin_ = pointer_origin; + target_ray_mode_ = target_ray_mode; - switch (pointer_origin_) { - case kOriginHead: - pointer_origin_string_ = "head"; - break; - case kOriginHand: - pointer_origin_string_ = "hand"; - break; - case kOriginScreen: - pointer_origin_string_ = "screen"; - break; - default: - NOTREACHED() << "Unknown pointer origin: " << pointer_origin_; + switch (target_ray_mode_) { + case kGazing: + target_ray_mode_string_ = "gazing"; + return; + case kPointing: + target_ray_mode_string_ = "pointing"; + return; + case kTapping: + target_ray_mode_string_ = "tapping"; + return; } + + NOTREACHED() << "Unknown target ray mode: " << target_ray_mode_; } void XRInputSource::SetHandedness(Handedness handedness) { @@ -43,16 +43,16 @@ switch (handedness_) { case kHandNone: handedness_string_ = ""; - break; + return; case kHandLeft: handedness_string_ = "left"; - break; + return; case kHandRight: handedness_string_ = "right"; - break; - default: - NOTREACHED() << "Unknown handedness: " << handedness_; + return; } + + NOTREACHED() << "Unknown handedness: " << handedness_; } void XRInputSource::SetEmulatedPosition(bool emulated_position) {
diff --git a/third_party/blink/renderer/modules/xr/xr_input_source.h b/third_party/blink/renderer/modules/xr/xr_input_source.h index eae92ea..3b35104 100644 --- a/third_party/blink/renderer/modules/xr/xr_input_source.h +++ b/third_party/blink/renderer/modules/xr/xr_input_source.h
@@ -20,7 +20,7 @@ public: enum Handedness { kHandNone = 0, kHandLeft = 1, kHandRight = 2 }; - enum PointerOrigin { kOriginHead = 1, kOriginHand = 2, kOriginScreen = 3 }; + enum TargetRayMode { kGazing = 1, kPointing = 2, kTapping = 3 }; XRInputSource(XRSession*, uint32_t source_id); ~XRInputSource() override = default; @@ -28,12 +28,12 @@ XRSession* session() const { return session_; } const String& handedness() const { return handedness_string_; } - const String& pointerOrigin() const { return pointer_origin_string_; } + const String& targetRayMode() const { return target_ray_mode_string_; } bool emulatedPosition() const { return emulated_position_; } uint32_t source_id() const { return source_id_; } - void SetPointerOrigin(PointerOrigin); + void SetTargetRayMode(TargetRayMode); void SetHandedness(Handedness); void SetEmulatedPosition(bool emulated_position); void SetBasePoseMatrix(std::unique_ptr<TransformationMatrix>); @@ -54,8 +54,8 @@ Handedness handedness_; String handedness_string_; - PointerOrigin pointer_origin_; - String pointer_origin_string_; + TargetRayMode target_ray_mode_; + String target_ray_mode_string_; bool emulated_position_ = false;
diff --git a/third_party/blink/renderer/modules/xr/xr_input_source.idl b/third_party/blink/renderer/modules/xr/xr_input_source.idl index bc08473..7b435414f 100644 --- a/third_party/blink/renderer/modules/xr/xr_input_source.idl +++ b/third_party/blink/renderer/modules/xr/xr_input_source.idl
@@ -7,10 +7,10 @@ "right" }; -enum XRPointerOrigin { - "head", - "grip", - "screen" +enum XRTargetRayMode { + "gazing", + "pointing", + "tapping" }; [ @@ -18,5 +18,5 @@ OriginTrialEnabled=WebXR ] interface XRInputSource { readonly attribute XRHandedness handedness; - readonly attribute XRPointerOrigin pointerOrigin; + readonly attribute XRTargetRayMode targetRayMode; }; \ No newline at end of file
diff --git a/third_party/blink/renderer/modules/xr/xr_session.cc b/third_party/blink/renderer/modules/xr/xr_session.cc index 36af1a63..58080c2 100644 --- a/third_party/blink/renderer/modules/xr/xr_session.cc +++ b/third_party/blink/renderer/modules/xr/xr_session.cc
@@ -665,8 +665,8 @@ const device::mojom::blink::XRInputSourceDescriptionPtr& desc = state->description; - input_source->SetPointerOrigin( - static_cast<XRInputSource::PointerOrigin>(desc->pointer_origin)); + input_source->SetTargetRayMode( + static_cast<XRInputSource::TargetRayMode>(desc->target_ray_mode)); input_source->SetHandedness( static_cast<XRInputSource::Handedness>(desc->handedness));
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn index cead58e1..84da85b 100644 --- a/third_party/blink/renderer/platform/BUILD.gn +++ b/third_party/blink/renderer/platform/BUILD.gn
@@ -2053,11 +2053,19 @@ test("blink_fuzzer_unittests") { deps = [ - "//third_party/blink/renderer/platform:test_support", + ":test_support", + "//third_party/blink/public:test_support", ] + sources = [ "testing/run_all_tests.cc", ] + + if (is_linux) { + deps += [ + "//third_party/blink/renderer/platform/scheduler:scheduler_fuzzer_tests", + ] + } } # This source set is used for fuzzers that need an environment similar to unit
diff --git a/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc b/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc index a608fba..d3316a8 100644 --- a/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc +++ b/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc
@@ -1230,17 +1230,19 @@ } unsigned ShapeResult::CachedNextSafeToBreakOffset(unsigned offset) const { - // TODO(layout-dev): Use character_position_ for RTL once supported. - if (!Rtl()) - return character_position_->NextSafeToBreakOffset(offset); - return NextSafeToBreakOffset(offset); + if (Rtl()) + return NextSafeToBreakOffset(offset); + + DCHECK(character_position_); + return character_position_->NextSafeToBreakOffset(offset); } unsigned ShapeResult::CachedPreviousSafeToBreakOffset(unsigned offset) const { + if (Rtl()) + return PreviousSafeToBreakOffset(offset); + DCHECK(character_position_); - // TODO(layout-dev): Use character_position_->PreviousSafeToBreakOffset(index) - // once implemented. - return PreviousSafeToBreakOffset(offset); + return character_position_->PreviousSafeToBreakOffset(offset); } // TODO(eae): Might be worth trying to set midpoint to ~50% more than the number @@ -1307,14 +1309,17 @@ unsigned ShapeResult::CharacterPositionData::PreviousSafeToBreakOffset( unsigned offset) const { - if (offset >= data_.size()) - return data_.size(); + DCHECK_LE(start_offset_, offset); + unsigned adjusted_offset = offset - start_offset_; + DCHECK_LT(adjusted_offset, data_.size()); - unsigned length = data_.size(); - for (unsigned i = offset; i < length; i++) { - if (data_[i].safe_to_break_before) { - return start_offset_ + i; - } + // Assume it is always safe to break at the end of the run. + if (adjusted_offset >= data_.size()) + return start_offset_ + data_.size(); + + for (unsigned i = adjusted_offset + 1; i > 0; i--) { + if (data_[i - 1].safe_to_break_before) + return start_offset_ + (i - 1); } // Previous safe break is at the start of the run.
diff --git a/third_party/blink/renderer/platform/heap/heap_page.cc b/third_party/blink/renderer/platform/heap/heap_page.cc index 0e8254d..066faf5d 100644 --- a/third_party/blink/renderer/platform/heap/heap_page.cc +++ b/third_party/blink/renderer/platform/heap/heap_page.cc
@@ -281,14 +281,11 @@ void BaseArena::SweepUnsweptPage() { BasePage* page = first_unswept_page_; - if (page->IsEmpty()) { - page->Unlink(&first_unswept_page_); + const bool is_empty = page->Sweep(); + page->Unlink(&first_unswept_page_); + if (is_empty) { page->RemoveFromHeap(); } else { - // Sweep a page and move the page from m_firstUnsweptPages to - // m_firstPages. - page->Sweep(); - page->Unlink(&first_unswept_page_); page->Link(&first_page_); page->MarkAsSwept(); } @@ -504,11 +501,6 @@ while (!SweepingCompleted()) { BasePage* page = first_unswept_page_; - if (page->IsEmpty()) { - page->Unlink(&first_unswept_page_); - page->RemoveFromHeap(); - continue; - } // Large objects do not belong to this arena. DCHECK(!page->IsLargeObjectPage()); NormalPage* normal_page = static_cast<NormalPage*>(page); @@ -836,17 +828,13 @@ Address result = nullptr; while (!SweepingCompleted()) { BasePage* page = first_unswept_page_; - if (page->IsEmpty()) { - page->Unlink(&first_unswept_page_); + const bool is_empty = page->Sweep(); + page->Unlink(&first_unswept_page_); + if (is_empty) { page->RemoveFromHeap(); } else { - // Sweep a page and move the page from m_firstUnsweptPages to - // m_firstPages. - page->Sweep(); - page->Unlink(&first_unswept_page_); page->Link(&first_page_); page->MarkAsSwept(); - // For NormalPage, stop lazy sweeping once we find a slot to // allocate a new object. result = AllocateFromFreeList(allocation_size, gc_info_index); @@ -1068,22 +1056,19 @@ size_t swept_size = 0; while (!SweepingCompleted()) { BasePage* page = first_unswept_page_; - if (page->IsEmpty()) { + const bool is_empty = page->Sweep(); + page->Unlink(&first_unswept_page_); + if (is_empty) { swept_size += static_cast<LargeObjectPage*>(page)->ObjectSize(); - page->Unlink(&first_unswept_page_); page->RemoveFromHeap(); // For LargeObjectPage, stop lazy sweeping once we have swept - // more than allocationSize bytes. + // more than |allocation_size| bytes. if (swept_size >= allocation_size) { result = DoAllocateLargeObjectPage(allocation_size, gc_info_index); DCHECK(result); break; } } else { - // Sweep a page and move the page from m_firstUnsweptPages to - // m_firstPages. - page->Sweep(); - page->Unlink(&first_unswept_page_); page->Link(&first_page_); page->MarkAsSwept(); } @@ -1305,11 +1290,6 @@ return object_payload_size; } -bool NormalPage::IsEmpty() { - HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(Payload()); - return header->IsFree() && header->size() == PayloadSize(); -} - void NormalPage::RemoveFromHeap() { ArenaForNormalPage()->FreePage(this); } @@ -1327,7 +1307,7 @@ } #endif -void NormalPage::Sweep() { +bool NormalPage::Sweep() { object_start_bit_map()->Clear(); size_t marked_object_size = 0; Address start_of_gap = Payload(); @@ -1383,7 +1363,10 @@ marked_object_size += size; start_of_gap = header_address; } - if (start_of_gap != PayloadEnd()) { + // Only add the memory to the free list if the page is not completely empty + // and we are not at the end of the page. Empty pages are not added to the + // free list as the pages are removed immediately. + if (start_of_gap != Payload() && start_of_gap != PayloadEnd()) { page_arena->AddToFreeList(start_of_gap, PayloadEnd() - start_of_gap); #if !DCHECK_IS_ON() && !defined(LEAK_SANITIZER) && !defined(ADDRESS_SANITIZER) if (MemoryCoordinator::IsLowEndDevice()) @@ -1397,6 +1380,7 @@ } VerifyObjectStartBitmapIsConsistentWithPayload(); + return start_of_gap == Payload(); } void NormalPage::SweepAndCompact(CompactionContext& context) { @@ -1707,17 +1691,17 @@ return PayloadSize(); } -bool LargeObjectPage::IsEmpty() { - return !ObjectHeader()->IsMarked(); -} - void LargeObjectPage::RemoveFromHeap() { static_cast<LargeObjectArena*>(Arena())->FreeLargeObjectPage(this); } -void LargeObjectPage::Sweep() { +bool LargeObjectPage::Sweep() { + if (!ObjectHeader()->IsMarked()) { + return true; + } ObjectHeader()->Unmark(); Arena()->GetThreadState()->Heap().IncreaseMarkedObjectSize(size()); + return false; } void LargeObjectPage::MakeConsistentForMutator() {
diff --git a/third_party/blink/renderer/platform/heap/heap_page.h b/third_party/blink/renderer/platform/heap/heap_page.h index a98cf35..b6977736 100644 --- a/third_party/blink/renderer/platform/heap/heap_page.h +++ b/third_party/blink/renderer/platform/heap/heap_page.h
@@ -373,9 +373,10 @@ // defined as non-virtual methods on |NormalPage| and |LargeObjectPage|. The // following methods are not performance-sensitive. virtual size_t ObjectPayloadSizeForTesting() = 0; - virtual bool IsEmpty() = 0; virtual void RemoveFromHeap() = 0; - virtual void Sweep() = 0; + // Sweeps a page. Returns true when that page is empty and false otherwise. + // Does not create free list entries for empty pages. + virtual bool Sweep() = 0; virtual void MakeConsistentForMutator() = 0; #if defined(ADDRESS_SANITIZER) @@ -509,9 +510,8 @@ } size_t ObjectPayloadSizeForTesting() override; - bool IsEmpty() override; void RemoveFromHeap() override; - void Sweep() override; + bool Sweep() override; void MakeConsistentForMutator() override; #if defined(ADDRESS_SANITIZER) void PoisonUnmarkedObjects() override; @@ -635,9 +635,8 @@ } size_t ObjectPayloadSizeForTesting() override; - bool IsEmpty() override; void RemoveFromHeap() override; - void Sweep() override; + bool Sweep() override; void MakeConsistentForMutator() override; void TakeSnapshot(base::trace_event::MemoryAllocatorDump*,
diff --git a/third_party/blink/renderer/platform/mediastream/media_stream_descriptor.cc b/third_party/blink/renderer/platform/mediastream/media_stream_descriptor.cc index d2373f3..cae016b4 100644 --- a/third_party/blink/renderer/platform/mediastream/media_stream_descriptor.cc +++ b/third_party/blink/renderer/platform/mediastream/media_stream_descriptor.cc
@@ -109,14 +109,14 @@ void MediaStreamDescriptor::AddRemoteTrack(MediaStreamComponent* component) { if (client_) - client_->AddTrackByComponent(component); + client_->AddTrackByComponentAndFireEvents(component); else AddComponent(component); } void MediaStreamDescriptor::RemoveRemoteTrack(MediaStreamComponent* component) { if (client_) - client_->RemoveTrackByComponent(component); + client_->RemoveTrackByComponentAndFireEvents(component); else RemoveComponent(component); }
diff --git a/third_party/blink/renderer/platform/mediastream/media_stream_descriptor.h b/third_party/blink/renderer/platform/mediastream/media_stream_descriptor.h index 7f12f28..aed544e 100644 --- a/third_party/blink/renderer/platform/mediastream/media_stream_descriptor.h +++ b/third_party/blink/renderer/platform/mediastream/media_stream_descriptor.h
@@ -49,8 +49,8 @@ virtual ~MediaStreamDescriptorClient() = default; virtual void StreamEnded() = 0; - virtual void AddTrackByComponent(MediaStreamComponent*) = 0; - virtual void RemoveTrackByComponent(MediaStreamComponent*) = 0; + virtual void AddTrackByComponentAndFireEvents(MediaStreamComponent*) = 0; + virtual void RemoveTrackByComponentAndFireEvents(MediaStreamComponent*) = 0; void Trace(blink::Visitor* visitor) override {} };
diff --git a/third_party/blink/renderer/platform/scheduler/BUILD.gn b/third_party/blink/renderer/platform/scheduler/BUILD.gn index 6c27d0c..5900ba7 100644 --- a/third_party/blink/renderer/platform/scheduler/BUILD.gn +++ b/third_party/blink/renderer/platform/scheduler/BUILD.gn
@@ -5,6 +5,7 @@ import("//build/config/jumbo.gni") import("//third_party/blink/renderer/platform/platform.gni") import("//third_party/protobuf/proto_library.gni") +import("//testing/libfuzzer/fuzzer_test.gni") blink_platform_sources("scheduler") { sources = [ @@ -230,6 +231,49 @@ configs += [ "//third_party/blink/renderer/platform:blink_platform_config" ] } +source_set("scheduler_fuzzer_tests") { + testonly = true + + sources = [] + deps = [ + "//base", + "//base/test:test_support", + "//testing/gmock", + "//testing/gtest", + "//third_party/blink/renderer/platform/scheduler:test_support", + ] + + if (is_linux) { + sources += [ + "base/sequence_manager_fuzzer_processor.cc", + "base/sequence_manager_fuzzer_processor.h", + "base/sequence_manager_fuzzer_processor_unittest.cc", + ] + + deps += [ + ":sequence_manager_test_description_proto", + "//third_party/libprotobuf-mutator", + ] + } + + configs += [ "//third_party/blink/renderer/platform:blink_platform_config" ] +} + +fuzzer_test("sequence_manager_fuzzer") { + sources = [ + "base/sequence_manager_fuzzer.cc", + "base/sequence_manager_fuzzer_processor.cc", + "base/sequence_manager_fuzzer_processor.h", + ] + + deps = [ + ":sequence_manager_test_description_proto", + "//third_party/blink/renderer/platform:blink_fuzzer_test_support", + "//third_party/blink/renderer/platform:test_support", + "//third_party/libprotobuf-mutator", + ] +} + proto_library("sequence_manager_test_description_proto") { sources = [ "base/proto/sequence_manager_test_description.proto",
diff --git a/third_party/blink/renderer/platform/scheduler/DEPS b/third_party/blink/renderer/platform/scheduler/DEPS index 872751e2..9e3e5fe 100644 --- a/third_party/blink/renderer/platform/scheduler/DEPS +++ b/third_party/blink/renderer/platform/scheduler/DEPS
@@ -58,4 +58,7 @@ "+base/metrics/field_trial_param_associator.h", "+testing", ], + "sequence_manager_fuzzer.cc": [ + '+testing/libfuzzer/proto/lpm_interface.h' + ], }
diff --git a/third_party/blink/renderer/platform/scheduler/base/DEPS b/third_party/blink/renderer/platform/scheduler/base/DEPS index 2b19197..5fcbda71 100644 --- a/third_party/blink/renderer/platform/scheduler/base/DEPS +++ b/third_party/blink/renderer/platform/scheduler/base/DEPS
@@ -6,3 +6,10 @@ "+third_party/blink/renderer/platform/platform_export.h", "+base", ] + +specific_include_rules = { + "sequence_manager_fuzzer_processor_unittest.cc": [ + "+third_party/protobuf/src/google/protobuf/text_format.h", + "+third_party/protobuf/src/google/protobuf/util/message_differencer.h", + ], +}
diff --git a/third_party/blink/renderer/platform/scheduler/base/proto/sequence_manager_test_description.proto b/third_party/blink/renderer/platform/scheduler/base/proto/sequence_manager_test_description.proto index 4bcb5bc..3bc9a35f 100644 --- a/third_party/blink/renderer/platform/scheduler/base/proto/sequence_manager_test_description.proto +++ b/third_party/blink/renderer/platform/scheduler/base/proto/sequence_manager_test_description.proto
@@ -21,18 +21,20 @@ // Describes interfaces that can be tested by the fuzzer. // TODO(farahcharab) Add more interfaces here. message Action { - // NEXT ID = 3 + // NEXT ID = 4 + + optional uint64 action_id = 1; oneof action { - CreateTaskQueueAction create_task_queue = 1; - PostDelayedTaskAction post_delayed_task = 2; + CreateTaskQueueAction create_task_queue = 2; + PostDelayedTaskAction post_delayed_task = 3; } } message Task { // NEXT ID = 4 - required uint64 task_id = 1; + optional uint64 task_id = 1; optional uint64 duration_ms = 2;
diff --git a/third_party/blink/renderer/platform/scheduler/base/sequence_manager_fuzzer.cc b/third_party/blink/renderer/platform/scheduler/base/sequence_manager_fuzzer.cc new file mode 100644 index 0000000..4c50375 --- /dev/null +++ b/third_party/blink/renderer/platform/scheduler/base/sequence_manager_fuzzer.cc
@@ -0,0 +1,24 @@ +#include <stdlib.h> +#include <iostream> + +#include "testing/libfuzzer/proto/lpm_interface.h" +#include "third_party/blink/renderer/platform/scheduler/base/proto/sequence_manager_test_description.pb.h" +#include "third_party/blink/renderer/platform/scheduler/base/sequence_manager_fuzzer_processor.h" + +// Tests some APIs in base::sequence_manager::SequenceManager (ones defined in +// SequenceManagerTesrDescription proto) for crashes, hangs, memory leaks, +// etc ... by running randomly generated tests, and exposing problematic corner +// cases. For more details, check out go/libfuzzer-chromium. +DEFINE_BINARY_PROTO_FUZZER( + const base::sequence_manager::SequenceManagerTestDescription& + fuzzer_input) { + // Dump code for debugging. + // TODO(farahcharab): Add code so that output looks more like the native + // function call. + if (getenv("LPM_DUMP_NATIVE_INPUT")) { + std::cout << fuzzer_input.DebugString() << std::endl; + } + + base::sequence_manager::SequenceManagerFuzzerProcessor::ParseAndRun( + fuzzer_input); +}
diff --git a/third_party/blink/renderer/platform/scheduler/base/sequence_manager_fuzzer_processor.cc b/third_party/blink/renderer/platform/scheduler/base/sequence_manager_fuzzer_processor.cc new file mode 100644 index 0000000..bc722ab --- /dev/null +++ b/third_party/blink/renderer/platform/scheduler/base/sequence_manager_fuzzer_processor.cc
@@ -0,0 +1,128 @@ +#include "third_party/blink/renderer/platform/scheduler/base/sequence_manager_fuzzer_processor.h" + +#include <algorithm> +#include <string> + +#include "base/test/test_mock_time_task_runner.h" +#include "base/threading/thread_task_runner_handle.h" +#include "third_party/blink/renderer/platform/scheduler/base/test/sequence_manager_for_test.h" + +namespace base { +namespace sequence_manager { + +void SequenceManagerFuzzerProcessor::ParseAndRun( + const SequenceManagerTestDescription& description) { + SequenceManagerFuzzerProcessor processor(description); + processor.RunTest(); +} + +SequenceManagerFuzzerProcessor::SequenceManagerFuzzerProcessor( + const SequenceManagerTestDescription& description) + : SequenceManagerFuzzerProcessor(description, false) {} + +SequenceManagerFuzzerProcessor::SequenceManagerFuzzerProcessor( + const SequenceManagerTestDescription& description, + bool log_tasks_for_testing) + : log_tasks_for_testing_(log_tasks_for_testing) { + test_task_runner_ = WrapRefCounted( + new TestMockTimeTaskRunner(TestMockTimeTaskRunner::Type::kBoundToThread)); + + // A zero clock triggers some assertions. + test_task_runner_->AdvanceMockTickClock(TimeDelta::FromMilliseconds(1)); + + initial_time_ = test_task_runner_->GetMockTickClock()->NowTicks(); + + manager_ = + SequenceManagerForTest::Create(nullptr, ThreadTaskRunnerHandle::Get(), + test_task_runner_->GetMockTickClock()); + + TaskQueue::Spec spec = TaskQueue::Spec("default_task_queue"); + task_queues_.push_back(manager_->CreateTaskQueue<TestTaskQueue>(spec)); + + for (const auto& task : description.initial_task()) { + PostDelayedTaskFromAction(task); + } +} + +void SequenceManagerFuzzerProcessor::RunTest() { + test_task_runner_->FastForwardUntilNoTasksRemain(); +} + +void SequenceManagerFuzzerProcessor::RunAction( + const SequenceManagerTestDescription::Action& action) { + if (action.has_create_task_queue()) { + return CreateTaskQueueFromAction(action.create_task_queue()); + } + + return PostDelayedTaskFromAction(action.post_delayed_task()); +} + +void SequenceManagerFuzzerProcessor::PostDelayedTaskFromAction( + const SequenceManagerTestDescription::PostDelayedTaskAction& action) { + DCHECK(!task_queues_.empty()); + + size_t index = action.task_queue_id() % task_queues_.size(); + TestTaskQueue* chosen_task_queue = task_queues_[index].get(); + + // TODO(farahcharab) After adding non-nestable/nestable tasks, fix this to + // PostNonnestableDelayedTask for the former and PostDelayedTask for the + // latter. + chosen_task_queue->PostDelayedTask( + FROM_HERE, + BindOnce(&SequenceManagerFuzzerProcessor::ExecuteTask, Unretained(this), + action.task()), + TimeDelta::FromMilliseconds(action.delay_ms())); +} + +void SequenceManagerFuzzerProcessor::CreateTaskQueueFromAction( + const SequenceManagerTestDescription::CreateTaskQueueAction& action) { + TaskQueue::Spec spec = TaskQueue::Spec("test_task_queue"); + task_queues_.push_back(manager_->CreateTaskQueue<TestTaskQueue>(spec)); +} + +void SequenceManagerFuzzerProcessor::ExecuteTask( + const SequenceManagerTestDescription::Task& task) { + TimeTicks start_time = test_task_runner_->GetMockTickClock()->NowTicks(); + + // We can limit the depth of the nested post delayed action when processing + // the proto. + for (const auto& task_action : task.action()) { + // TODO(farahcharab) Add run loop to deal with nested tasks later. So far, + // we are assuming tasks are non-nestable. + RunAction(task_action); + } + + TimeTicks end_time = test_task_runner_->GetMockTickClock()->NowTicks(); + + test_task_runner_->AdvanceMockTickClock( + TimeDelta::FromMilliseconds(task.duration_ms()) - + (end_time - start_time)); + + if (log_tasks_for_testing_) { + uint64_t start_time_ms = (start_time - initial_time_).InMilliseconds(); + uint64_t end_time_ms = + (test_task_runner_->GetMockTickClock()->NowTicks() - initial_time_) + .InMilliseconds(); + + ordered_tasks_.emplace_back(task.task_id(), start_time_ms, end_time_ms); + } +} + +const std::vector<SequenceManagerFuzzerProcessor::TaskForTest>& +SequenceManagerFuzzerProcessor::ordered_tasks() const { + return ordered_tasks_; +} + +SequenceManagerFuzzerProcessor::TaskForTest::TaskForTest(uint64_t id, + uint64_t start, + uint64_t end) + : task_id(id), start_time_ms(start), end_time_ms(end) {} + +bool SequenceManagerFuzzerProcessor::TaskForTest::operator==( + const TaskForTest& rhs) const { + return task_id == rhs.task_id && start_time_ms == rhs.start_time_ms && + end_time_ms == rhs.end_time_ms; +} + +} // namespace sequence_manager +} // namespace base
diff --git a/third_party/blink/renderer/platform/scheduler/base/sequence_manager_fuzzer_processor.h b/third_party/blink/renderer/platform/scheduler/base/sequence_manager_fuzzer_processor.h new file mode 100644 index 0000000..54849b7 --- /dev/null +++ b/third_party/blink/renderer/platform/scheduler/base/sequence_manager_fuzzer_processor.h
@@ -0,0 +1,80 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file + +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_SEQUENCE_MANAGER_FUZZER_PROCESSOR_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_SEQUENCE_MANAGER_FUZZER_PROCESSOR_H_ + +#include <memory> +#include <vector> + +#include "base/test/test_mock_time_task_runner.h" +#include "base/time/time.h" +#include "third_party/blink/renderer/platform/platform_export.h" +#include "third_party/blink/renderer/platform/scheduler/base/proto/sequence_manager_test_description.pb.h" +#include "third_party/blink/renderer/platform/scheduler/base/test/sequence_manager_for_test.h" +#include "third_party/blink/renderer/platform/scheduler/base/test/test_task_queue.h" + +namespace base { +namespace sequence_manager { + +// Provides functionality to parse the fuzzer's test description and run the +// relevant APIs. +class PLATFORM_EXPORT SequenceManagerFuzzerProcessor { + public: + // Public interface used to parse the fuzzer's test description and + // run the relevant APIs. + static void ParseAndRun(const SequenceManagerTestDescription& description); + + protected: + struct TaskForTest { + uint64_t task_id; + uint64_t start_time_ms; + uint64_t end_time_ms; + + TaskForTest(uint64_t id, uint64_t start, uint64_t end); + bool operator==(const TaskForTest& rhs) const; + }; + + explicit SequenceManagerFuzzerProcessor( + const SequenceManagerTestDescription& description); + + SequenceManagerFuzzerProcessor( + const SequenceManagerTestDescription& description, + bool log_tasks_for_testing); + + void RunTest(); + + void RunAction(const SequenceManagerTestDescription::Action& action); + + const std::vector<TaskForTest>& ordered_tasks() const; + + private: + void CreateTaskQueueFromAction( + const SequenceManagerTestDescription::CreateTaskQueueAction& action); + + void PostDelayedTaskFromAction( + const SequenceManagerTestDescription::PostDelayedTaskAction& action); + + void ExecuteTask(const SequenceManagerTestDescription::Task& task); + + std::unique_ptr<SequenceManagerForTest> manager_; + + // Bound to current thread. Used to control the clock of the task queue + // manager. + scoped_refptr<TestMockTimeTaskRunner> test_task_runner_; + + std::vector<scoped_refptr<TestTaskQueue>> task_queues_; + + const bool log_tasks_for_testing_; + + TimeTicks initial_time_; + + // For Testing. Used to log tasks in their order of execution. + std::vector<TaskForTest> ordered_tasks_; +}; + +} // namespace sequence_manager +} // namespace base + +#endif
diff --git a/third_party/blink/renderer/platform/scheduler/base/sequence_manager_fuzzer_processor_unittest.cc b/third_party/blink/renderer/platform/scheduler/base/sequence_manager_fuzzer_processor_unittest.cc new file mode 100644 index 0000000..a4b17b0 --- /dev/null +++ b/third_party/blink/renderer/platform/scheduler/base/sequence_manager_fuzzer_processor_unittest.cc
@@ -0,0 +1,266 @@ +// 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 "third_party/blink/renderer/platform/scheduler/base/sequence_manager_fuzzer_processor.h" + +#include <memory> + +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/platform/scheduler/base/proto/sequence_manager_test_description.pb.h" +#include "third_party/protobuf/src/google/protobuf/text_format.h" +#include "third_party/protobuf/src/google/protobuf/util/message_differencer.h" + +namespace base { +namespace sequence_manager { + +using testing::ContainerEq; + +class SequenceManagerFuzzerProcessorForTest + : public SequenceManagerFuzzerProcessor { + public: + explicit SequenceManagerFuzzerProcessorForTest( + const SequenceManagerTestDescription& description) + : SequenceManagerFuzzerProcessor(description, true) {} + + static const std::vector<SequenceManagerFuzzerProcessorForTest::TaskForTest> + ParseAndRun(std::string test_description) { + SequenceManagerTestDescription proto_description; + google::protobuf::TextFormat::ParseFromString(test_description, + &proto_description); + + SequenceManagerFuzzerProcessorForTest processor(proto_description); + processor.RunTest(); + return processor.ordered_tasks(); + } + + using SequenceManagerFuzzerProcessor::ordered_tasks; + using TaskForTest = SequenceManagerFuzzerProcessor::TaskForTest; +}; + +TEST(SequenceManagerFuzzerProcessorTest, CreateTaskQueue) { + // Posts a instant task to create a task queue. + std::vector<SequenceManagerFuzzerProcessorForTest::TaskForTest> + executed_tasks = SequenceManagerFuzzerProcessorForTest::ParseAndRun(R"( + initial_task { + task { + task_id : 1 + action { + create_task_queue { + } + } + } + })"); + + std::vector<SequenceManagerFuzzerProcessorForTest::TaskForTest> + expected_tasks; + expected_tasks.emplace_back(1, 0, 0); + + EXPECT_THAT(executed_tasks, ContainerEq(expected_tasks)); +} + +TEST(SequenceManagerFuzzerProcessorTest, PostDelayedTaskWithDuration) { + // Posts an 10 ms delayed task of duration 20 ms. + std::vector<SequenceManagerFuzzerProcessorForTest::TaskForTest> + executed_tasks = SequenceManagerFuzzerProcessorForTest::ParseAndRun(R"( + initial_task { + task_queue_id : 1 + delay_ms : 10 + task { + task_id : 1 + duration_ms : 20 + } + })"); + + std::vector<SequenceManagerFuzzerProcessorForTest::TaskForTest> + expected_tasks; + expected_tasks.emplace_back(1, 10, 30); + + EXPECT_THAT(executed_tasks, ContainerEq(expected_tasks)); +} + +TEST(SequenceManagerFuzzerProcessorTest, + TaskDurationBlocksOtherPendingTasksPostedFromOutsideOfTask) { + // Posts a 10 ms delayed task of duration 40 ms and a 20 ms delayed task of + // duration 20 ms. + std::vector<SequenceManagerFuzzerProcessorForTest::TaskForTest> + executed_tasks = SequenceManagerFuzzerProcessorForTest::ParseAndRun(R"( + initial_task { + delay_ms : 20 + task { + task_id : 1 + duration_ms : 20 + } + } + initial_task { + delay_ms : 10 + task { + task_id : 2 + duration_ms : 40 + } + })"); + + // Task with id 2 is expected to run first and block the other task until it + // done. + std::vector<SequenceManagerFuzzerProcessorForTest::TaskForTest> + expected_tasks; + expected_tasks.emplace_back(2, 10, 50); + expected_tasks.emplace_back(1, 50, 70); + + EXPECT_THAT(executed_tasks, ContainerEq(expected_tasks)); +} + +TEST(SequenceManagerFuzzerProcessorTest, + TaskDurationBlocksOtherNonNestableTaskWhenPostedFromTheWithinTask) { + // Posts an instant task of duration 40 ms that posts another non-nested + // instant task. + std::vector<SequenceManagerFuzzerProcessorForTest::TaskForTest> + executed_tasks = SequenceManagerFuzzerProcessorForTest::ParseAndRun(R"( + initial_task { + task { + task_id : 1 + duration_ms : 40 + action { + post_delayed_task { + task { + task_id : 2 + } + } + } + } + })"); + + // Task with task id 1 is expected to run for 40 ms, and block the other + // posted task from running until its done. Note that the task with id 2 is + // blocked as it is non-nested, so it is not supposed to run from within the + // posting task. + std::vector<SequenceManagerFuzzerProcessorForTest::TaskForTest> + expected_tasks; + expected_tasks.emplace_back(1, 0, 40); + expected_tasks.emplace_back(2, 40, 40); + + EXPECT_THAT(executed_tasks, ContainerEq(expected_tasks)); +} + +TEST(SequenceManagerFuzzerProcessorTest, OrderOfSimpleUnnestedExecutedActions) { + // Creates a task after 5 ms of delay, creates a task after 10 ms of + // delay, posts a task after 20 ms delay, posts a 10 ms duration task after 15 + // ms of delay, and posts a task after 100 ms of delay. + std::vector<SequenceManagerFuzzerProcessorForTest::TaskForTest> + executed_tasks = SequenceManagerFuzzerProcessorForTest::ParseAndRun(R"( + initial_task { + delay_ms : 5 + task { + task_id : 1 + action { + create_task_queue { + } + } + } + } + initial_task { + delay_ms : 20 + task { + task_id : 2 + } + } + initial_task { + delay_ms : 15 + task { + task_id : 3 + duration_ms : 10 + } + } + initial_task { + delay_ms : 10 + task { + task_id : 4 + action { + create_task_queue { + } + } + } + } + initial_task { + delay_ms : 100 + task { + task_id : 5 + } + })"); + + // Tasks are expected to run in order of non-decreasing delay with ties broken + // by order of posting. Note that the task with id 3 will block the task with + // id 2 from running at its scheduled time. + std::vector<SequenceManagerFuzzerProcessorForTest::TaskForTest> + expected_tasks; + expected_tasks.emplace_back(1, 5, 5); + expected_tasks.emplace_back(4, 10, 10); + expected_tasks.emplace_back(3, 15, 25); + expected_tasks.emplace_back(2, 25, 25); + expected_tasks.emplace_back(5, 100, 100); + + EXPECT_THAT(executed_tasks, ContainerEq(expected_tasks)); +} + +TEST(SequenceManagerFuzzerProcessorTest, PostNonEmptyTask) { + // Posthes a 5 ms delayed task of duration 40 ms that creates a task queue, + // posts a 4 ms delayed task, posts an instant task, creates a task queue, + // and then posts a 40 ms delayed task. + std::vector<SequenceManagerFuzzerProcessorForTest::TaskForTest> + executed_tasks = SequenceManagerFuzzerProcessorForTest::ParseAndRun(R"( + initial_task { + delay_ms : 5 + task { + task_id : 1 + duration_ms : 40 + action { + create_task_queue { + } + } + action { + post_delayed_task { + delay_ms : 4 + task { + task_id : 2 + } + } + } + action { + post_delayed_task { + task { + task_id : 3 + } + } + } + action { + create_task_queue { + } + } + action { + post_delayed_task { + delay_ms : 40 + task { + task_id : 4 + } + } + } + } + })"); + + // Task with task id 1 is expected to run first, and block all other pending + // tasks until its done. The remaining tasks will be executed in + // non-decreasing order of the delay parameter with ties broken by + // the post order. + std::vector<SequenceManagerFuzzerProcessorForTest::TaskForTest> + expected_tasks; + expected_tasks.emplace_back(1, 5, 45); + expected_tasks.emplace_back(3, 45, 45); + expected_tasks.emplace_back(2, 45, 45); + expected_tasks.emplace_back(4, 45, 45); + + EXPECT_THAT(executed_tasks, ContainerEq(expected_tasks)); +} + +} // namespace sequence_manager +} // namespace base
diff --git a/third_party/blink/renderer/platform/testing/data/third_party/Roboto/LICENSE.txt b/third_party/blink/renderer/platform/testing/data/third_party/Roboto/LICENSE.txt new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/third_party/blink/renderer/platform/testing/data/third_party/Roboto/LICENSE.txt
@@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License.
diff --git a/third_party/blink/renderer/platform/testing/data/third_party/Roboto/README.chromium b/third_party/blink/renderer/platform/testing/data/third_party/Roboto/README.chromium new file mode 100644 index 0000000..8660130 --- /dev/null +++ b/third_party/blink/renderer/platform/testing/data/third_party/Roboto/README.chromium
@@ -0,0 +1,12 @@ +Name: Roboto Font +Short Name: roboto +URL: https://github.com/google/roboto/ +Version: 5700de83856781fa0c097a349e46dbaae5792cb0 +Date: 2017-08-02 +License: Apache-2.0 +License File: LICENSE.txt +Security Critical: no + +Description: +We need a a latin font with ligatures for platform testing. +Roboto contains ffi and ff.
diff --git a/third_party/blink/renderer/platform/testing/data/third_party/Roboto/roboto-regular.woff2 b/third_party/blink/renderer/platform/testing/data/third_party/Roboto/roboto-regular.woff2 new file mode 100644 index 0000000..bf6ecad --- /dev/null +++ b/third_party/blink/renderer/platform/testing/data/third_party/Roboto/roboto-regular.woff2 Binary files differ
diff --git a/third_party/blink/renderer/platform/testing/testing_platform_support_with_web_rtc.cc b/third_party/blink/renderer/platform/testing/testing_platform_support_with_web_rtc.cc index c4790dcc..ea69f6bc 100644 --- a/third_party/blink/renderer/platform/testing/testing_platform_support_with_web_rtc.cc +++ b/third_party/blink/renderer/platform/testing/testing_platform_support_with_web_rtc.cc
@@ -27,7 +27,7 @@ uintptr_t Id() const override { return id_; } WebMediaStreamTrack Track() const override { return WebMediaStreamTrack(); } - WebVector<WebMediaStream> Streams() const override { return {}; } + WebVector<WebString> StreamIds() const override { return {}; } void ReplaceTrack(WebMediaStreamTrack, WebRTCVoidRequest) override {} std::unique_ptr<WebRTCDTMFSenderHandler> GetDtmfSender() const override { return nullptr;
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 1781c31..52a543b 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -8799,6 +8799,22 @@ <int value="3" label="Connected to service with KeepAlive connection"/> </enum> +<enum name="CustomTabsDynamicModuleLoadResult"> + <int value="0" label="Loaded new instance successfully"/> + <int value="1" label="Used cached instance"/> + <int value="2" label="Not loaded because the feature is disabled"/> + <int value="3" label="Not loaded because the package is not Google-signed"/> + <int value="4" + label="Not loaded because the package name could not be found"/> + <int value="5" + label="Not loaded because the entry point class could not be found"/> + <int value="6" + label="Not loaded because the entry point class could not be + instantiated"/> + <int value="7" + label="Loaded but the host and module versions are incompatible"/> +</enum> + <enum name="CustomTabsParallelRequestStatusOnStart"> <int value="0" label="No Parallel Request was requested"/> <int value="1" label="Parallel request successfully started"/> @@ -19272,6 +19288,7 @@ <int value="2494" label="DocumentOpenTwoArgs"/> <int value="2495" label="DocumentOpenTwoArgsWithReplace"/> <int value="2496" label="DocumentOpenThreeArgs"/> + <int value="2497" label="V8FunctionTokenOffsetTooLongForToString"/> </enum> <enum name="FeedbackSource"> @@ -47562,7 +47579,6 @@ <int value="-400619253" label="mus_demo"/> <int value="-254080081" label="cdm"/> <int value="-2816355" label="profile_import"/> - <int value="69152809" label="font_service"/> <int value="357224138" label="user_id"/> <int value="498331100" label="preferences"/> <int value="573935755" label="removable_storage_writer"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index dfac0f0..0cbbf63 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -14966,6 +14966,14 @@ </summary> </histogram> +<histogram name="CustomTabs.DynamicModule.LoadResult" + enum="CustomTabsDynamicModuleLoadResult"> + <owner>mvanouwerkerk@chromium.org</owner> + <summary> + Possible results when loading a custom tabs dynamic module. Android only. + </summary> +</histogram> + <histogram name="CustomTabs.IntentToFirstCommitNavigationTime" units="ms"> <obsolete> Deprecated 10/2016 in favor of .IntentToFirstCommitNavigationTime2.*.
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml index 3e7687b1..19daeb7 100644 --- a/tools/metrics/ukm/ukm.xml +++ b/tools/metrics/ukm/ukm.xml
@@ -2526,6 +2526,15 @@ correspond to the enum PasswordFormMetricsRecorder::BubbleTrigger. </summary> </metric> + <metric name="Saving.ShowedManualFallbackForSaving"> + <summary> + Records if a manual fallback for saving option was shown to the user (on + Android this is recorded, even though the UI does not exist at the + moment). This is a bit mask. 1 means a prompt was shown, 2 means the + prompt was due to a generated password, 4 means the prompt was due to an + update. + </summary> + </metric> <metric name="Submission.Indicator"> <summary> Records the event that led the password manager to believe the submission
diff --git a/tools/perf/core/perf_data_generator.py b/tools/perf/core/perf_data_generator.py index 6548b0b..f9d7e9d6 100755 --- a/tools/perf/core/perf_data_generator.py +++ b/tools/perf/core/perf_data_generator.py
@@ -1065,14 +1065,14 @@ }, 'Win 7 Nvidia GPU Perf': { 'tests': [ - #{ - # 'isolate': 'performance_test_suite', - # 'num_shards': 5, - # 'extra_args': [ - # '--run-ref-build', - # '--test-shard-map-filename=win7_nvidia_shard_map.json', - # ], - #}, + { + 'isolate': 'performance_test_suite', + 'num_shards': 5, + 'extra_args': [ + '--run-ref-build', + '--test-shard-map-filename=win7_nvidia_shard_map.json', + ], + }, # crbug.com/735679 enable performance_browser_tests { 'isolate': 'load_library_perf_tests', @@ -1245,6 +1245,14 @@ 'True' ], } + + if tester_config['platform'] == 'win': + service_account_path = ( + 'C:\\creds\\service_accounts\\' + 'service-account-chromium-perf-histograms.json') + else: + service_account_path = ( + '/creds/service_accounts/service-account-chromium-perf-histograms.json') # Only want to append multiple-trigger-configs if we don't support # soft device affinity if len(dimensions): @@ -1254,7 +1262,7 @@ 'script': '//tools/perf/process_perf_results.py', 'args': [ '--service-account-file', - '/creds/service_accounts/service-account-chromium-perf-histograms.json' + service_account_path ], } return len(dimensions)
diff --git a/tools/perf/process_perf_results.py b/tools/perf/process_perf_results.py index 82ee302..7014d8d 100755 --- a/tools/perf/process_perf_results.py +++ b/tools/perf/process_perf_results.py
@@ -399,13 +399,23 @@ # Kick off the uploads in mutliple processes cpus = mp.cpu_count() pool = mp.Pool(cpus) - result_iterator = pool.map(_upload_individual_benchmark, - invocations) + try: + async_result = pool.map_async( + _upload_individual_benchmark, invocations) + results = async_result.get(timeout=2000) + except mp.TimeoutError: + print 'Failed uploading benchmarks to perf dashboard in parallel' + print 'Terminate the pool' + pool.terminate() + results = [] + for benchmark_name in benchmark_directory_map: + results.append((benchmark_name, False)) + # Keep a mapping of benchmarks to their upload results benchmark_upload_result_map = {} - for result in result_iterator: - benchmark_upload_result_map[result[0]] = bool(result[1]) + for r in results: + benchmark_upload_result_map[r[0]] = bool(r[1]) logdog_dict = {} upload_failure = False
diff --git a/tools/traffic_annotation/scripts/traffic_annotation_auditor_tests.py b/tools/traffic_annotation/scripts/traffic_annotation_auditor_tests.py index c1345d5a..bac06ed7 100755 --- a/tools/traffic_annotation/scripts/traffic_annotation_auditor_tests.py +++ b/tools/traffic_annotation/scripts/traffic_annotation_auditor_tests.py
@@ -18,6 +18,7 @@ # //tools/traffic_annotation/OWNERS. TEST_IS_ENABLED = True +MINIMUM_EXPECTED_NUMBER_OF_ANNOTATIONS = 260 class TrafficAnnotationTestsChecker(): def __init__(self, build_path=None): @@ -28,6 +29,7 @@ directory. """ self.tools = NetworkTrafficAnnotationTools(build_path) + self.last_result = None def RunAllTests(self): @@ -50,25 +52,36 @@ ["--test-only", "--no-filtering"] # Not using heuristic filtering. ] - last_result = None + self.last_result = None for config in configs: result = self._RunTest(config) if not result: print("No output for config: %s" % config) return False - if last_result and last_result != result: + if self.last_result and self.last_result != result: print("Unexpected different results for config: %s" % config) return False - last_result = result + self.last_result = result return True def CheckOutputExpectations(self): - # TODO(https://crbug.com/690323): Add tests to check for an expected minimum - # number of items for each type of pattern that auditor extracts. E.g., we - # should have many annotations of each type (complete, partial, ...), - # functions that need annotations, direct assignment to mutable annotations, - # etc. + # This test can be replaced by getting results from a diagnostic mode call + # to traffic_annotation_auditor, and checking for an expected minimum number + # of items for each type of pattern that it extracts. E.g., we should have + # many annotations of each type (complete, partial, ...), functions that + # need annotations, direct assignment to mutable annotations, etc. + + # |self.last_result| includes the content of the TSV file that the auditor + # generates. Counting the number of end of lines in the text will give the + # number of extracted annotations. + annotations_count = self.last_result.count("\n") + print("%i annotations found in auditor's output." % annotations_count) + + if annotations_count < MINIMUM_EXPECTED_NUMBER_OF_ANNOTATIONS: + print("Annotations are expected to be at least %i." % + MINIMUM_EXPECTED_NUMBER_OF_ANNOTATIONS) + return False return True
diff --git a/ui/base/ime/input_method_chromeos.cc b/ui/base/ime/input_method_chromeos.cc index 1a4c2367..3478bcd 100644 --- a/ui/base/ime/input_method_chromeos.cc +++ b/ui/base/ime/input_method_chromeos.cc
@@ -512,7 +512,7 @@ if (handled && NeedInsertChar()) { for (base::string16::const_iterator i = result_text_.begin(); i != result_text_.end(); ++i) { - ui::KeyEvent ch_event(*event); + KeyEvent ch_event(ET_KEY_PRESSED, VKEY_UNKNOWN, EF_NONE); ch_event.set_character(*i); client->InsertChar(ch_event); }
diff --git a/ui/file_manager/integration_tests/file_manager/copy_between_windows.js b/ui/file_manager/integration_tests/file_manager/copy_between_windows.js index 4814f8d..eec6dd35 100644 --- a/ui/file_manager/integration_tests/file_manager/copy_between_windows.js +++ b/ui/file_manager/integration_tests/file_manager/copy_between_windows.js
@@ -36,7 +36,7 @@ * @param {TestEntryInfo} file Test entry info to be copied. * @return {Promise} Promise fulfilled on success. */ -function copyBetweenWindows(window1, window2, file) { +function copyBetweenWindows(window1, window2, file, alreadyPresentFile = null) { if (!file || !file.nameText) chrome.test.assertTrue(false, 'copyBetweenWindows invalid file name'); @@ -62,7 +62,11 @@ return remoteCall.callRemoteTestUtil('execCommand', window2, ['paste']); }) .then(function() { - return remoteCall.waitForFiles(window2, [file.getExpectedRow()], flag); + var expectedFiles = [file.getExpectedRow()]; + if (alreadyPresentFile) { + expectedFiles.push(alreadyPresentFile.getExpectedRow()); + } + return remoteCall.waitForFiles(window2, expectedFiles, flag); }); } @@ -77,24 +81,26 @@ function() { openTwoWindows(RootPath.DOWNLOADS, RootPath.DRIVE).then(this.next); }, - // Check: Downloads window is empty. + // Add files. function(appIdArray) { window1 = appIdArray[0]; window2 = appIdArray[1]; - remoteCall.waitForFiles(window1, []).then(this.next); + Promise + .all([ + addEntries(['drive'], [ENTRIES.hello]), + addEntries(['local'], [ENTRIES.photos]), + ]) + .then(this.next); }, - // Add hello file to Drive. + // Check: Downloads photos file. function() { - addEntries(['drive'], [ENTRIES.hello], this.next); - }, - // Check: Drive hello file. - function() { - remoteCall.waitForFiles(window2, [ENTRIES.hello.getExpectedRow()]) + remoteCall.waitForFiles(window1, [ENTRIES.photos.getExpectedRow()]) .then(this.next); }, // Copy Drive hello file to Downloads. function() { - copyBetweenWindows(window2, window1, ENTRIES.hello).then(this.next); + copyBetweenWindows(window2, window1, ENTRIES.hello, ENTRIES.photos) + .then(this.next); }, function() { checkIfNoErrorsOccured(this.next); @@ -113,24 +119,26 @@ function() { openTwoWindows(RootPath.DOWNLOADS, RootPath.DRIVE).then(this.next); }, - // Check: Drive window is empty. + // Add files. function(appIdArray) { window1 = appIdArray[0]; window2 = appIdArray[1]; - remoteCall.waitForFiles(window2, []).then(this.next); + Promise + .all([ + addEntries(['local'], [ENTRIES.hello]), + addEntries(['drive'], [ENTRIES.photos]), + ]) + .then(this.next); }, - // Add hello file to Downloads. + // Check: Downloads hello file and Drive photos file. function() { - addEntries(['local'], [ENTRIES.hello], this.next); - }, - // Check: Downloads hello file. - function() { - remoteCall.waitForFiles(window1, [ENTRIES.hello.getExpectedRow()]) + remoteCall.waitForFiles(window2, [ENTRIES.photos.getExpectedRow()]) .then(this.next); }, // Copy Downloads hello file to Drive. function() { - copyBetweenWindows(window1, window2, ENTRIES.hello).then(this.next); + copyBetweenWindows(window1, window2, ENTRIES.hello, ENTRIES.photos) + .then(this.next); }, function() { checkIfNoErrorsOccured(this.next);